From 90c4ec47d2b94280b6edf20603f16a55aee1ae53 Mon Sep 17 00:00:00 2001 From: "Documenter.jl" Date: Mon, 28 Oct 2024 15:51:45 +0000 Subject: [PATCH] delete preview for 4245 --- previews/PR4245/.documenter-siteinfo.json | 1 - .../AbstractAlgebra/assertions/index.html | 143 -- .../assets/elements_diagram.svg | 162 -- .../assets/parents_diagram.svg | 136 -- .../AbstractAlgebra/constructors/index.html | 97 -- .../AbstractAlgebra/direct_sum/index.html | 230 --- .../euclidean_interface/index.html | 3 - .../extending_abstractalgebra/index.html | 111 -- .../PR4245/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 | 132 -- .../AbstractAlgebra/free_module/index.html | 24 - .../AbstractAlgebra/function_field/index.html | 223 --- .../AbstractAlgebra/functional_map/index.html | 11 - .../PR4245/AbstractAlgebra/ideal/index.html | 75 - previews/PR4245/AbstractAlgebra/img/types.dia | Bin 2988 -> 0 bytes previews/PR4245/AbstractAlgebra/img/types.png | Bin 17647 -> 0 bytes previews/PR4245/AbstractAlgebra/index.html | 44 - .../PR4245/AbstractAlgebra/integer/index.html | 60 - .../interface_introduction/index.html | 2 - .../laurent_mpolynomial/index.html | 27 - .../laurent_polynomial/index.html | 49 - .../AbstractAlgebra/linear_solving/index.html | 237 --- .../AbstractAlgebra/map_cache/index.html | 30 - .../AbstractAlgebra/map_interface/index.html | 26 - .../map_introduction/index.html | 2 - .../map_with_inverse/index.html | 34 - .../PR4245/AbstractAlgebra/mathjaxhelper.js | 10 - .../PR4245/AbstractAlgebra/matrix/index.html | 831 ---------- .../matrix_algebras/index.html | 40 - .../matrix_interface/index.html | 16 - .../matrix_introduction/index.html | 2 - .../PR4245/AbstractAlgebra/misc/index.html | 148 -- .../PR4245/AbstractAlgebra/module/index.html | 94 -- .../module_homomorphism/index.html | 54 - .../module_interface/index.html | 2 - .../module_introduction/index.html | 2 - .../mpoly_interface/index.html | 7 - .../AbstractAlgebra/mpolynomial/index.html | 479 ------ .../PR4245/AbstractAlgebra/mseries/index.html | 78 - .../AbstractAlgebra/ncpolynomial/index.html | 213 --- .../ncring_interface/index.html | 3 - .../PR4245/AbstractAlgebra/perm/index.html | 188 --- .../AbstractAlgebra/poly_interface/index.html | 4 - .../AbstractAlgebra/polynomial/index.html | 517 ------ .../PR4245/AbstractAlgebra/puiseux/index.html | 157 -- .../quotient_module/index.html | 65 - .../PR4245/AbstractAlgebra/rand/index.html | 53 - .../AbstractAlgebra/rational/index.html | 58 - .../PR4245/AbstractAlgebra/real/index.html | 51 - .../PR4245/AbstractAlgebra/residue/index.html | 116 -- .../residue_interface/index.html | 3 - .../PR4245/AbstractAlgebra/ring/index.html | 35 - .../AbstractAlgebra/ring_interface/index.html | 272 --- .../ring_introduction/index.html | 2 - .../PR4245/AbstractAlgebra/series/index.html | 302 ---- .../series_interface/index.html | 18 - .../AbstractAlgebra/submodule/index.html | 86 - .../AbstractAlgebra/total_fraction/index.html | 107 -- .../PR4245/AbstractAlgebra/types/index.html | 18 - .../AbstractAlgebra/univpolynomial/index.html | 26 - .../visualizing_types/index.html | 2 - .../PR4245/AbstractAlgebra/ytabs/index.html | 260 --- .../AffineAlgebraicSet/index.html | 73 - .../ProjectiveAlgebraicSet/index.html | 41 - .../AffineVariety/index.html | 23 - .../ProjectiveVariety/index.html | 92 -- .../Curves/AffinePlaneCurves/index.html | 82 - .../ParametrizationPlaneCurves/index.html | 59 - .../Curves/ProjectiveCurves/index.html | 28 - .../Curves/ProjectivePlaneCurves/index.html | 7 - .../ArchitectureOfAffineSchemes/index.html | 24 - .../Miscellaneous/miscellaneous/index.html | 30 - .../Schemes/AffineSchemes/index.html | 522 ------ .../Schemes/CoveredSchemeMorphisms/index.html | 60 - .../Schemes/CoveredSchemes/index.html | 254 --- .../Schemes/CoveringsAndGluings/index.html | 133 -- .../Schemes/Cycles/index.html | 189 --- .../Schemes/GeneralSchemes/index.html | 4 - .../MorphismsOfAffineSchemes/index.html | 294 ---- .../MorphismsOfProjectiveSchemes/index.html | 33 - .../Schemes/ProjectiveSchemes/index.html | 213 --- .../Schemes/RationalPointsAffine/index.html | 20 - .../RationalPointsProjective/index.html | 8 - .../Schemes/Sheaves/index.html | 37 - .../Schemes/intro/index.html | 2 - .../sheaf_cohomology/index.html | 59 - .../Surfaces/AdjunctionProcess/index.html | 43 - .../Surfaces/K3Surfaces/index.html | 4 - .../ParametrizationSurfaces/index.html | 35 - .../Surfaces/SurfacesP4/index.html | 2 - .../Surfaces/duValSing/index.html | 84 - .../ToricVarieties/AlgebraicCycles/index.html | 216 --- .../ToricVarieties/BlowupMorphisms/index.html | 206 --- .../CohomologyClasses/index.html | 212 --- .../CyclicQuotientSingularities/index.html | 59 - .../NormalToricVarieties/index.html | 422 ----- .../ToricVarieties/Subvarieties/index.html | 50 - .../ToricDivisorClasses/index.html | 63 - .../ToricVarieties/ToricDivisors/index.html | 151 -- .../ToricIdealSheaves/index.html | 25 - .../ToricLineBundles/index.html | 169 -- .../ToricVarieties/ToricMorphisms/index.html | 140 -- .../ToricVarieties/ToricSchemes/index.html | 38 - .../ToricVarieties/cohomCalg/index.html | 97 -- .../ToricVarieties/intro/index.html | 2 - .../PR4245/AlgebraicGeometry/intro/index.html | 2 - .../compositions/index.html | 49 - .../partitions/index.html | 86 - .../schur_polynomials/index.html | 17 - .../tableaux/index.html | 49 - .../PR4245/Combinatorics/graphs/index.html | 296 ---- .../PR4245/Combinatorics/intro/index.html | 2 - .../PR4245/Combinatorics/matroids/index.html | 418 ----- .../phylogenetic_trees/index.html | 91 - .../simplicialcomplexes/index.html | 141 -- .../module_localizations/index.html | 8 - .../FrameWorks/ring_localizations/index.html | 4 - .../GroebnerBases/groebner_bases/index.html | 445 ----- .../groebner_bases_integers/index.html | 24 - .../GroebnerBases/orderings/index.html | 459 ------ .../Miscellaneous/binomial_ideals/index.html | 147 -- .../complexes/index.html | 119 -- .../free_modules/index.html | 395 ----- .../hom_operations/index.html | 2 - .../ideals_quorings_as_modules/index.html | 68 - .../intro/index.html | 2 - .../module_operations/index.html | 453 ----- .../subquotients/index.html | 1467 ----------------- .../affine_algebras/index.html | 1197 -------------- .../homological_algebra/index.html | 998 ----------- .../CommutativeAlgebra/ideals/index.html | 802 --------- .../CommutativeAlgebra/intro/index.html | 2 - .../localizations/index.html | 517 ------ .../CommutativeAlgebra/rings/index.html | 621 ------- .../AbstractCollection/index.html | 9 - .../SubObjectIterator/index.html | 49 - .../DeveloperDocumentation/caching/index.html | 28 - .../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 | 142 -- .../DeveloperDocumentation/release/index.html | 2 - .../serialization/index.html | 127 -- .../styleguide/index.html | 69 - .../AlgebraicStatistics/ci/index.html | 55 - .../gaussian_graphical_models/index.html | 87 - .../graphical_models/index.html | 8 - .../introduction/index.html | 2 - .../AlgebraicStatistics/markov/index.html | 81 - .../phylogenetics/index.html | 197 --- .../introduction/index.html | 2 - .../user_functions/index.html | 285 ---- .../advice_for_the_programmer/index.html | 58 - .../user_interface/index.html | 16 - .../Experimental/FTheoryTools/g4/index.html | 46 - .../FTheoryTools/generalities/index.html | 393 ----- .../FTheoryTools/hypersurface/index.html | 126 -- .../FTheoryTools/introduction/index.html | 2 - .../FTheoryTools/literature/index.html | 486 ------ .../Experimental/FTheoryTools/tate/index.html | 213 --- .../FTheoryTools/weierstrass/index.html | 152 -- .../GroebnerWalk/introduction/index.html | 41 - .../GroebnerWalk/special-ideals/index.html | 2 - .../AbstractBundles/index.html | 176 -- .../AbstractVarieties/index.html | 554 ------- .../AbstractVarietyMaps/index.html | 75 - .../IntersectionTheory/BlowUps/index.html | 156 -- .../BottFormulas/index.html | 2 - .../IntersectionTheory/examples/index.html | 78 - .../IntersectionTheory/intro/index.html | 2 - .../IntersectionTheory/schubert/index.html | 76 - .../LieAlgebras/cartan_matrix/index.html | 31 - .../ideals_and_subalgebras/index.html | 2 - .../LieAlgebras/introduction/index.html | 2 - .../LieAlgebras/lie_algebra_homs/index.html | 45 - .../LieAlgebras/lie_algebras/index.html | 159 -- .../LieAlgebras/module_homs/index.html | 55 - .../LieAlgebras/modules/index.html | 123 -- .../LinearQuotients/cox_rings/index.html | 2 - .../LinearQuotients/introduction/index.html | 2 - .../linear_quotients/index.html | 2 - .../introduction/index.html | 109 -- .../OrthogonalDiscriminants/access/index.html | 23 - .../compute/index.html | 43 - .../introduction/index.html | 2 - .../OrthogonalDiscriminants/misc/index.html | 39 - .../introduction/index.html | 14 - .../QuadFormAndIsom/enumeration/index.html | 128 -- .../QuadFormAndIsom/introduction/index.html | 17 - .../QuadFormAndIsom/latwithisom/index.html | 1091 ------------ .../QuadFormAndIsom/primembed/index.html | 37 - .../QuadFormAndIsom/spacewithisom/index.html | 371 ----- .../Singularities/intro/index.html | 2 - .../Singularities/space_germs/index.html | 7 - .../introduction/index.html | 3 - previews/PR4245/Experimental/intro/index.html | 12 - .../Fields/algebraic_closure_fp/index.html | 11 - previews/PR4245/Fields/intro/index.html | 2 - .../PR4245/General/architecture/index.html | 24 - previews/PR4245/General/complex/index.html | 2 - previews/PR4245/General/faq/index.html | 18 - previews/PR4245/General/other/index.html | 20 - .../PR4245/General/serialization/index.html | 84 - previews/PR4245/Groups/action/index.html | 214 --- previews/PR4245/Groups/autgroup/index.html | 96 -- previews/PR4245/Groups/basics/index.html | 215 --- previews/PR4245/Groups/fpgroup/index.html | 101 -- .../PR4245/Groups/group_characters/index.html | 462 ------ previews/PR4245/Groups/grouphom/index.html | 82 - previews/PR4245/Groups/grouplib/index.html | 271 --- previews/PR4245/Groups/intro/index.html | 2 - previews/PR4245/Groups/matgroup/index.html | 127 -- previews/PR4245/Groups/pcgroup/index.html | 52 - previews/PR4245/Groups/permgroup/index.html | 404 ----- previews/PR4245/Groups/products/index.html | 135 -- previews/PR4245/Groups/quotients/index.html | 36 - previews/PR4245/Groups/recog/index.html | 22 - previews/PR4245/Groups/subgroups/index.html | 474 ------ previews/PR4245/Groups/tom/index.html | 68 - previews/PR4245/Hecke/.vitepress/config.mts | 169 -- .../PR4245/Hecke/.vitepress/theme/index.ts | 19 - .../PR4245/Hecke/.vitepress/theme/style.css | 210 --- .../Hecke/.vitepress/theme/style.css.backu | 179 -- previews/PR4245/Hecke/Hecke.bib | 86 - previews/PR4245/Hecke/css/extra.css | 64 - previews/PR4245/Hecke/examples/index.html | 2 - previews/PR4245/Hecke/howto/index.html | 2 - .../PR4245/Hecke/howto/reduction/index.html | 10 - previews/PR4245/Hecke/index.html | 37 - .../Hecke/manual/abelian/elements/index.html | 8 - .../manual/abelian/introduction/index.html | 6 - .../Hecke/manual/abelian/maps/index.html | 6 - .../manual/abelian/structural/index.html | 84 - .../Hecke/manual/algebras/basics/index.html | 32 - .../manual/algebras/groupalgebras/index.html | 15 - .../Hecke/manual/algebras/intro/index.html | 2 - .../algebras/structureconstant/index.html | 17 - .../manual/developer/documentation/index.html | 4 - .../Hecke/manual/developer/test/index.html | 35 - .../manual/elliptic_curves/basics/index.html | 51 - .../elliptic_curves/finite_fields/index.html | 62 - .../manual/elliptic_curves/intro/index.html | 2 - .../elliptic_curves/number_fields/index.html | 2 - previews/PR4245/Hecke/manual/index.html | 2 - .../Hecke/manual/misc/FacElem/index.html | 9 - .../Hecke/manual/misc/conjugacy/index.html | 15 - .../PR4245/Hecke/manual/misc/mset/index.html | 157 -- .../PR4245/Hecke/manual/misc/pmat/index.html | 19 - .../Hecke/manual/misc/sparse/index.html | 5 - .../number_fields/class_fields/index.html | 15 - .../complex_embeddings/index.html | 131 -- .../number_fields/conventions/index.html | 11 - .../manual/number_fields/elements/index.html | 14 - .../manual/number_fields/fields/index.html | 64 - .../manual/number_fields/internal/index.html | 2 - .../manual/number_fields/intro/index.html | 2 - .../Hecke/manual/orders/elements/index.html | 44 - .../manual/orders/frac_ideals/index.html | 6 - .../Hecke/manual/orders/ideals/index.html | 92 -- .../manual/orders/introduction/index.html | 16 - .../Hecke/manual/orders/orders/index.html | 11 - .../manual/quad_forms/Zgenera/index.html | 5 - .../Hecke/manual/quad_forms/basics/index.html | 35 - .../quad_forms/discriminant_group/index.html | 196 --- .../manual/quad_forms/genusherm/index.html | 139 -- .../quad_forms/integer_lattices/index.html | 412 ----- .../manual/quad_forms/introduction/index.html | 2 - .../manual/quad_forms/lattices/index.html | 260 --- previews/PR4245/Hecke/start/index.html | 4 - previews/PR4245/Hecke/tutorials/index.html | 2 - .../InvariantTheory/finite_groups/index.html | 506 ------ .../PR4245/InvariantTheory/intro/index.html | 2 - .../reductive_groups/index.html | 59 - .../PR4245/InvariantTheory/tori/index.html | 50 - .../PR4245/LinearAlgebra/intro/index.html | 2 - previews/PR4245/Nemo/about/index.html | 2 - previews/PR4245/Nemo/acb/index.html | 204 --- previews/PR4245/Nemo/algebraic/index.html | 121 -- previews/PR4245/Nemo/arb/index.html | 244 --- previews/PR4245/Nemo/complex/index.html | 175 -- previews/PR4245/Nemo/constructors/index.html | 12 - .../Nemo/developer/conventions/index.html | 2 - previews/PR4245/Nemo/developer/img/types.svg | 3 - previews/PR4245/Nemo/developer/img/types2.svg | 3 - .../Nemo/developer/interfaces/index.html | 2 - .../Nemo/developer/introduction/index.html | 7 - .../PR4245/Nemo/developer/parents/index.html | 2 - .../PR4245/Nemo/developer/topics/index.html | 6 - .../Nemo/developer/typesystem/index.html | 2 - previews/PR4245/Nemo/exact/index.html | 176 -- previews/PR4245/Nemo/factor/index.html | 21 - previews/PR4245/Nemo/ff_embedding/index.html | 34 - previews/PR4245/Nemo/finitefield/index.html | 47 - previews/PR4245/Nemo/fraction/index.html | 36 - previews/PR4245/Nemo/gfp/index.html | 13 - previews/PR4245/Nemo/img/types.dia | Bin 3033 -> 0 bytes previews/PR4245/Nemo/img/types.png | Bin 17782 -> 0 bytes previews/PR4245/Nemo/index.html | 68 - previews/PR4245/Nemo/integer/index.html | 183 -- previews/PR4245/Nemo/mathjaxhelper.js | 10 - previews/PR4245/Nemo/matrix/index.html | 239 --- previews/PR4245/Nemo/misc/index.html | 16 - previews/PR4245/Nemo/mpolynomial/index.html | 2 - previews/PR4245/Nemo/numberfield/index.html | 87 - previews/PR4245/Nemo/padic/index.html | 107 -- previews/PR4245/Nemo/polynomial/index.html | 158 -- previews/PR4245/Nemo/puiseux/index.html | 12 - previews/PR4245/Nemo/qadic/index.html | 88 - previews/PR4245/Nemo/rational/index.html | 2 - previews/PR4245/Nemo/real/index.html | 225 --- previews/PR4245/Nemo/residue/index.html | 5 - previews/PR4245/Nemo/series/index.html | 27 - previews/PR4245/Nemo/types/index.html | 2 - .../PBWAlgebras/creation/index.html | 90 - .../PBWAlgebras/ideals/index.html | 318 ---- .../PBWAlgebras/intro/index.html | 2 - .../PBWAlgebras/quotients/index.html | 89 - .../free_associative_algebra/index.html | 23 - .../NoncommutativeAlgebra/intro/index.html | 2 - .../NumberTheory/abelian_closure/index.html | 54 - .../PR4245/NumberTheory/galois/index.html | 173 -- previews/PR4245/NumberTheory/intro/index.html | 2 - .../PR4245/NumberTheory/vinberg/index.html | 2 - .../Polyhedra/auxiliary/index.html | 628 ------- .../Polyhedra/constructions/index.html | 723 -------- .../Polyhedra/intro/index.html | 2 - .../Polyhedra/polymake/index.html | 42 - .../PolyhedralGeometry/cones/index.html | 234 --- .../PR4245/PolyhedralGeometry/fans/index.html | 268 --- .../PolyhedralGeometry/intro/index.html | 92 -- .../linear_programs/index.html | 123 -- .../mixed_integer_linear_programs/index.html | 45 - .../polyhedral_complexes/index.html | 326 ---- .../subdivisions_of_points/index.html | 124 -- previews/PR4245/Rings/integer/index.html | 225 --- previews/PR4245/Rings/intro/index.html | 2 - previews/PR4245/Rings/rational/index.html | 107 -- .../abstractalgebra/index.html | 140 -- .../StraightLinePrograms/gapslps/index.html | 91 - .../StraightLinePrograms/intro/index.html | 134 -- .../PR4245/TropicalGeometry/curve/index.html | 34 - .../groebner_theory/index.html | 59 - .../TropicalGeometry/hypersurface/index.html | 89 - .../PR4245/TropicalGeometry/intro/index.html | 2 - .../TropicalGeometry/linear_space/index.html | 58 - .../TropicalGeometry/semiring/index.html | 79 - .../TropicalGeometry/semiring_map/index.html | 54 - .../tropicalization/index.html | 11 - .../TropicalGeometry/variety/index.html | 57 - previews/PR4245/assets/documenter.js | 1064 ------------ previews/PR4245/assets/logo.png | Bin 15093 -> 0 bytes .../assets/themes/catppuccin-frappe.css | 1 - .../PR4245/assets/themes/catppuccin-latte.css | 1 - .../assets/themes/catppuccin-macchiato.css | 1 - .../PR4245/assets/themes/catppuccin-mocha.css | 1 - .../PR4245/assets/themes/documenter-dark.css | 7 - .../PR4245/assets/themes/documenter-light.css | 9 - previews/PR4245/assets/themeswap.js | 84 - previews/PR4245/assets/warner.js | 52 - previews/PR4245/index.html | 2 - previews/PR4245/manualindex/index.html | 2 - previews/PR4245/objects.inv | Bin 136446 -> 0 bytes previews/PR4245/references/index.html | 14 - previews/PR4245/search_index.js | 3 - previews/PR4245/siteinfo.js | 1 - 372 files changed, 40294 deletions(-) delete mode 100644 previews/PR4245/.documenter-siteinfo.json delete mode 100644 previews/PR4245/AbstractAlgebra/assertions/index.html delete mode 100644 previews/PR4245/AbstractAlgebra/assets/elements_diagram.svg delete mode 100644 previews/PR4245/AbstractAlgebra/assets/parents_diagram.svg delete mode 100644 previews/PR4245/AbstractAlgebra/constructors/index.html delete mode 100644 previews/PR4245/AbstractAlgebra/direct_sum/index.html delete mode 100644 previews/PR4245/AbstractAlgebra/euclidean_interface/index.html delete mode 100644 previews/PR4245/AbstractAlgebra/extending_abstractalgebra/index.html delete mode 100644 previews/PR4245/AbstractAlgebra/field/index.html delete mode 100644 previews/PR4245/AbstractAlgebra/field_interface/index.html delete mode 100644 previews/PR4245/AbstractAlgebra/field_introduction/index.html delete mode 100644 previews/PR4245/AbstractAlgebra/finfield/index.html delete mode 100644 previews/PR4245/AbstractAlgebra/fraction/index.html delete mode 100644 previews/PR4245/AbstractAlgebra/fraction_interface/index.html delete mode 100644 previews/PR4245/AbstractAlgebra/free_associative_algebra/index.html delete mode 100644 previews/PR4245/AbstractAlgebra/free_module/index.html delete mode 100644 previews/PR4245/AbstractAlgebra/function_field/index.html delete mode 100644 previews/PR4245/AbstractAlgebra/functional_map/index.html delete mode 100644 previews/PR4245/AbstractAlgebra/ideal/index.html delete mode 100644 previews/PR4245/AbstractAlgebra/img/types.dia delete mode 100644 previews/PR4245/AbstractAlgebra/img/types.png delete mode 100644 previews/PR4245/AbstractAlgebra/index.html delete mode 100644 previews/PR4245/AbstractAlgebra/integer/index.html delete mode 100644 previews/PR4245/AbstractAlgebra/interface_introduction/index.html delete mode 100644 previews/PR4245/AbstractAlgebra/laurent_mpolynomial/index.html delete mode 100644 previews/PR4245/AbstractAlgebra/laurent_polynomial/index.html delete mode 100644 previews/PR4245/AbstractAlgebra/linear_solving/index.html delete mode 100644 previews/PR4245/AbstractAlgebra/map_cache/index.html delete mode 100644 previews/PR4245/AbstractAlgebra/map_interface/index.html delete mode 100644 previews/PR4245/AbstractAlgebra/map_introduction/index.html delete mode 100644 previews/PR4245/AbstractAlgebra/map_with_inverse/index.html delete mode 100644 previews/PR4245/AbstractAlgebra/mathjaxhelper.js delete mode 100644 previews/PR4245/AbstractAlgebra/matrix/index.html delete mode 100644 previews/PR4245/AbstractAlgebra/matrix_algebras/index.html delete mode 100644 previews/PR4245/AbstractAlgebra/matrix_interface/index.html delete mode 100644 previews/PR4245/AbstractAlgebra/matrix_introduction/index.html delete mode 100644 previews/PR4245/AbstractAlgebra/misc/index.html delete mode 100644 previews/PR4245/AbstractAlgebra/module/index.html delete mode 100644 previews/PR4245/AbstractAlgebra/module_homomorphism/index.html delete mode 100644 previews/PR4245/AbstractAlgebra/module_interface/index.html delete mode 100644 previews/PR4245/AbstractAlgebra/module_introduction/index.html delete mode 100644 previews/PR4245/AbstractAlgebra/mpoly_interface/index.html delete mode 100644 previews/PR4245/AbstractAlgebra/mpolynomial/index.html delete mode 100644 previews/PR4245/AbstractAlgebra/mseries/index.html delete mode 100644 previews/PR4245/AbstractAlgebra/ncpolynomial/index.html delete mode 100644 previews/PR4245/AbstractAlgebra/ncring_interface/index.html delete mode 100644 previews/PR4245/AbstractAlgebra/perm/index.html delete mode 100644 previews/PR4245/AbstractAlgebra/poly_interface/index.html delete mode 100644 previews/PR4245/AbstractAlgebra/polynomial/index.html delete mode 100644 previews/PR4245/AbstractAlgebra/puiseux/index.html delete mode 100644 previews/PR4245/AbstractAlgebra/quotient_module/index.html delete mode 100644 previews/PR4245/AbstractAlgebra/rand/index.html delete mode 100644 previews/PR4245/AbstractAlgebra/rational/index.html delete mode 100644 previews/PR4245/AbstractAlgebra/real/index.html delete mode 100644 previews/PR4245/AbstractAlgebra/residue/index.html delete mode 100644 previews/PR4245/AbstractAlgebra/residue_interface/index.html delete mode 100644 previews/PR4245/AbstractAlgebra/ring/index.html delete mode 100644 previews/PR4245/AbstractAlgebra/ring_interface/index.html delete mode 100644 previews/PR4245/AbstractAlgebra/ring_introduction/index.html delete mode 100644 previews/PR4245/AbstractAlgebra/series/index.html delete mode 100644 previews/PR4245/AbstractAlgebra/series_interface/index.html delete mode 100644 previews/PR4245/AbstractAlgebra/submodule/index.html delete mode 100644 previews/PR4245/AbstractAlgebra/total_fraction/index.html delete mode 100644 previews/PR4245/AbstractAlgebra/types/index.html delete mode 100644 previews/PR4245/AbstractAlgebra/univpolynomial/index.html delete mode 100644 previews/PR4245/AbstractAlgebra/visualizing_types/index.html delete mode 100644 previews/PR4245/AbstractAlgebra/ytabs/index.html delete mode 100644 previews/PR4245/AlgebraicGeometry/AlgebraicSets/AffineAlgebraicSet/index.html delete mode 100644 previews/PR4245/AlgebraicGeometry/AlgebraicSets/ProjectiveAlgebraicSet/index.html delete mode 100644 previews/PR4245/AlgebraicGeometry/AlgebraicVarieties/AffineVariety/index.html delete mode 100644 previews/PR4245/AlgebraicGeometry/AlgebraicVarieties/ProjectiveVariety/index.html delete mode 100644 previews/PR4245/AlgebraicGeometry/Curves/AffinePlaneCurves/index.html delete mode 100644 previews/PR4245/AlgebraicGeometry/Curves/ParametrizationPlaneCurves/index.html delete mode 100644 previews/PR4245/AlgebraicGeometry/Curves/ProjectiveCurves/index.html delete mode 100644 previews/PR4245/AlgebraicGeometry/Curves/ProjectivePlaneCurves/index.html delete mode 100644 previews/PR4245/AlgebraicGeometry/FrameWorks/ArchitectureOfAffineSchemes/index.html delete mode 100644 previews/PR4245/AlgebraicGeometry/Miscellaneous/miscellaneous/index.html delete mode 100644 previews/PR4245/AlgebraicGeometry/Schemes/AffineSchemes/index.html delete mode 100644 previews/PR4245/AlgebraicGeometry/Schemes/CoveredSchemeMorphisms/index.html delete mode 100644 previews/PR4245/AlgebraicGeometry/Schemes/CoveredSchemes/index.html delete mode 100644 previews/PR4245/AlgebraicGeometry/Schemes/CoveringsAndGluings/index.html delete mode 100644 previews/PR4245/AlgebraicGeometry/Schemes/Cycles/index.html delete mode 100644 previews/PR4245/AlgebraicGeometry/Schemes/GeneralSchemes/index.html delete mode 100644 previews/PR4245/AlgebraicGeometry/Schemes/MorphismsOfAffineSchemes/index.html delete mode 100644 previews/PR4245/AlgebraicGeometry/Schemes/MorphismsOfProjectiveSchemes/index.html delete mode 100644 previews/PR4245/AlgebraicGeometry/Schemes/ProjectiveSchemes/index.html delete mode 100644 previews/PR4245/AlgebraicGeometry/Schemes/RationalPointsAffine/index.html delete mode 100644 previews/PR4245/AlgebraicGeometry/Schemes/RationalPointsProjective/index.html delete mode 100644 previews/PR4245/AlgebraicGeometry/Schemes/Sheaves/index.html delete mode 100644 previews/PR4245/AlgebraicGeometry/Schemes/intro/index.html delete mode 100644 previews/PR4245/AlgebraicGeometry/SheafCohomology/sheaf_cohomology/index.html delete mode 100644 previews/PR4245/AlgebraicGeometry/Surfaces/AdjunctionProcess/index.html delete mode 100644 previews/PR4245/AlgebraicGeometry/Surfaces/K3Surfaces/index.html delete mode 100644 previews/PR4245/AlgebraicGeometry/Surfaces/ParametrizationSurfaces/index.html delete mode 100644 previews/PR4245/AlgebraicGeometry/Surfaces/SurfacesP4/index.html delete mode 100644 previews/PR4245/AlgebraicGeometry/Surfaces/duValSing/index.html delete mode 100644 previews/PR4245/AlgebraicGeometry/ToricVarieties/AlgebraicCycles/index.html delete mode 100644 previews/PR4245/AlgebraicGeometry/ToricVarieties/BlowupMorphisms/index.html delete mode 100644 previews/PR4245/AlgebraicGeometry/ToricVarieties/CohomologyClasses/index.html delete mode 100644 previews/PR4245/AlgebraicGeometry/ToricVarieties/CyclicQuotientSingularities/index.html delete mode 100644 previews/PR4245/AlgebraicGeometry/ToricVarieties/NormalToricVarieties/index.html delete mode 100644 previews/PR4245/AlgebraicGeometry/ToricVarieties/Subvarieties/index.html delete mode 100644 previews/PR4245/AlgebraicGeometry/ToricVarieties/ToricDivisorClasses/index.html delete mode 100644 previews/PR4245/AlgebraicGeometry/ToricVarieties/ToricDivisors/index.html delete mode 100644 previews/PR4245/AlgebraicGeometry/ToricVarieties/ToricIdealSheaves/index.html delete mode 100644 previews/PR4245/AlgebraicGeometry/ToricVarieties/ToricLineBundles/index.html delete mode 100644 previews/PR4245/AlgebraicGeometry/ToricVarieties/ToricMorphisms/index.html delete mode 100644 previews/PR4245/AlgebraicGeometry/ToricVarieties/ToricSchemes/index.html delete mode 100644 previews/PR4245/AlgebraicGeometry/ToricVarieties/cohomCalg/index.html delete mode 100644 previews/PR4245/AlgebraicGeometry/ToricVarieties/intro/index.html delete mode 100644 previews/PR4245/AlgebraicGeometry/intro/index.html delete mode 100644 previews/PR4245/Combinatorics/EnumerativeCombinatorics/compositions/index.html delete mode 100644 previews/PR4245/Combinatorics/EnumerativeCombinatorics/partitions/index.html delete mode 100644 previews/PR4245/Combinatorics/EnumerativeCombinatorics/schur_polynomials/index.html delete mode 100644 previews/PR4245/Combinatorics/EnumerativeCombinatorics/tableaux/index.html delete mode 100644 previews/PR4245/Combinatorics/graphs/index.html delete mode 100644 previews/PR4245/Combinatorics/intro/index.html delete mode 100644 previews/PR4245/Combinatorics/matroids/index.html delete mode 100644 previews/PR4245/Combinatorics/phylogenetic_trees/index.html delete mode 100644 previews/PR4245/Combinatorics/simplicialcomplexes/index.html delete mode 100644 previews/PR4245/CommutativeAlgebra/FrameWorks/module_localizations/index.html delete mode 100644 previews/PR4245/CommutativeAlgebra/FrameWorks/ring_localizations/index.html delete mode 100644 previews/PR4245/CommutativeAlgebra/GroebnerBases/groebner_bases/index.html delete mode 100644 previews/PR4245/CommutativeAlgebra/GroebnerBases/groebner_bases_integers/index.html delete mode 100644 previews/PR4245/CommutativeAlgebra/GroebnerBases/orderings/index.html delete mode 100644 previews/PR4245/CommutativeAlgebra/Miscellaneous/binomial_ideals/index.html delete mode 100644 previews/PR4245/CommutativeAlgebra/ModulesOverMultivariateRings/complexes/index.html delete mode 100644 previews/PR4245/CommutativeAlgebra/ModulesOverMultivariateRings/free_modules/index.html delete mode 100644 previews/PR4245/CommutativeAlgebra/ModulesOverMultivariateRings/hom_operations/index.html delete mode 100644 previews/PR4245/CommutativeAlgebra/ModulesOverMultivariateRings/ideals_quorings_as_modules/index.html delete mode 100644 previews/PR4245/CommutativeAlgebra/ModulesOverMultivariateRings/intro/index.html delete mode 100644 previews/PR4245/CommutativeAlgebra/ModulesOverMultivariateRings/module_operations/index.html delete mode 100644 previews/PR4245/CommutativeAlgebra/ModulesOverMultivariateRings/subquotients/index.html delete mode 100644 previews/PR4245/CommutativeAlgebra/affine_algebras/index.html delete mode 100644 previews/PR4245/CommutativeAlgebra/homological_algebra/index.html delete mode 100644 previews/PR4245/CommutativeAlgebra/ideals/index.html delete mode 100644 previews/PR4245/CommutativeAlgebra/intro/index.html delete mode 100644 previews/PR4245/CommutativeAlgebra/localizations/index.html delete mode 100644 previews/PR4245/CommutativeAlgebra/rings/index.html delete mode 100644 previews/PR4245/DeveloperDocumentation/AbstractCollection/index.html delete mode 100644 previews/PR4245/DeveloperDocumentation/SubObjectIterator/index.html delete mode 100644 previews/PR4245/DeveloperDocumentation/caching/index.html delete mode 100644 previews/PR4245/DeveloperDocumentation/debugging/index.html delete mode 100644 previews/PR4245/DeveloperDocumentation/design_decisions/index.html delete mode 100644 previews/PR4245/DeveloperDocumentation/documentation/index.html delete mode 100644 previews/PR4245/DeveloperDocumentation/gap_integration/index.html delete mode 100644 previews/PR4245/DeveloperDocumentation/new_developers/index.html delete mode 100644 previews/PR4245/DeveloperDocumentation/printing_details/index.html delete mode 100644 previews/PR4245/DeveloperDocumentation/release/index.html delete mode 100644 previews/PR4245/DeveloperDocumentation/serialization/index.html delete mode 100644 previews/PR4245/DeveloperDocumentation/styleguide/index.html delete mode 100644 previews/PR4245/Experimental/AlgebraicStatistics/ci/index.html delete mode 100644 previews/PR4245/Experimental/AlgebraicStatistics/gaussian_graphical_models/index.html delete mode 100644 previews/PR4245/Experimental/AlgebraicStatistics/graphical_models/index.html delete mode 100644 previews/PR4245/Experimental/AlgebraicStatistics/introduction/index.html delete mode 100644 previews/PR4245/Experimental/AlgebraicStatistics/markov/index.html delete mode 100644 previews/PR4245/Experimental/AlgebraicStatistics/phylogenetics/index.html delete mode 100644 previews/PR4245/Experimental/BasisLieHighestWeight/introduction/index.html delete mode 100644 previews/PR4245/Experimental/BasisLieHighestWeight/user_functions/index.html delete mode 100644 previews/PR4245/Experimental/DoubleAndHyperComplexes/advice_for_the_programmer/index.html delete mode 100644 previews/PR4245/Experimental/DoubleAndHyperComplexes/user_interface/index.html delete mode 100644 previews/PR4245/Experimental/FTheoryTools/g4/index.html delete mode 100644 previews/PR4245/Experimental/FTheoryTools/generalities/index.html delete mode 100644 previews/PR4245/Experimental/FTheoryTools/hypersurface/index.html delete mode 100644 previews/PR4245/Experimental/FTheoryTools/introduction/index.html delete mode 100644 previews/PR4245/Experimental/FTheoryTools/literature/index.html delete mode 100644 previews/PR4245/Experimental/FTheoryTools/tate/index.html delete mode 100644 previews/PR4245/Experimental/FTheoryTools/weierstrass/index.html delete mode 100644 previews/PR4245/Experimental/GroebnerWalk/introduction/index.html delete mode 100644 previews/PR4245/Experimental/GroebnerWalk/special-ideals/index.html delete mode 100644 previews/PR4245/Experimental/IntersectionTheory/AbstractBundles/index.html delete mode 100644 previews/PR4245/Experimental/IntersectionTheory/AbstractVarieties/index.html delete mode 100644 previews/PR4245/Experimental/IntersectionTheory/AbstractVarietyMaps/index.html delete mode 100644 previews/PR4245/Experimental/IntersectionTheory/BlowUps/index.html delete mode 100644 previews/PR4245/Experimental/IntersectionTheory/BottFormulas/index.html delete mode 100644 previews/PR4245/Experimental/IntersectionTheory/examples/index.html delete mode 100644 previews/PR4245/Experimental/IntersectionTheory/intro/index.html delete mode 100644 previews/PR4245/Experimental/IntersectionTheory/schubert/index.html delete mode 100644 previews/PR4245/Experimental/LieAlgebras/cartan_matrix/index.html delete mode 100644 previews/PR4245/Experimental/LieAlgebras/ideals_and_subalgebras/index.html delete mode 100644 previews/PR4245/Experimental/LieAlgebras/introduction/index.html delete mode 100644 previews/PR4245/Experimental/LieAlgebras/lie_algebra_homs/index.html delete mode 100644 previews/PR4245/Experimental/LieAlgebras/lie_algebras/index.html delete mode 100644 previews/PR4245/Experimental/LieAlgebras/module_homs/index.html delete mode 100644 previews/PR4245/Experimental/LieAlgebras/modules/index.html delete mode 100644 previews/PR4245/Experimental/LinearQuotients/cox_rings/index.html delete mode 100644 previews/PR4245/Experimental/LinearQuotients/introduction/index.html delete mode 100644 previews/PR4245/Experimental/LinearQuotients/linear_quotients/index.html delete mode 100644 previews/PR4245/Experimental/MatroidRealizationSpaces/introduction/index.html delete mode 100644 previews/PR4245/Experimental/OrthogonalDiscriminants/access/index.html delete mode 100644 previews/PR4245/Experimental/OrthogonalDiscriminants/compute/index.html delete mode 100644 previews/PR4245/Experimental/OrthogonalDiscriminants/introduction/index.html delete mode 100644 previews/PR4245/Experimental/OrthogonalDiscriminants/misc/index.html delete mode 100644 previews/PR4245/Experimental/PartitionedPermutations/introduction/index.html delete mode 100644 previews/PR4245/Experimental/QuadFormAndIsom/enumeration/index.html delete mode 100644 previews/PR4245/Experimental/QuadFormAndIsom/introduction/index.html delete mode 100644 previews/PR4245/Experimental/QuadFormAndIsom/latwithisom/index.html delete mode 100644 previews/PR4245/Experimental/QuadFormAndIsom/primembed/index.html delete mode 100644 previews/PR4245/Experimental/QuadFormAndIsom/spacewithisom/index.html delete mode 100644 previews/PR4245/Experimental/Singularities/intro/index.html delete mode 100644 previews/PR4245/Experimental/Singularities/space_germs/index.html delete mode 100644 previews/PR4245/Experimental/StandardFiniteFields/introduction/index.html delete mode 100644 previews/PR4245/Experimental/intro/index.html delete mode 100644 previews/PR4245/Fields/algebraic_closure_fp/index.html delete mode 100644 previews/PR4245/Fields/intro/index.html delete mode 100644 previews/PR4245/General/architecture/index.html delete mode 100644 previews/PR4245/General/complex/index.html delete mode 100644 previews/PR4245/General/faq/index.html delete mode 100644 previews/PR4245/General/other/index.html delete mode 100644 previews/PR4245/General/serialization/index.html delete mode 100644 previews/PR4245/Groups/action/index.html delete mode 100644 previews/PR4245/Groups/autgroup/index.html delete mode 100644 previews/PR4245/Groups/basics/index.html delete mode 100644 previews/PR4245/Groups/fpgroup/index.html delete mode 100644 previews/PR4245/Groups/group_characters/index.html delete mode 100644 previews/PR4245/Groups/grouphom/index.html delete mode 100644 previews/PR4245/Groups/grouplib/index.html delete mode 100644 previews/PR4245/Groups/intro/index.html delete mode 100644 previews/PR4245/Groups/matgroup/index.html delete mode 100644 previews/PR4245/Groups/pcgroup/index.html delete mode 100644 previews/PR4245/Groups/permgroup/index.html delete mode 100644 previews/PR4245/Groups/products/index.html delete mode 100644 previews/PR4245/Groups/quotients/index.html delete mode 100644 previews/PR4245/Groups/recog/index.html delete mode 100644 previews/PR4245/Groups/subgroups/index.html delete mode 100644 previews/PR4245/Groups/tom/index.html delete mode 100644 previews/PR4245/Hecke/.vitepress/config.mts delete mode 100644 previews/PR4245/Hecke/.vitepress/theme/index.ts delete mode 100644 previews/PR4245/Hecke/.vitepress/theme/style.css delete mode 100644 previews/PR4245/Hecke/.vitepress/theme/style.css.backu delete mode 100644 previews/PR4245/Hecke/Hecke.bib delete mode 100644 previews/PR4245/Hecke/css/extra.css delete mode 100644 previews/PR4245/Hecke/examples/index.html delete mode 100644 previews/PR4245/Hecke/howto/index.html delete mode 100644 previews/PR4245/Hecke/howto/reduction/index.html delete mode 100644 previews/PR4245/Hecke/index.html delete mode 100644 previews/PR4245/Hecke/manual/abelian/elements/index.html delete mode 100644 previews/PR4245/Hecke/manual/abelian/introduction/index.html delete mode 100644 previews/PR4245/Hecke/manual/abelian/maps/index.html delete mode 100644 previews/PR4245/Hecke/manual/abelian/structural/index.html delete mode 100644 previews/PR4245/Hecke/manual/algebras/basics/index.html delete mode 100644 previews/PR4245/Hecke/manual/algebras/groupalgebras/index.html delete mode 100644 previews/PR4245/Hecke/manual/algebras/intro/index.html delete mode 100644 previews/PR4245/Hecke/manual/algebras/structureconstant/index.html delete mode 100644 previews/PR4245/Hecke/manual/developer/documentation/index.html delete mode 100644 previews/PR4245/Hecke/manual/developer/test/index.html delete mode 100644 previews/PR4245/Hecke/manual/elliptic_curves/basics/index.html delete mode 100644 previews/PR4245/Hecke/manual/elliptic_curves/finite_fields/index.html delete mode 100644 previews/PR4245/Hecke/manual/elliptic_curves/intro/index.html delete mode 100644 previews/PR4245/Hecke/manual/elliptic_curves/number_fields/index.html delete mode 100644 previews/PR4245/Hecke/manual/index.html delete mode 100644 previews/PR4245/Hecke/manual/misc/FacElem/index.html delete mode 100644 previews/PR4245/Hecke/manual/misc/conjugacy/index.html delete mode 100644 previews/PR4245/Hecke/manual/misc/mset/index.html delete mode 100644 previews/PR4245/Hecke/manual/misc/pmat/index.html delete mode 100644 previews/PR4245/Hecke/manual/misc/sparse/index.html delete mode 100644 previews/PR4245/Hecke/manual/number_fields/class_fields/index.html delete mode 100644 previews/PR4245/Hecke/manual/number_fields/complex_embeddings/index.html delete mode 100644 previews/PR4245/Hecke/manual/number_fields/conventions/index.html delete mode 100644 previews/PR4245/Hecke/manual/number_fields/elements/index.html delete mode 100644 previews/PR4245/Hecke/manual/number_fields/fields/index.html delete mode 100644 previews/PR4245/Hecke/manual/number_fields/internal/index.html delete mode 100644 previews/PR4245/Hecke/manual/number_fields/intro/index.html delete mode 100644 previews/PR4245/Hecke/manual/orders/elements/index.html delete mode 100644 previews/PR4245/Hecke/manual/orders/frac_ideals/index.html delete mode 100644 previews/PR4245/Hecke/manual/orders/ideals/index.html delete mode 100644 previews/PR4245/Hecke/manual/orders/introduction/index.html delete mode 100644 previews/PR4245/Hecke/manual/orders/orders/index.html delete mode 100644 previews/PR4245/Hecke/manual/quad_forms/Zgenera/index.html delete mode 100644 previews/PR4245/Hecke/manual/quad_forms/basics/index.html delete mode 100644 previews/PR4245/Hecke/manual/quad_forms/discriminant_group/index.html delete mode 100644 previews/PR4245/Hecke/manual/quad_forms/genusherm/index.html delete mode 100644 previews/PR4245/Hecke/manual/quad_forms/integer_lattices/index.html delete mode 100644 previews/PR4245/Hecke/manual/quad_forms/introduction/index.html delete mode 100644 previews/PR4245/Hecke/manual/quad_forms/lattices/index.html delete mode 100644 previews/PR4245/Hecke/start/index.html delete mode 100644 previews/PR4245/Hecke/tutorials/index.html delete mode 100644 previews/PR4245/InvariantTheory/finite_groups/index.html delete mode 100644 previews/PR4245/InvariantTheory/intro/index.html delete mode 100644 previews/PR4245/InvariantTheory/reductive_groups/index.html delete mode 100644 previews/PR4245/InvariantTheory/tori/index.html delete mode 100644 previews/PR4245/LinearAlgebra/intro/index.html delete mode 100644 previews/PR4245/Nemo/about/index.html delete mode 100644 previews/PR4245/Nemo/acb/index.html delete mode 100644 previews/PR4245/Nemo/algebraic/index.html delete mode 100644 previews/PR4245/Nemo/arb/index.html delete mode 100644 previews/PR4245/Nemo/complex/index.html delete mode 100644 previews/PR4245/Nemo/constructors/index.html delete mode 100644 previews/PR4245/Nemo/developer/conventions/index.html delete mode 100644 previews/PR4245/Nemo/developer/img/types.svg delete mode 100644 previews/PR4245/Nemo/developer/img/types2.svg delete mode 100644 previews/PR4245/Nemo/developer/interfaces/index.html delete mode 100644 previews/PR4245/Nemo/developer/introduction/index.html delete mode 100644 previews/PR4245/Nemo/developer/parents/index.html delete mode 100644 previews/PR4245/Nemo/developer/topics/index.html delete mode 100644 previews/PR4245/Nemo/developer/typesystem/index.html delete mode 100644 previews/PR4245/Nemo/exact/index.html delete mode 100644 previews/PR4245/Nemo/factor/index.html delete mode 100644 previews/PR4245/Nemo/ff_embedding/index.html delete mode 100644 previews/PR4245/Nemo/finitefield/index.html delete mode 100644 previews/PR4245/Nemo/fraction/index.html delete mode 100644 previews/PR4245/Nemo/gfp/index.html delete mode 100644 previews/PR4245/Nemo/img/types.dia delete mode 100644 previews/PR4245/Nemo/img/types.png delete mode 100644 previews/PR4245/Nemo/index.html delete mode 100644 previews/PR4245/Nemo/integer/index.html delete mode 100644 previews/PR4245/Nemo/mathjaxhelper.js delete mode 100644 previews/PR4245/Nemo/matrix/index.html delete mode 100644 previews/PR4245/Nemo/misc/index.html delete mode 100644 previews/PR4245/Nemo/mpolynomial/index.html delete mode 100644 previews/PR4245/Nemo/numberfield/index.html delete mode 100644 previews/PR4245/Nemo/padic/index.html delete mode 100644 previews/PR4245/Nemo/polynomial/index.html delete mode 100644 previews/PR4245/Nemo/puiseux/index.html delete mode 100644 previews/PR4245/Nemo/qadic/index.html delete mode 100644 previews/PR4245/Nemo/rational/index.html delete mode 100644 previews/PR4245/Nemo/real/index.html delete mode 100644 previews/PR4245/Nemo/residue/index.html delete mode 100644 previews/PR4245/Nemo/series/index.html delete mode 100644 previews/PR4245/Nemo/types/index.html delete mode 100644 previews/PR4245/NoncommutativeAlgebra/PBWAlgebras/creation/index.html delete mode 100644 previews/PR4245/NoncommutativeAlgebra/PBWAlgebras/ideals/index.html delete mode 100644 previews/PR4245/NoncommutativeAlgebra/PBWAlgebras/intro/index.html delete mode 100644 previews/PR4245/NoncommutativeAlgebra/PBWAlgebras/quotients/index.html delete mode 100644 previews/PR4245/NoncommutativeAlgebra/free_associative_algebra/index.html delete mode 100644 previews/PR4245/NoncommutativeAlgebra/intro/index.html delete mode 100644 previews/PR4245/NumberTheory/abelian_closure/index.html delete mode 100644 previews/PR4245/NumberTheory/galois/index.html delete mode 100644 previews/PR4245/NumberTheory/intro/index.html delete mode 100644 previews/PR4245/NumberTheory/vinberg/index.html delete mode 100644 previews/PR4245/PolyhedralGeometry/Polyhedra/auxiliary/index.html delete mode 100644 previews/PR4245/PolyhedralGeometry/Polyhedra/constructions/index.html delete mode 100644 previews/PR4245/PolyhedralGeometry/Polyhedra/intro/index.html delete mode 100644 previews/PR4245/PolyhedralGeometry/Polyhedra/polymake/index.html delete mode 100644 previews/PR4245/PolyhedralGeometry/cones/index.html delete mode 100644 previews/PR4245/PolyhedralGeometry/fans/index.html delete mode 100644 previews/PR4245/PolyhedralGeometry/intro/index.html delete mode 100644 previews/PR4245/PolyhedralGeometry/linear_programs/index.html delete mode 100644 previews/PR4245/PolyhedralGeometry/mixed_integer_linear_programs/index.html delete mode 100644 previews/PR4245/PolyhedralGeometry/polyhedral_complexes/index.html delete mode 100644 previews/PR4245/PolyhedralGeometry/subdivisions_of_points/index.html delete mode 100644 previews/PR4245/Rings/integer/index.html delete mode 100644 previews/PR4245/Rings/intro/index.html delete mode 100644 previews/PR4245/Rings/rational/index.html delete mode 100644 previews/PR4245/StraightLinePrograms/abstractalgebra/index.html delete mode 100644 previews/PR4245/StraightLinePrograms/gapslps/index.html delete mode 100644 previews/PR4245/StraightLinePrograms/intro/index.html delete mode 100644 previews/PR4245/TropicalGeometry/curve/index.html delete mode 100644 previews/PR4245/TropicalGeometry/groebner_theory/index.html delete mode 100644 previews/PR4245/TropicalGeometry/hypersurface/index.html delete mode 100644 previews/PR4245/TropicalGeometry/intro/index.html delete mode 100644 previews/PR4245/TropicalGeometry/linear_space/index.html delete mode 100644 previews/PR4245/TropicalGeometry/semiring/index.html delete mode 100644 previews/PR4245/TropicalGeometry/semiring_map/index.html delete mode 100644 previews/PR4245/TropicalGeometry/tropicalization/index.html delete mode 100644 previews/PR4245/TropicalGeometry/variety/index.html delete mode 100644 previews/PR4245/assets/documenter.js delete mode 100644 previews/PR4245/assets/logo.png delete mode 100644 previews/PR4245/assets/themes/catppuccin-frappe.css delete mode 100644 previews/PR4245/assets/themes/catppuccin-latte.css delete mode 100644 previews/PR4245/assets/themes/catppuccin-macchiato.css delete mode 100644 previews/PR4245/assets/themes/catppuccin-mocha.css delete mode 100644 previews/PR4245/assets/themes/documenter-dark.css delete mode 100644 previews/PR4245/assets/themes/documenter-light.css delete mode 100644 previews/PR4245/assets/themeswap.js delete mode 100644 previews/PR4245/assets/warner.js delete mode 100644 previews/PR4245/index.html delete mode 100644 previews/PR4245/manualindex/index.html delete mode 100644 previews/PR4245/objects.inv delete mode 100644 previews/PR4245/references/index.html delete mode 100644 previews/PR4245/search_index.js delete mode 100644 previews/PR4245/siteinfo.js diff --git a/previews/PR4245/.documenter-siteinfo.json b/previews/PR4245/.documenter-siteinfo.json deleted file mode 100644 index 2e1d978fed52..000000000000 --- a/previews/PR4245/.documenter-siteinfo.json +++ /dev/null @@ -1 +0,0 @@ -{"documenter":{"julia_version":"1.10.5","generation_timestamp":"2024-10-28T09:45:37","documenter_version":"1.7.0"}} \ No newline at end of file diff --git a/previews/PR4245/AbstractAlgebra/assertions/index.html b/previews/PR4245/AbstractAlgebra/assertions/index.html deleted file mode 100644 index fa95b1de87fb..000000000000 --- a/previews/PR4245/AbstractAlgebra/assertions/index.html +++ /dev/null @@ -1,143 +0,0 @@ - -Assertion and Verbosity Macros · Oscar.jl

Assertion and Verbosity Macros

We describe here various macros provided by AbstractAlgebra.

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
AbstractAlgebra.add_verbosity_scope(s::Symbol) -> Nothing

Add the symbol s to the list of (global) verbosity scopes.

Examples

julia> AbstractAlgebra.add_verbosity_scope(:MyScope)
-
source
set_verbosity_levelMethod
AbstractAlgebra.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> AbstractAlgebra.add_verbosity_scope(:MyScope)
-
-julia> AbstractAlgebra.set_verbosity_level(:MyScope, 4)
-4
-
-julia> AbstractAlgebra.set_verbosity_level(:MyScope, 0)
-0
source
get_verbosity_levelMethod
AbstractAlgebra.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> AbstractAlgebra.add_verbosity_scope(:MyScope)
-
-julia> AbstractAlgebra.get_verbosity_level(:MyScope)
-0
-
-julia> AbstractAlgebra.set_verbosity_level(:MyScope, 4)
-4
-
-julia> AbstractAlgebra.get_verbosity_level(:MyScope)
-4
-
-julia> AbstractAlgebra.set_verbosity_level(:MyScope, 0)
-0
-
-julia> AbstractAlgebra.get_verbosity_level(:MyScope)
-0
source

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> AbstractAlgebra.add_verbosity_scope(:Test1);
-
-julia> AbstractAlgebra.add_verbosity_scope(:Test2);
-
-julia> AbstractAlgebra.add_verbosity_scope(:Test3);
-
-julia> AbstractAlgebra.set_verbosity_level(:Test1, 1);
-
-julia> AbstractAlgebra.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".

source
@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.

source

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> AbstractAlgebra.add_verbosity_scope(:Test1);
-
-julia> AbstractAlgebra.add_verbosity_scope(:Test2);
-
-julia> AbstractAlgebra.add_verbosity_scope(:Test3);
-
-julia> AbstractAlgebra.set_verbosity_level(:Test1, 1);
-
-julia> AbstractAlgebra.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".

source

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
AbstractAlgebra.add_assertion_scope(s::Symbol) -> Nothing

Add the symbol s to the list of (global) assertion scopes.

Examples

julia> AbstractAlgebra.add_assertion_scope(:MyScope)
-
source
set_assertion_levelMethod
AbstractAlgebra.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> AbstractAlgebra.add_assertion_scope(:MyScope)
-
-julia> AbstractAlgebra.set_assertion_level(:MyScope, 4)
-4
-
-julia> AbstractAlgebra.set_assertion_level(:MyScope, 0)
-0
source
get_assertion_levelMethod
AbstractAlgebra.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> AbstractAlgebra.add_assertion_scope(:MyScope)
-
-julia> AbstractAlgebra.get_assertion_level(:MyScope)
-0
-
-julia> AbstractAlgebra.set_assertion_level(:MyScope, 1)
-1
-
-julia> AbstractAlgebra.get_assertion_level(:MyScope)
-1
-
-julia> AbstractAlgebra.set_assertion_level(:MyScope, 0)
-0
-
-julia> AbstractAlgebra.get_assertion_level(:MyScope)
-0
source

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> AbstractAlgebra.add_assertion_scope(:MyScope)
-
-julia> AbstractAlgebra.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> AbstractAlgebra.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> AbstractAlgebra.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".

source

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
-
source
diff --git a/previews/PR4245/AbstractAlgebra/assets/elements_diagram.svg b/previews/PR4245/AbstractAlgebra/assets/elements_diagram.svg deleted file mode 100644 index 00f248c36431..000000000000 --- a/previews/PR4245/AbstractAlgebra/assets/elements_diagram.svg +++ /dev/null @@ -1,162 +0,0 @@ -SetElemIdealElem{T}Map{D, C, S, T}SetMapIdentityMapFunctionalMapFPModuleHomomorphismGroupElemAbstractPermAdditiveGroupElemModuleElem{T}FPModuleElem{T}MatElem{T}NCRingElemMatRingElem{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/PR4245/AbstractAlgebra/assets/parents_diagram.svg b/previews/PR4245/AbstractAlgebra/assets/parents_diagram.svg deleted file mode 100644 index 93ac8313aada..000000000000 --- a/previews/PR4245/AbstractAlgebra/assets/parents_diagram.svg +++ /dev/null @@ -1,136 +0,0 @@ -SetIdeal{T}GroupAbstractPermutationGroupAdditiveGroupModule{T}FPModule{T}MatSpace{T}NCRingMatRing{T}NCPolyRing{T}RingFieldPolyRing{T}LaurentPolyRing{T}SeriesRing{T}ResidueRing{T}ResidueField{T}NumField{T}SimpleNumField{T}FracField{T}FinField \ No newline at end of file diff --git a/previews/PR4245/AbstractAlgebra/constructors/index.html b/previews/PR4245/AbstractAlgebra/constructors/index.html deleted file mode 100644 index acf7f06b9a78..000000000000 --- a/previews/PR4245/AbstractAlgebra/constructors/index.html +++ /dev/null @@ -1,97 +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\langle x, y\rangle$S, (x, y) = free_associative_algebra(R, [:x, :y])
$S = K(x)$S, x = rational_function_field(K, :x)
$S = K(x, y)$S, (x, y) = rational_function_field(K, [:x, :y])
$S = R[[x]]$ (to precision $n$)S, x = power_series_ring(R, n, :x)
$S = R[[x, y]]$ (to precision $n$)S, (x, y) = power_series_ring(R, n, [:x, :y])
$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 = R((x, y))$ (to precision $n$)S, (x, y) = laurent_polynomial_ring(R, n, [:x, :y])
Puiseux series ring to precision $n$S, x = puiseux_series_ring(R, n, :x)
Puiseux series field to precision $n$S, x = puiseux_series_field(K, n, :x)
$S = K(x)(y)/(f)$S, y = function_field(f, :y) with $f\in K(x)[t]$
$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)

Parent objects with variable names

The multivariate parent object constructors (polynomial_ring, power_series_ring, free_associative_algebra, laurent_polynomial_ring, and rational_function_field) share a common interface for specifying the variable names, which is provided by @varnames_interface.

@varnames_interfaceMacro
@varnames_interface [M.]f(args..., varnames) macros=:yes n=n range=1:n

Add methods X, vars = f(args..., varnames...) and macro X = @f(args..., varnames...) to current scope.

Created methods

X, gens::Vector{T} = f(args..., varnames::Vector{Symbol})

Base method, called by everything else defined below. If a module M is specified, this is implemented as a call to M.f. Otherwise, a method f with this signature must already exist.


X, gens... = f(args..., varnames...; kv...)
-X, gens... = f(args..., varnames::Tuple; kv...)

Compute X and gens via the base method. Then reshape gens into the shape defined by varnames according to variable_names.

The vararg varnames... method needs at least one argument to avoid confusion. Moreover a single VarName argument will be dispatched to use a univariate method of f if it exists (e.g. polynomial_ring(R, :x)). If you need those cases, use the Tuple method.

Keyword arguments are passed on to the base method.


X, x::Vector{T} = f(args..., n::Int, s::VarName = :x; kv...)

Shorthand for X, x = f(args..., "$s#" => 1:n; kv...). The name of the argument n can be changed via the n option. The range 1:n is given via the range option.

Setting n=:no disables creation of this method.


X = @f(args..., varnames...; kv...)
-X = @f(args..., varnames::Tuple; kv...)
-X = @f(args..., n::Int, s::VarName = :x; kv...)
-X = @f(args..., varname::VarName; kv...)

These macros behave like their f(args..., varnames; kv...) counterparts but also introduce the indexed varnames into the current scope. The first version needs at least one varnames argument to avoid confusion. The last version calls the univariate base method if it exists (e.g. polynomial_ring(R, varname)).

Setting macros=:no disables macro creation.

Warning

Turning varnames into a vector of symbols happens by evaluating variable_names(varnames) in the global scope of the current module. For interactive usage in the REPL this is fine, but in general you have no access to local variables and should not use any side effects in varnames.

Examples

julia> f(a, s::Vector{Symbol}) = a, String.(s)
-f (generic function with 1 method)
-
-julia> AbstractAlgebra.@varnames_interface f(a, s)
-@f (macro with 1 method)
-
-julia> f
-f (generic function with 5 methods)
-
-julia> f("hello", [:x, :y, :z])
-("hello", ["x", "y", "z"])
-
-julia> f("numbered", 3)
-("numbered", ["x1", "x2", "x3"])
-
-julia> f("hello", :x => (1:1, 1:2), :y => 1:2, [:z])
-("hello", ["x[1, 1]" "x[1, 2]"], ["y[1]", "y[2]"], ["z"])
-
-julia> f("projective", ["x$i$j" for i in 0:1, j in 0:1], [:y0, :y1], [:z])
-("projective", ["x00" "x01"; "x10" "x11"], ["y0", "y1"], ["z"])
-
-julia> f("fun inputs", 'a':'g', Symbol.('x':'z', [0 1]))
-("fun inputs", ["a", "b", "c", "d", "e", "f", "g"], ["x0" "x1"; "y0" "y1"; "z0" "z1"])
-
-julia> @f("hello", "x#" => (1:1, 1:2), "y#" => (1:2), [:z])
-"hello"
-
-julia> (x11, x12, y1, y2, z)
-("x11", "x12", "y1", "y2", "z")
-
-julia> g(a, s::Vector{Symbol}; kv...) = (a, kv...), String.(s)
-g (generic function with 1 method)
-
-julia> AbstractAlgebra.@varnames_interface g(a, s)
-@g (macro with 1 method)
-
-julia> @g("parameters", [:x, :y], a=1, b=2; c=3)
-("parameters", :c => 3, :a => 1, :b => 2)
source
variable_namesFunction
variable_names(a...) -> Vector{Symbol}
-variable_names(a::Tuple) -> Vector{Symbol}

Create a vector of variable names from a variable name specification.

Each argument can be either an Array of VarNames, or of the form s::VarName => iter, or of the form s::VarName => (iter...). Here iter is supposed to be any iterable, typically a range like 1:5. The :s => iter specification is shorthand for ["s[$i]" for i in iter]. Similarly :s => (iter1, iter2) is shorthand for ["s[$i,$j]" for i in iter1, j in iter2], and likewise for three and more iterables.

As an alternative "s#" => iter is shorthand for ["s$i" for i in iter]. This also works for multiple iterators in that"s#" => (iter1, iter2) is shorthand for ["s$i$j" for i in iter1, j in iter2].

Examples

julia> AbstractAlgebra.variable_names([:x, :y])
-2-element Vector{Symbol}:
- :x
- :y
-
-julia> AbstractAlgebra.variable_names(:x => (0:0, 0:1), :y => 0:1, [:z])
-5-element Vector{Symbol}:
- Symbol("x[0, 0]")
- Symbol("x[0, 1]")
- Symbol("y[0]")
- Symbol("y[1]")
- :z
-
-julia> AbstractAlgebra.variable_names("x#" => (0:0, 0:1), "y#" => 0:1)
-4-element Vector{Symbol}:
- :x00
- :x01
- :y0
- :y1
-
-julia> AbstractAlgebra.variable_names("x#" => 9:11)
-3-element Vector{Symbol}:
- :x9
- :x10
- :x11
-
-julia> AbstractAlgebra.variable_names(["x$i$i" for i in 1:3])
-3-element Vector{Symbol}:
- :x11
- :x22
- :x33
-
-julia> AbstractAlgebra.variable_names('a':'c', ['z'])
-4-element Vector{Symbol}:
- :a
- :b
- :c
- :z
source
reshape_to_varnamesFunction
reshape_to_varnames(vec::Vector{T}, varnames...) :: Tuple{Array{<:Any, T}}
-reshape_to_varnames(vec::Vector{T}, varnames::Tuple) :: Tuple{Array{<:Any, T}}

Turn vec into the shape of varnames. Reverse flattening from variable_names.

Examples

julia> s = ([:a, :b], "x#" => (1:1, 1:2), "y#" => 1:2, [:z]);
-
-julia> AbstractAlgebra.reshape_to_varnames(AbstractAlgebra.variable_names(s...), s...)
-([:a, :b], [:x11 :x12], [:y1, :y2], [:z])
-
-julia> R, v = polynomial_ring(ZZ, AbstractAlgebra.variable_names(s...))
-(Multivariate polynomial ring in 7 variables over integers, AbstractAlgebra.Generic.MPoly{BigInt}[a, b, x11, x12, y1, y2, z])
-
-julia> (a, b), x, y, z = AbstractAlgebra.reshape_to_varnames(v, s...)
-(AbstractAlgebra.Generic.MPoly{BigInt}[a, b], AbstractAlgebra.Generic.MPoly{BigInt}[x11 x12], AbstractAlgebra.Generic.MPoly{BigInt}[y1, y2], AbstractAlgebra.Generic.MPoly{BigInt}[z])
-
-julia> R, (a, b), x, y, z = polynomial_ring(ZZ, s...)
-(Multivariate polynomial ring in 7 variables over integers, AbstractAlgebra.Generic.MPoly{BigInt}[a, b], AbstractAlgebra.Generic.MPoly{BigInt}[x11 x12], AbstractAlgebra.Generic.MPoly{BigInt}[y1, y2], AbstractAlgebra.Generic.MPoly{BigInt}[z])
source
diff --git a/previews/PR4245/AbstractAlgebra/direct_sum/index.html b/previews/PR4245/AbstractAlgebra/direct_sum/index.html deleted file mode 100644 index 21b3b5e9892d..000000000000 --- a/previews/PR4245/AbstractAlgebra/direct_sum/index.html +++ /dev/null @@ -1,230 +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::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]$.

source
direct_sum(G::FinGenAbGroup...) -> FinGenAbGroup, Vector{FinGenAbGroupHom}

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 G_i$, one should call direct_product(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.

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).

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).

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

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).

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

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

source
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).

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

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

source
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.

source
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.

source
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.

source
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 [Oxl11].

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: quadratic space -> quadratic space, Map: quadratic space -> quadratic space])
-
-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]
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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: quadratic space -> quadratic space, Map: quadratic space -> quadratic space])
-
-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]
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source

For a vector of maps fi : M -> Ni compute the map f : M -> prod Ni : m -> (fi(m))_i

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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

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

Examples

julia> L = special_linear_lie_algebra(QQ, 3);
-
-julia> V1 = exterior_power(standard_module(L), 2)[1]; # some module
-
-julia> V2 = symmetric_power(standard_module(L), 3)[1]; # some module
-
-julia> direct_sum(V1, V2)
-Direct sum module
-  of dimension 13
-  direct sum with direct summands
-    2nd exterior power of
-      standard module
-    3rd symmetric power of
-      standard module
-over special linear Lie algebra of degree 3 over QQ
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source

Examples

julia> F = free_module(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.

source

Examples

julia> F = free_module(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 = free_module(QQ, 1);
-
-julia> M = free_module(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 = free_module(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/PR4245/AbstractAlgebra/euclidean_interface/index.html b/previews/PR4245/AbstractAlgebra/euclidean_interface/index.html deleted file mode 100644 index 237f33fcbb01..000000000000 --- a/previews/PR4245/AbstractAlgebra/euclidean_interface/index.html +++ /dev/null @@ -1,3 +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.

source
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.
source
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.

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

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

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

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

source
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.

source
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).

source
is_divisible_byMethod
is_divisible_by(x::T, y::T) where T <: RingElem

Check if x is divisible by y, i.e. if $x = zy$ for some $z$.

source
is_associatedMethod
is_associated(x::T, y::T) where T <: RingElem

Check if x and y are associated, i.e. if x is a unit times y.

source
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.

source
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.

source
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.

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

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

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

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

source
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$.

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

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

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

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

source
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$.

source
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}$.

source
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).

source
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$.

source
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.

source
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$.

source
coprime_baseFunction
coprime_base(S::Vector{RingElement}) -> Vector{RingElement}

Returns a coprime base for $S$, i.e. the resulting array contains pairwise coprime objects that multiplicatively generate the same set as the input array.

source
coprime_base(A::Vector{AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}}) -> Vector{AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}}
-coprime_base(A::Vector{AbsSimpleNumFieldOrderElem}) -> Vector{AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}}

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.

source
coprime_base_push!Function
coprime_base_push!(S::Vector{RingElem}, a::RingElem) -> Vector{RingElem}

Given an array $S$ of coprime elements, insert a new element, that is, find a coprime base for push(S, a).

source
diff --git a/previews/PR4245/AbstractAlgebra/extending_abstractalgebra/index.html b/previews/PR4245/AbstractAlgebra/extending_abstractalgebra/index.html deleted file mode 100644 index 7e29c4424043..000000000000 --- a/previews/PR4245/AbstractAlgebra/extending_abstractalgebra/index.html +++ /dev/null @@ -1,111 +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
source
elem_typeFunction
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
source
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
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
source

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{}
source
base_ring_typeFunction
base_ring_type(a)

Return the type of the base ring of the given element, element type, parent or parent type $a$.

Examples

julia> R, x = polynomial_ring(ZZ, :x)
-(Univariate polynomial ring in x over integers, x)
-
-julia> base_ring_type(R) == typeof(base_ring(R))
-true
-
-julia> base_ring_type(zero(R)) == typeof(base_ring(zero(R)))
-true
-
-julia> base_ring_type(typeof(R)) == typeof(base_ring(R))
-true
-
-julia> base_ring_type(typeof(zero(R))) == typeof(base_ring(zero(R)))
-true
source

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 = puiseux_series_field(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
source
zeroFunction
zero(a)

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

Examples

julia> S = matrix_ring(QQ, 2)
-Matrix ring 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
source

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 = puiseux_series_field(QQ, 10, :x)
-(Puiseux series field in x over rationals, x + O(x^11))
-
-julia> isone(x), isone(T(1))
-(false, true)
source
iszeroFunction
iszero(a)

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

Examples

julia> T, x = puiseux_series_field(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
source
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)
source

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

diff --git a/previews/PR4245/AbstractAlgebra/field/index.html b/previews/PR4245/AbstractAlgebra/field/index.html deleted file mode 100644 index bbb7f8abd595..000000000000 --- a/previews/PR4245/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/PR4245/AbstractAlgebra/field_interface/index.html b/previews/PR4245/AbstractAlgebra/field_interface/index.html deleted file mode 100644 index b378c329ecc9..000000000000 --- a/previews/PR4245/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.FracFieldElem{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/PR4245/AbstractAlgebra/field_introduction/index.html b/previews/PR4245/AbstractAlgebra/field_introduction/index.html deleted file mode 100644 index d5aa302796e3..000000000000 --- a/previews/PR4245/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/PR4245/AbstractAlgebra/finfield/index.html b/previews/PR4245/AbstractAlgebra/finfield/index.html deleted file mode 100644 index 3c695eaae50e..000000000000 --- a/previews/PR4245/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.

source

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.

source
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.

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

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

source
orderMethod
order(R::GFField)

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

source
degreeMethod
degree(R::GFField)

Return the degree of the given finite field.

source

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/PR4245/AbstractAlgebra/fraction/index.html b/previews/PR4245/AbstractAlgebra/fraction/index.html deleted file mode 100644 index b0f2a3ef0500..000000000000 --- a/previews/PR4245/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.FracFieldElem{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.FactoredFracFieldElem{T} with parent objects of such fractions having type Generic.FactoredFracField{T}. As opposed to the fractions of type Generic.FracFieldElem{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.

source

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.

source
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.

source

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$.

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

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

source

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.FactoredFracFieldElem{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/PR4245/AbstractAlgebra/fraction_interface/index.html b/previews/PR4245/AbstractAlgebra/fraction_interface/index.html deleted file mode 100644 index f77ce8d6bff0..000000000000 --- a/previews/PR4245/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/PR4245/AbstractAlgebra/free_associative_algebra/index.html b/previews/PR4245/AbstractAlgebra/free_associative_algebra/index.html deleted file mode 100644 index 0c3c6e3e3c72..000000000000 --- a/previews/PR4245/AbstractAlgebra/free_associative_algebra/index.html +++ /dev/null @@ -1,132 +0,0 @@ - -Free algebras · Oscar.jl

Free algebras

AbstractAlgebra.jl provides a module, implemented in src/FreeAssociativeAlgebra.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.FreeAssociativeAlgebraElem{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.FreeAssociativeAlgebra{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::FreeAssociativeAlgebra)
-base_ring(a::FreeAssociativeAlgebraElem)
-parent(a::FreeAssociativeAlgebraElem)
-characteristic(R::FreeAssociativeAlgebra)

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.FreeAssociativeAlgebraElem{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.FreeAssociativeAlgebraElem{BigInt}[x, y, z])
-
-julia> B = MPolyBuildCtx(R)
-Builder for an element of free associative algebra
-
-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.FreeAssociativeAlgebraElem{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::FreeAssociativeAlgebra)
-number_of_variables(f::FreeAssociativeAlgebra)
-gens(S::FreeAssociativeAlgebra)
-gen(S::FreeAssociativeAlgebra, i::Int)
-is_gen(x::FreeAssociativeAlgebraElem)
-total_degree(a::FreeAssociativeAlgebraElem)
-length(f::FreeAssociativeAlgebraElem)

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::FreeAssociativeAlgebraElem)
-leading_monomial(a::FreeAssociativeAlgebraElem)
-leading_term(a::FreeAssociativeAlgebraElem)
-leading_exponent_word(a::FreeAssociativeAlgebraElem)

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::FreeAssociativeAlgebraElem, n::Int)
-monomial(f::FreeAssociativeAlgebraElem, n::Int)
-term(f::FreeAssociativeAlgebraElem, n::Int)

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

exponent_wordMethod
exponent_word(a::FreeAssociativeAlgebraElem{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.

source

Examples

julia> R, (x, y, z) = free_associative_algebra(ZZ, [:x, :y, :z])
-(Free associative algebra on 3 indeterminates over integers, AbstractAlgebra.Generic.FreeAssociativeAlgebraElem{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
evaluateMethod
evaluate(a::FreeAssociativeAlgebraElem{T}, vals::Vector{U}) where {T <: RingElement, U <: NCRingElem}

Evaluate a 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 vals.

The syntax a(vals...) is also supported.

Examples

julia> R, (x, y) = free_associative_algebra(ZZ, ["x", "y"]);
-
-julia> f = x*y - y*x
-x*y - y*x
-
-julia> S = matrix_ring(ZZ, 2);
-
-julia> m1 = S([1 2; 3 4])
-[1   2]
-[3   4]
-
-julia> m2 = S([0 1; 1 0])
-[0   1]
-[1   0]
-
-julia> evaluate(f, [m1, m2])
-[-1   -3]
-[ 3    1]
-
-julia> m1*m2 - m2*m1 == evaluate(f, [m1, m2])
-true
-
-julia> m1*m2 - m2*m1 == f(m1, m2)
-true
source

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::FreeAssociativeAlgebraElem)
-coefficients(p::FreeAssociativeAlgebraElem)
-monomials(p::FreeAssociativeAlgebraElem)
exponent_wordsMethod
exponent_words(a::FreeAssociativeAlgebraElem{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)).

source

Examples

julia> R, (a, b, c) = free_associative_algebra(ZZ, [:a, :b, :c])
-(Free associative algebra on 3 indeterminates over integers, AbstractAlgebra.Generic.FreeAssociativeAlgebraElem{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]
- []

Groebner bases

The function groebner_basis provides the computation of a Groebner basis of an ideal, given a set of generators of that ideal. Since such a Groebner basis is not necessarily finite, one can additionally pass a reduction_bound to the function, to only compute a partial Groebner basis.

groebner_basisMethod
groebner_basis(g::Vector{FreeAssociativeAlgebraElem{T}}, reduction_bound::Int = typemax(Int), remove_redundancies::Bool = false)

Compute a Groebner basis for the ideal generated by g. Stop when reduction_bound many non-zero entries have been added to the Groebner basis. If the computation stops due to the bound being exceeded, the result is in general not an actual Groebner basis, just a subset of one. However, whenever the normal form with respect to this incomplete Groebner basis is 0, it will also be 0 with respect to the full Groebner basis.

If remove_redundancies is set to true, some redundant obstructions will be removed during the computation, which might save time, however in practice it seems to inflate the running time regularly.

source
normal_formMethod
normal_form(f::FreeAssociativeAlgebraElem{T}, g::Vector{FreeAssociativeAlgebraElem{T}}, aut::AhoCorasickAutomaton)

Assuming g is a Groebner basis and aut an Aho-Corasick automaton for the elements of g, compute the normal form of f with respect to g

source
interreduce!Method
interreduce!(g::Vector{FreeAssociativeAlgebraElem{T}}) where T

Interreduce a given Groebner basis with itself, i.e. compute the normal form of each element of g with respect to the rest of the elements and discard elements with normal form $0$ and duplicates.

source

The implementation uses a non-commutative version of the Buchberger algorithm as described in

Xingqiang Xiu, Non-commutative Gröbner Bases and Applications, PhD thesis, 2012.

Examples

julia> R = @free_associative_algebra(GF(2), [:x, :y, :u, :v, :t, :s])
-Free associative algebra on 6 indeterminates x, y, u, v, ..., s
-  over finite field F_2
-
-julia> g = Generic.groebner_basis([u*(x*y)^3 + u*(x*y)^2 + u + v, (y*x)^3*t + (y*x)^2*t + t + s])
-5-element Vector{AbstractAlgebra.Generic.FreeAssociativeAlgebraElem{AbstractAlgebra.GFElem{Int64}}}:
- u*x*y*x*y*x*y + u*x*y*x*y + u + v
- y*x*y*x*y*x*t + y*x*y*x*t + t + s
- u*x*s + v*x*t
- u*x*y*x*s + v*x*y*x*t
- u*x*y*x*y*x*s + v*x*y*x*y*x*t

In order to check whether a given element of the algebra is in the ideal generated by a Groebner basis g, one can compute its normal form.

julia> R = @free_associative_algebra(GF(2), [:x, :y, :u, :v, :t, :s]);
-
-julia> g = Generic.groebner_basis([u*(x*y)^3 + u*(x*y)^2 + u + v, (y*x)^3*t + (y*x)^2*t + t + s]);
-
-julia> normal_form(u*(x*y)^3*s*t + u*(x*y)^2*s*t +u*s*t + v*s*t, g)
-0
diff --git a/previews/PR4245/AbstractAlgebra/free_module/index.html b/previews/PR4245/AbstractAlgebra/free_module/index.html deleted file mode 100644 index 6a6e1641cb23..000000000000 --- a/previews/PR4245/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

free_moduleMethod
free_module(R::NCRing, rank::Int; cached::Bool = true)

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

source
vector_spaceMethod
vector_space(R::Field, dim::Int; cached::Bool = true)

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

source

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

Examples

julia> M = free_module(ZZ, 3)
-Free module of rank 3 over integers
-
-julia> V = vector_space(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 = free_module(ZZ, 3)
-Free module of rank 3 over integers
-
-julia> V = vector_space(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/PR4245/AbstractAlgebra/function_field/index.html b/previews/PR4245/AbstractAlgebra/function_field/index.html deleted file mode 100644 index cce5c4ff299a..000000000000 --- a/previews/PR4245/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.

rational_function_field(k::Field, s::VarName; cached::Bool = true)
-rational_function_field(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 = rational_function_field(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) = rational_function_field(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 = rational_function_field(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.

source

Examples

julia> R, x = rational_function_field(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.

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

Return true if $a$ is a square.

source
sqrtMethod
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.

source
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.

source
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.

source

Examples

julia> R, x = rational_function_field(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:

function_field(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 = rational_function_field(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 = function_field(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 = rational_function_field(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 = function_field(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 = rational_function_field(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 = function_field(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.

source
varMethod
var(R::FunctionField)

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

source
characteristicMethod
characteristic(R::FunctionField)

Return the characteristic of the underlying rational function field.

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

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

source
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.

source
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.

source
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.

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

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

source
is_genMethod
is_gen(a::FunctionFieldElem)

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

source
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.

source
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.

source

Examples

julia> R, x = rational_function_field(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 = function_field(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.

source
julia> R, x = rational_function_field(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 = function_field(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/PR4245/AbstractAlgebra/functional_map/index.html b/previews/PR4245/AbstractAlgebra/functional_map/index.html deleted file mode 100644 index 9e70fb43a1fb..000000000000 --- a/previews/PR4245/AbstractAlgebra/functional_map/index.html +++ /dev/null @@ -1,11 +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_funcMethod
map_from_func(image_fn::Function, domain, codomain)

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 defined by a Julia function
-  from integers
-  to integers
-
-julia> f(ZZ(2))
-3
source
diff --git a/previews/PR4245/AbstractAlgebra/ideal/index.html b/previews/PR4245/AbstractAlgebra/ideal/index.html deleted file mode 100644 index 0b3cb08ce5cf..000000000000 --- a/previews/PR4245/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]; internal_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.

source

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.

source
intersectMethod
intersect(I::Ideal{T}, J::Ideal{T}) where T <: RingElement

Return the intersection of the ideals I and J.

source

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> intersect(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.

source

Examples

julia> R, (x, y) = polynomial_ring(ZZ, [:x, :y]; internal_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/PR4245/AbstractAlgebra/img/types.dia b/previews/PR4245/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/PR4245/AbstractAlgebra/img/types.png b/previews/PR4245/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/PR4245/AbstractAlgebra/index.html b/previews/PR4245/AbstractAlgebra/index.html deleted file mode 100644 index ae7028cfa34f..000000000000 --- a/previews/PR4245/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/PR4245/AbstractAlgebra/integer/index.html b/previews/PR4245/AbstractAlgebra/integer/index.html deleted file mode 100644 index 39ac579656ee..000000000000 --- a/previews/PR4245/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$.

source
is_associatedMethod
is_associated(a::Integer, b::Integer)

Return true if $a$ and $b$ are associated, i.e. if there exists a unit $c$ such that $a = bc$. For integers, this reduces to checking if $a$ and $b$ differ by a factor of $1$ or $-1$.

source

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.

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

Return true if $f$ is a perfect square.

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

Return true if $a$ is a square.

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

Return true if $a$ is a square.

source
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).

source
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$.

source
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.

source
is_powerMethod
is_power(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$.

source
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.

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

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

source

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)

Return a pair $(c,d)$ such that $a=c*d$ and $c = gcd(a, b^\infty)$ if $a\neq 0$, and $c=b$, $d=0$ if $a=0$.

source

Examples

julia> c, n = ppio(ZZ(12), ZZ(26))
-(4, 3)
-
diff --git a/previews/PR4245/AbstractAlgebra/interface_introduction/index.html b/previews/PR4245/AbstractAlgebra/interface_introduction/index.html deleted file mode 100644 index 96f6a083eff1..000000000000 --- a/previews/PR4245/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/PR4245/AbstractAlgebra/laurent_mpolynomial/index.html b/previews/PR4245/AbstractAlgebra/laurent_mpolynomial/index.html deleted file mode 100644 index f516ce260c19..000000000000 --- a/previews/PR4245/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.

laurent_polynomial_ring(R::Ring, S::Vector{<:VarName}; cached::Bool = true)
-laurent_polynomial_ring(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)
-number_of_variables(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::AbstractUnitRange{Int}, exp_range::AbstractUnitRange{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) = laurent_polynomial_ring(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/PR4245/AbstractAlgebra/laurent_polynomial/index.html b/previews/PR4245/AbstractAlgebra/laurent_polynomial/index.html deleted file mode 100644 index 38350a002c80..000000000000 --- a/previews/PR4245/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, ...} <: LaurentPolyRing{T}.

Abstract types

Two abstract types LaurentPolyRingElem{T} and LaurentPolyRing{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:

laurent_polynomial_ringFunction
laurent_polynomial_ring(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 = laurent_polynomial_ring(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
source
laurent_polynomial_ring(R::Ring, varnames...; cached::Bool = true)

Given a base ring R and variable names varnames..., say :x, :y, :z, return a tuple S, x, y, z representing the new ring $S = R[x, 1/x, y, 1/y, z, 1/z]$ and the generators $x, y, z$ of the ring.

By default (cached=true), the output S will be cached, i.e. if laurent_polynomial_ring is invoked again with the same arguments, the same (identical) ring is returned. Setting cached to false ensures a distinct new ring is returned, and will also prevent it from being cached.

For information about the many ways to specify varnames... refer to polynomial_ring or the specification in AbstractAlgebra.@varnames_interface.

source

Basic functionality

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

julia> R, x = laurent_polynomial_ring(ZZ, :x)
-(Univariate Laurent polynomial ring in x over integers, x)
-
-julia> var(R)
-:x
-
-julia> symbols(R)
-1-element Vector{Symbol}:
- :x
-
-julia> number_of_variables(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/PR4245/AbstractAlgebra/linear_solving/index.html b/previews/PR4245/AbstractAlgebra/linear_solving/index.html deleted file mode 100644 index 2db6136e7198..000000000000 --- a/previews/PR4245/AbstractAlgebra/linear_solving/index.html +++ /dev/null @@ -1,237 +0,0 @@ - -Linear solving · Oscar.jl

Linear solving

Overview of the functionality

The module AbstractAlgebra.Solve provides the following four functions for solving linear systems:

  • solve
  • can_solve
  • can_solve_with_solution
  • can_solve_with_solution_and_kernel

All of these take the same set of arguments, namely:

  • a matrix $A$ of type MatElem;
  • a vector or matrix $B$ of type Vector or MatElem;
  • a keyword argument side which can be either :left (default) or :right.

If side is :left, the system $xA = B$ is solved, otherwise the system $Ax = B$ is solved.

The functionality of the functions can be summarized as follows.

  • solve: return a solution, if it exists, otherwise throw an error.
  • can_solve: return true, if a solution exists, false otherwise.
  • can_solve_with_solution: return true and a solution, if this exists, and false and an empty vector or matrix otherwise.
  • can_solve_with_solution_and_kernel: like can_solve_with_solution and additionally return a matrix whose rows (respectively columns) give a basis of the kernel of $A$.

Solving with several right hand sides

Systems $xA = b_1,\dots, xA = b_k$ with the same matrix $A$, but several right hand sides $b_i$ can be solved more efficiently, by first initializing a "context object" C.

solve_initFunction
solve_init(A::MatElem)

Return a context object C that allows to efficiently solve linear systems $Ax = b$ or $xA = b$ for different $b$.

Example

julia> A = QQ[1 2 3; 0 3 0; 5 0 0];
-
-julia> C = solve_init(A)
-Linear solving context of matrix
-  [1//1   2//1   3//1]
-  [0//1   3//1   0//1]
-  [5//1   0//1   0//1]
-
-julia> solve(C, [QQ(1), QQ(1), QQ(1)], side = :left)
-3-element Vector{Rational{BigInt}}:
- 1//3
- 1//9
- 2//15
-
-julia> solve(C, [QQ(1), QQ(1), QQ(1)], side = :right)
-3-element Vector{Rational{BigInt}}:
- 1//5
- 1//3
- 2//45
source

Now the functions solve, can_solve, etc. can be used with C in place of $A$. This way the time-consuming part of the solving (i.e. computing a reduced form of $A$) is only done once and the result cached in C to be reused.

Detailed documentation

solveFunction
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_verbosity_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.RelSimpleNumFieldElem{Hecke.RelSimpleNumFieldElem{AbsSimpleNumFieldElem}}}:
- 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])
-
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
solve(A::MatElem{T}, b::Vector{T}; side::Symbol = :left) where T
-solve(A::MatElem{T}, b::MatElem{T}; side::Symbol = :left) where T
-solve(C::SolveCtx{T}, b::Vector{T}; side::Symbol = :left) where T
-solve(C::SolveCtx{T}, b::MatElem{T}; side::Symbol = :left) where T

Return $x$ of same type as $b$ solving the linear system $xA = b$, if side == :left (default), or $Ax = b$, if side == :right.

If no solution exists, an error is raised.

If a context object C is supplied, then the above applies for A = matrix(C).

See also can_solve_with_solution.

source
can_solveFunction
 can_solve(f::QuadBin, n::IntegerUnion) -> Bool

For a binary quadratic form f with negative discriminant and an integer n, return whether f represents n.

source
can_solve(A::MatElem{T}, b::Vector{T}; side::Symbol = :left) where T
-can_solve(A::MatElem{T}, b::MatElem{T}; side::Symbol = :left) where T
-can_solve(C::SolveCtx{T}, b::Vector{T}; side::Symbol = :left) where T
-can_solve(C::SolveCtx{T}, b::MatElem{T}; side::Symbol = :left) where T

Return true if the linear system $xA = b$ or $Ax = b$ with side == :left (default) or side == :right, respectively, has a solution and false otherwise.

If a context object C is supplied, then the above applies for A = matrix(C).

See also can_solve_with_solution.

source
can_solve_with_solutionFunction
 can_solve_with_solution(f::QuadBin, n::IntegerUnion)
-                                       -> Bool, Tuple{ZZRingElem, ZZRingElem}

For a binary quadratic form f with negative discriminant and an integer n, return the tuple (true, (x, y)) if $f(x, y) = n$ for integers x, y. If no such integers exist, return (false, (0, 0))

source
can_solve_with_solution(A::MatElem{T}, b::Vector{T}; side::Symbol = :left) where T
-can_solve_with_solution(A::MatElem{T}, b::MatElem{T}; side::Symbol = :left) where T
-can_solve_with_solution(C::SolveCtx{T}, b::Vector{T}; side::Symbol = :left) where T
-can_solve_with_solution(C::SolveCtx{T}, b::MatElem{T}; side::Symbol = :left) where T

Return true and $x$ of same type as $b$ solving the linear system $xA = b$, if such a solution exists. Return false and an empty vector or matrix, if the system has no solution.

If side == :right, the system $Ax = b$ is solved.

If a context object C is supplied, then the above applies for A = matrix(C).

See also solve.

source
can_solve_with_solution_and_kernelFunction
can_solve_with_solution_and_kernel(A::MatElem{T}, b::Vector{T}; side::Symbol = :left) where T
-can_solve_with_solution_and_kernel(A::MatElem{T}, b::MatElem{T}; side::Symbol = :left) where T
-can_solve_with_solution_and_kernel(C::SolveCtx{T}, b::Vector{T}; side::Symbol = :left) where T
-can_solve_with_solution_and_kernel(C::SolveCtx{T}, b::MatElem{T}; side::Symbol = :left) where T

Return true, $x$ of same type as $b$ solving the linear system $xA = b$, together with a matrix $K$ giving the kernel of $A$ (i.e. $KA = 0$), if such a solution exists. Return false, an empty vector or matrix and an empty matrix, if the system has no solution.

If side == :right, the system $Ax = b$ is solved.

If a context object C is supplied, then the above applies for A = matrix(C).

See also solve and kernel.

source
kernelFunction
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$.

source
kernel(M::SMat{T}; side::Symbol = :left) where {T <: FieldElement}

Return a matrix $N$ containing a basis of the kernel of $M$. If side is :left (default), the left kernel is computed, i.e. the matrix of rows whose span gives the left kernel space. If side is :right, the right kernel is computed, i.e. the matrix of columns whose span is the right kernel space.

source
kernel(h::FinGenAbGroupHom) -> FinGenAbGroup, Map

Let $G$ be the domain of $h$. This function returns an abelian group $A$ and an injective morphism $f \colon A \to G$, such that the image of $f$ is the kernel of $h$.

source
kernel(f::TorQuadModuleMap) -> TorQuadModule, TorQuadModuleMap

Given an abelian group homomorphism f between two torsion quadratic modules T and U, return the kernel S of f as well as the injection $S \to T$.

source
kernel(f::AbstractAlgebra.Map(SAlgHom))

Return the kernel of the algebra homomorphism $f$.

source
kernel(f::AbstractAlgebra.Map(SIdAlgHom))

Return the kernel of the identity algebra homomorphism.

source
kernel(A::MatElem; side::Symbol = :left)
-kernel(C::SolveCtx; side::Symbol = :left)

Return a matrix $K$ whose rows generate the left kernel of $A$, that is, $KA$ is the zero matrix.

If side == :right, the columns of $K$ generate the right kernel of $A$, that is, $AK$ is the zero matrix.

If the base ring is a principal ideal domain, the rows or columns respectively of $K$ are a basis of the respective kernel.

If a context object C is supplied, then the above applies for A = matrix(C).

source
kernel(F::AffAlgHom)

Return the kernel of F.

source
kernel(f::GAPGroupHomomorphism)

Return the kernel of f, together with its embedding into domain(f).

source
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
kernel(a::FreeModuleHom)

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])
-(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])
-
-julia> F = free_module(R, 3)
-Free module of rank 3 over R
-
-julia> G = free_module(R, 2)
-Free module of rank 2 over R
-
-julia> V = [y*G[1], x*G[1]+y*G[2], z*G[2]];
-
-julia> a = hom(F, G, V);
-
-julia> kernel(a)
-(Submodule with 1 generator
-1 -> x*z*e[1] - y*z*e[2] + y^2*e[3]
-represented as subquotient with no relations., 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 R)
julia> Rg, (x, y, z) = graded_polynomial_ring(QQ, [:x, :y, :z]);
-
-julia> F = graded_free_module(Rg, 3);
-
-julia> G = graded_free_module(Rg, 2);
-
-julia> V = [y*G[1], x*G[1]+y*G[2], z*G[2]];
-
-julia> a = hom(F, G, V);
-
-julia> kernel(a)
-(Graded submodule of F
-1 -> x*z*e[1] - y*z*e[2] + y^2*e[3]
-represented as subquotient with no relations, Graded submodule of F
-1 -> x*z*e[1] - y*z*e[2] + y^2*e[3]
-represented as subquotient with no relations -> F
-x*z*e[1] - y*z*e[2] + y^2*e[3] -> x*z*e[1] - y*z*e[2] + y^2*e[3]
-Homogeneous module homomorphism)
-
source
kernel(a::SubQuoHom)

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).

source
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 R
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> Rg, (x, y, z) = graded_polynomial_ring(QQ, [: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*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*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*y*e[1] -> -x*y*e[1]
-Homogeneous module homomorphism)
-
source
kernel(h::LieAlgebraHom) -> LieAlgebraIdeal

Return the kernel of h as an ideal of the domain.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
diff --git a/previews/PR4245/AbstractAlgebra/map_cache/index.html b/previews/PR4245/AbstractAlgebra/map_cache/index.html deleted file mode 100644 index 639208e66304..000000000000 --- a/previews/PR4245/AbstractAlgebra/map_cache/index.html +++ /dev/null @@ -1,30 +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 defined by a Julia function
-  from integers
-  to 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/PR4245/AbstractAlgebra/map_interface/index.html b/previews/PR4245/AbstractAlgebra/map_interface/index.html deleted file mode 100644 index 7492162da7c3..000000000000 --- a/previews/PR4245/AbstractAlgebra/map_interface/index.html +++ /dev/null @@ -1,26 +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_mapMethod
identity_map(R::D) where D <: AbstractAlgebra.Set

Return an identity map on the domain $R$.

Examples

julia> R, t = ZZ[:t]
-(Univariate polynomial ring in t over integers, t)
-
-julia> f = identity_map(R)
-Identity map
-  of univariate polynomial ring in t over integers
-
-julia> f(t)
-t
source

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:

composeMethod
compose(f::Map, g::Map)

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

Examples

julia> f = map_from_func(x -> x + 1, ZZ, ZZ);
-
-julia> g = map_from_func(x -> QQ(x), ZZ, QQ);
-
-julia> h = compose(f, g)
-Functional composite map
-  from integers
-  to rationals
-which is the composite of
-  Map: integers -> integers
-  Map: integers -> rationals
source

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/PR4245/AbstractAlgebra/map_introduction/index.html b/previews/PR4245/AbstractAlgebra/map_introduction/index.html deleted file mode 100644 index d292d3f59f18..000000000000 --- a/previews/PR4245/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/PR4245/AbstractAlgebra/map_with_inverse/index.html b/previews/PR4245/AbstractAlgebra/map_with_inverse/index.html deleted file mode 100644 index d7591cce0e6e..000000000000 --- a/previews/PR4245/AbstractAlgebra/map_with_inverse/index.html +++ /dev/null @@ -1,34 +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
-  from integers
-  to 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
-  from integers
-  to integers
-
-julia> g = inv(f)
-Map with section
-  from integers
-  to integers
-
-julia> h = f*g
-Composite map
-  from integers
-  to integers
-which is the composite of
-  Map: integers -> integers
-  Map: integers -> integers
-
-julia> a = h(ZZ(1))
-1
-
diff --git a/previews/PR4245/AbstractAlgebra/mathjaxhelper.js b/previews/PR4245/AbstractAlgebra/mathjaxhelper.js deleted file mode 100644 index 1bd5394af59d..000000000000 --- a/previews/PR4245/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/PR4245/AbstractAlgebra/matrix/index.html b/previews/PR4245/AbstractAlgebra/matrix/index.html deleted file mode 100644 index 25ac44b8518c..000000000000 --- a/previews/PR4245/AbstractAlgebra/matrix/index.html +++ /dev/null @@ -1,831 +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/MatRing.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 rings of $m\times m$ matrices are implemented in src/generic/MatRing.jl.

Generic matrices in AbstractAlgebra.jl have type Generic.MatSpaceElem{T} for matrices in a matrix space, or Generic.MatRingElem{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 MatSpace{T}. Parents of matrices in a matrix algebra have type Generic.MatRing{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 all matrix space parents are of the concrete type MatSpace{T}. On the other hand, the generic matrix algebra matrix types belong to the abstract type MatRingElem{T} and the parent types belong to the abstract MatRing{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::MatRing{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 = matrix_ring(QQ, 2)
-Matrix ring 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 = matrix_ring(ZZ, 2)
-Matrix ring 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.

source
block_diagonal_matrix(xs::Vector{SMat})

Return the block diagonal matrix with the matrices in xs on the diagonal. Requires all blocks to have the same base ring.

source
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.

source

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, iteration and broacasting

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<:NCRingElement}
-Matrix{U}(A::MatrixElem{T}) where {U<:NCRingElement, T<:NCRingElement}

Convert A to a Julia Matrix{U} of the same dimensions with the same elements. If U is omitted then eltype(M) is used in its place.

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
-
-julia> Matrix{Int}(A)
-2×3 Matrix{Int64}:
- 1  2  3
- 4  5  6
source
ArrayMethod
Array(A::MatrixElem{T}) where T <: NCRingElement

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
source

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

Matrices also support broadcasting, which amounts to elementwise application of functions to matrices:

julia> k = GF(5);
-
-julia> A = ZZ[1 2; 3 4];
-
-julia> k.(A)
-[1   2]
-[3   4]
-
-julia> 3 .* A .+ 2
-[ 5    8]
-[11   14]
-
-julia> B = ZZ[3 4; 5 6];
-
-julia> ((x, y) -> x^2 + y^2).(A, B)
-[10   20]
-[34   52]

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).

source
number_of_rowsMethod
number_of_rows(a::MatSpace)

Return the number of rows of the given matrix space.

source
number_of_columnsMethod
number_of_columns(a::MatSpace)

Return the number of columns of the given matrix space.

source
number_of_rowsMethod
number_of_rows(a::MatrixElem{T}) where T <: NCRingElement

Return the number of rows of the given matrix.

source
number_of_columnsMethod
number_of_columns(a::MatrixElem{T}) where T <: NCRingElement

Return the number of columns of the given matrix.

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

Return the number of entries in the given matrix.

source
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.

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

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

source
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).

source
ones_matrixMethod
ones_matrix(R::Ring, r::Int, c::Int)

Return the $r \times c$ ones matrix over $R$.

source
scalar_matrixMethod
scalar_matrix(R::NCRing, n::Int, a::NCRingElement)
-scalar_matrix(n::Int, a::NCRingElement)

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

source
diagonal_matrixMethod
diagonal_matrix(x::NCRingElement, 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]
source
zeroMethod
zero(a::MatSpace)

Return the zero matrix in the given matrix space.

source
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.

source
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.

source
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.

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

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]
source
upper_triangular_matrixMethod
upper_triangular_matrix(L::AbstractVector{T}) where {T <: NCRingElement}

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]
source
strictly_lower_triangular_matrixMethod
strictly_lower_triangular_matrix(L::AbstractVector{T}) where {T <: NCRingElement}

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]
source
strictly_upper_triangular_matrixMethod
strictly_upper_triangular_matrix(L::AbstractVector{T}) where {T <: NCRingElement}

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]
source
is_lower_triangularMethod
is_lower_triangular(A::MatrixElem)

Return true if $A$ is an lower triangular matrix, that is, all entries above the main diagonal are zero. Note that this definition also applies to non-square matrices.

Alias for LinearAlgebra.istril.

Examples

julia> is_lower_triangular(QQ[1 2 ; 0 4])
-false
-
-julia> is_lower_triangular(QQ[1 0 ; 3 4])
-true
-
-julia> is_lower_triangular(QQ[1 2 ;])
-false
-
-julia> is_lower_triangular(QQ[1 ; 2])
-true
source
is_upper_triangularMethod
is_upper_triangular(A::MatrixElem)

Return true if $A$ is an upper triangular matrix, that is, all entries below the main diagonal are zero. Note that this definition also applies to non-square matrices.

Alias for LinearAlgebra.istriu.

Examples

julia> is_upper_triangular(QQ[1 2 ; 0 4])
-true
-
-julia> is_upper_triangular(QQ[1 0 ; 3 4])
-false
-
-julia> is_upper_triangular(QQ[1 2 ;])
-true
-
-julia> is_upper_triangular(QQ[1 ; 2])
-false
source
is_diagonalMethod
is_diagonal(A::MatrixElem)

Return true if $A$ is a diagonal matrix, that is, all entries off the main diagonal are zero. Note that this definition also applies to non-square matrices.

Alias for LinearAlgebra.isdiag.

Examples

julia> is_diagonal(QQ[1 0 ; 0 4])
-true
-
-julia> is_diagonal(QQ[1 2 ; 3 4])
-false
-
-julia> is_diagonal(QQ[1 0 ;])
-true
source
change_base_ringMethod
change_base_ring(R::NCRing, M::MatrixElem{T}) where T <: NCRingElement

Return the matrix obtained by coercing each entry into R.

source
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).

source
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).

source

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 = number_of_rows(B)
-3
-
-julia> c = number_of_columns(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 <: NCRingElement

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]
-
source
transpose(A::SMat) -> SMat

Returns the transpose of $A$.

source

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.

source
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.

source
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.

source
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.

source
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.

source
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.

source
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.

source
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.

source

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 <: NCRingElement

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]
source
swap_rows!Method
swap_rows!(a::MatrixElem{T}, i::Int, j::Int) where T <: NCRingElement

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]
source
swap_colsMethod
swap_cols(a::MatrixElem{T}, i::Int, j::Int) where T <: NCRingElement

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

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

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).

source

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(M::MatrixElem)

Return true if the given matrix is symmetric with respect to its main diagonal, i.e., transpose(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
source
is_skew_symmetricMethod
is_skew_symmetric(M::MatrixElem)

Return true if the given matrix is skew symmetric with respect to its main diagonal, i.e., transpose(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
-
source

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]
-
source

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]
-
source

Trace

trMethod
tr(x::MatrixElem{T}) where T <: NCRingElement

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
-
source
tr(x::AbstractAssociativeAlgebraElem{T}) where T -> T

Returns the trace of $x$.

source

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
-
source

Permutation

*Method
*(P::Perm, x::MatrixElem{T}) where T <: NCRingElement

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]
-
source

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$.

source
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.

source

Examples

julia> R, x = polynomial_ring(QQ, :x)
-(Univariate polynomial ring in x over rationals, x)
-
-julia> K, = residue_field(R, x^3 + 3x + 1); a = K(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.

source
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$.

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

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

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

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

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

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

source

Examples

julia> R, x = polynomial_ring(QQ, :x)
-(Univariate polynomial ring in x over rationals, x)
-
-julia> K, = residue_field(R, x^3 + 3x + 1); a = K(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> A = R[x 1; 1 x^2];
-
-julia> d = det(A)
-x^3 - 1
source

Rank

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

Return the rank of the matrix $M$.

Examples

julia> A = QQ[1 2; 3 4];
-
-julia> d = rank(A)
-2
source

Nilpotency

is_nilpotentMethod
is_nilpotent(A::MatrixElem{T}) where {T <: RingElement}

Return if A is nilpotent, i.e. if there exists a natural number $k$ such that $A^k = 0$. If A is not square an exception is raised.

source

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
-
source

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]
source

Pfaffian

pfaffianMethod
pfaffian(M::MatElem)

Return the Pfaffian of a skew-symmetric matrix M.

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

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

source

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

See Linear Solving & Kernel

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.

source
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 a right inverse of $A$ i.e. $A B$ is the $n \times n$ unit matrix. If side is :left and flag is true, $B$ is a left inverse of $A$ i.e. $B A$ is the $m \times m$ unit matrix. If flag is false, no right or left inverse exists.

To get the space of all inverses, note that if $B$ and $C$ are both right inverses, then $A (B - C) = 0$, and similar for left inverses. Hence from one inverse one can find all by making suitable use of kernel.

source
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.

source

Examples

julia> R, x = polynomial_ring(QQ, :x)
-(Univariate polynomial ring in x over rationals, x)
-
-julia> K, = residue_field(R, x^3 + 3x + 1); a = K(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])
source
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.

source

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.

source
is_hessenbergMethod
is_hessenberg(A::MatrixElem{T}) where {T <: RingElement}

Return true if $M$ is in Hessenberg form, otherwise returns false.

source

Examples

julia> R, = residue_ring(ZZ, 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(Y::MatrixElem{T}) where {T <: RingElement}
-charpoly(S::PolyRing{T}, Y::MatrixElem{T}) where {T <: RingElement}

Return the characteristic polynomial $p$ of the square matrix $Y$. If a polynomial ring $S$ over the same base ring as $Y$ is supplied, the resulting polynomial is an element of it.

Examples

julia> R, = residue_ring(ZZ, 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, y = polynomial_ring(R, :y)
-(Univariate polynomial ring in y over residue ring, y)
-
-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)
-y^4 + 2*y^2 + 6*y + 2
-
-julia> A = charpoly(M)
-x^4 + 2*x^2 + 6*x + 2
-
source

Minimal polynomial

minpolyMethod
minpoly(M::MatElem{T}, charpoly_only::Bool = false) where {T <: RingElement}
-minpoly(S::PolyRing{T}, M::MatElem{T}, charpoly_only::Bool = false) where {T <: RingElement}

Return the minimal polynomial $p$ of the square matrix $M$. If a polynomial ring $S$ over the same base ring as $Y$ is supplied, the resulting polynomial is an element of it.

Examples

julia> R = GF(13)
-Finite field F_13
-
-julia> S, 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(S, M)
-y^2 + 10*y
-
-julia> A = minpoly(M)
-x^2 + 10*x
-
source

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);
-
-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))
-
source

Hermite normal form

hnfMethod
hnf(A::MatrixElem{T}) where {T <: RingElement}

Return the upper right row Hermite normal form of $A$.

source
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$.

source
is_hnfMethod
is_hnf(M::MatrixElem{T}) where T <: RingElement

Return true if the matrix is in Hermite normal form.

source

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.

source
snfMethod
snf(A::MatrixElem{T}) where {T <: RingElement}

Return the Smith normal form of $A$.

source
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$.

source

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.

source
weak_popovMethod
weak_popov(A::MatElem{T}) where {T <: PolyRingElem}

Return the weak Popov form of $A$.

source
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$.

source
popovMethod
popov(A::MatElem{T}) where {T <: PolyRingElem}

Return the Popov form of $A$.

source
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$.

source

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/PR4245/AbstractAlgebra/matrix_algebras/index.html b/previews/PR4245/AbstractAlgebra/matrix_algebras/index.html deleted file mode 100644 index 451813c7964d..000000000000 --- a/previews/PR4245/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/MatRing.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.MatRingElem{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.MatRing{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 MatRingElem{T} and the parent types belong to MatRing{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.

matrix_ring(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 = matrix_ring(R, 3)
-Matrix ring 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).

source
identity_matrix(M::MatRingElem{T}) where T <: RingElement

Return the identity matrix over the same base ring as $M$ and with the same dimensions.

source

Examples

S = matrix_ring(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::MatRingElem{T}) where T <: RingElement

Return the degree $n$ of the given matrix algebra.

source

Examples

julia> R, t = polynomial_ring(QQ, :t)
-(Univariate polynomial ring in t over rationals, t)
-
-julia> S = matrix_ring(R, 3)
-Matrix ring 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/PR4245/AbstractAlgebra/matrix_interface/index.html b/previews/PR4245/AbstractAlgebra/matrix_interface/index.html deleted file mode 100644 index e5e0158c0ce0..000000000000 --- a/previews/PR4245/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 types for matrix spaces and their elements:

  • MatSpace{T} is the concrete 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:

  • MatRing{T} is the abstract type for matrix algebra parent types
  • MatRingElem{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 either making them struct types, or 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.

number_of_rows(M::MyMatSpace{T}) where T <: RingElem
-number_of_rows(M::MyMatAlgebra{T}) where T <: RingElem

Return the number of rows of matrices in the matrix space.

number_of_columns(M:MyMatSpace{T}) where T <: RingElem
-number_of_columns(M:MyMatAlgebra{T}) where T <: RingElem

Return the number of columns of matrices in the matrix space.

number_of_rows(f::MyMat{T}) where T <: RingElem

Return the number of rows of the given matrix.

number_of_columns(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.MatRingElem 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/PR4245/AbstractAlgebra/matrix_introduction/index.html b/previews/PR4245/AbstractAlgebra/matrix_introduction/index.html deleted file mode 100644 index 2c2651cfea57..000000000000 --- a/previews/PR4245/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/PR4245/AbstractAlgebra/misc/index.html b/previews/PR4245/AbstractAlgebra/misc/index.html deleted file mode 100644 index e9402409469b..000000000000 --- a/previews/PR4245/AbstractAlgebra/misc/index.html +++ /dev/null @@ -1,148 +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.

source
get_html_as_latexFunction
get_html_as_latex()

Returns whether MIME type text/html is printed as text/latex.

source

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
source
@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
-
source
has_attributeFunction
has_attribute(G::Any, attr::Symbol)

Return a boolean indicating whether G has a value stored for the attribute attr.

source
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
source
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.

source
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
source
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.

source
set_attribute!Function
set_attribute!(G::Any, data::Pair{Symbol, <:Any}...)

Attach the given sequence of key=>value pairs as attributes of G.

source
set_attribute!(G::Any, attr::Symbol, value::Any)

Attach the given value as attribute attr of G.

source

Advanced printing

Self-given names

We provide macros @show_name, @show_special and @show_special_elem to change the way certain objects are printed.

In compact and terse printing mode, @show_name tries to determine a suitable name to print instead of the object (see AbstractAlgebra.get_name).

@show_special checks if an attribute :show is present. If so, it has to be a function taking IO, optionally a MIME-type, and the object. This is then called instead of the usual show function.

Similarly, @show_special_elem checks if an attribute :show_elem is present in the object's parent. The semantics are the same as for @show_special.

All are supposed to be used within the usual show function, where @show_special_elem is only relevant for element types of algebraic structures.

@attributes MyObj
-
-function show(io::IO, A::MyObj)
-   @show_name(io, A)
-   @show_special(io, A)
-
-   # ... usual stuff
-end
-
-function show(io::IO, mime::MIME"text/plain", A::MyObj)
-   @show_name(io, A)
-   @show_special(io, mime, A)
-
-   # ... usual stuff
-end
-
-function show(io::IO, A::MyObjElem)
-   @show_name(io, A)
-   @show_special_elem(io, A)
-
-   # ... usual stuff
-end
-
-function show(io::IO, mime::MIME"text/plain", A::MyObjElem)
-   @show_name(io, A)
-   @show_special_elem(io, mime, A)
-
-   # ... usual stuff
-end

Documentation

@show_specialMacro
@show_special(io::IO, obj)

If the obj has a show attribute, this gets called with io and obj and returns from the current scope. Otherwise, does nothing.

obj is required to have attribute storage available.

It is supposed to be used at the start of show methods as shown in the documentation.

source
@show_special(io::IO, mime, obj)

If the obj has a show attribute, this gets called with io, mime and obj (if applicable) and io and obj otherwise, and returns from the current scope. Otherwise, does nothing.

obj is required to have attribute storage available.

It is supposed to be used at the start of show methods as shown in the documentation.

source
@show_special_elemMacro
@show_special_elem(io::IO, obj)

If the parent of obj has a show_elem attribute, this gets called with io and obj and returns from the current scope. Otherwise, does nothing.

parent(obj) is required to have attribute storage available.

It is supposed to be used at the start of show methods as shown in the documentation.

source
@show_special_elem(io::IO, mime, obj)

If the parent of obj has a show_elem attribute, this gets called with io, mime and obj (if applicable) and io and obj otherwise, and returns from the current scope. Otherwise, does nothing.

parent(obj) is required to have attribute storage available.

It is supposed to be used at the start of show methods as shown in the documentation.

source
@show_nameMacro
@show_name(io::IO, obj)

If either is_terse(io) is true or property :compact is set to true for io (see IOContext), print the name get_name(obj) of the object obj to the io stream, then return from the current scope. Otherwise, do nothing.

It is supposed to be used at the start of show methods as shown in the documentation.

source
set_name!Function
set_name!(obj, name::String; override::Bool=true)

Sets the name of the object obj to name. This name is used for printing using AbstractAlgebra.@show_name. If override is false, the name is only set if there is no name already set.

This function errors if obj does not support attribute storage.

source
set_name!(obj; override::Bool=true)

Sets the name of the object obj to the name of a variable in global (Main module) namespace with value bound to the object obj, if such a variable exists (see AbstractAlgebra.PrettyPrinting.find_name). This name is used for printing using AbstractAlgebra.@show_name. If override is false, the name is only set if there is no name already set.

This function errors if obj does not support attribute storage.

source
extra_nameFunction
extra_name(obj) -> Union{String,Nothing}

May be overloaded to provide a fallback name for the object obj in AbstractAlgebra.get_name. The default implementation returns nothing.

source
find_nameFunction
find_name(obj, M = Main; all::Bool = false) -> Union{String,Nothing}

Return name of a variable in M's namespace with value bound to the object obj, or nothing if no such variable exists. If all is true, private and non-exported variables are also searched.

Note

If the object is stored in several variables, the first one will be used, but a name returned once is kept until the variable no longer contains this object.

For this to work in doctests, one should call AbstractAlgebra.set_current_module(@__MODULE__) in the value argument of Documenter.DocMeta.setdocmeta! and keep the default value of M = Main here.

Warning

This function should not be used directly, but rather through AbstractAlgebra.get_name.

source

Indentation and Decapitalization

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);
source
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
source
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
source
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
source
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
source

Linear solving interface for developers

AbstractAlgebra has a generic interface for linear solving and we describe here how one may extend this interface. For the user-facing functionality of linear solving, see Linear Solving.

Notice that the functionality is implemented in the module AbstractAlgebra.Solve and the internal functions are not exported from there.

Matrix normal forms

To distinguish between different algorithms, we use type traits of abstract type MatrixNormalFormTrait which usually correspond to a certain matrix normal form. The available algorithms/normal forms are

  • HowellFormTrait: uses a Howell form;
  • HermiteFormTrait: uses a Hermite normal form;
  • RREFTrait: uses a row-reduced echelon form over fields;
  • LUTrait: uses a LU factoring of the matrix;
  • FFLUTrait: uses a "fraction-free" LU factoring of the matrix over fraction fields;
  • MatrixInterpolateTrait: uses interpolation of polynomials for fraction fields of polynomial rings.

To select a normal form type for rings of type NewRing, implement the function

Solve.matrix_normal_form_type(::NewRing) = Bla()

where Bla <: MatrixNormalFormTrait. A new type trait can be added via

struct NewTrait <: Solve.MatrixNormalFormTrait end

Internal solving functionality

If a new ring type NewRing can make use of one of the available MatrixNormalFormTraits, then it suffices to specify this normal form as described above to use the generic solving functionality. (However, for example HermiteFormTrait requires that the function hermite_form_with_transformation is implemented.)

For a new trait NewTrait <: MatrixNormalFormTrait, one needs to implement the function

Solve._can_solve_internal_no_check(
-  ::NewTrait, A::MatElem{T}, b::MatElem{T}, task::Symbol; side::Symbol = :left
-  ) where T

Inside this function, one can assume that A and b have the same base ring and have compatible dimensions. Further, task and side are set to "legal" options. (All this is checked in Solve._can_solve_internal.) This function should then (try to) solve Ax = b (side == :right) or xA = b (side == :left) possibly with kernel. The function must always return a tuple (::Bool, ::MatElem{T}, ::MatElem{T}) consisting of:

  • true/false whether a solution exists or not
  • the solution (or a placeholder if no solution exists or a solution is not requested)
  • the kernel (or a placeholder if the kernel is not requested)

The input task may be:

  • :only_check: Only test whether there is a solution, the second and third return value are only for type stability;
  • :with_solution: Compute a solution, if it exists, the last return value is only for type stability;
  • :with_kernel: Compute a solution and a kernel.

One should further implement the function

kernel(::NewTrait, A::MatElem; side::Symbol = :left)

which computes a left (or right) kernel of A.

Internal solve context functionality

To efficiently solve several linear systems with the same matrix A, we provide the "solve contexts objects" of type Solve.SolveCtx. These can be extended for a ring of type NewRing as follows.

Solve context type

For a new ring type, one may have to define the type parameters of a SolveCtx object. First of all, one needs to implement the function

function Solve.solve_context_type(::NewRing)
-  return Solve.solve_context_type(::NormalFormTrait, elem_type(NewRing))
-end

to pick a MatrixNormalFormTrait.

Usually, nothing else should be necessary. However, if for example the normal form of a matrix does not live over the same ring as the matrix itself, one might also need to implement

function Solve.solve_context_type(NF::NormalFormTrait, T::Type{NewRingElem})
-  return Solve.SolveCtx{T, typeof(NF), MatType, RedMatType, TranspMatType}
-end

where MatType is the dense matrix type over NewRing, RedMatType the type of a matrix in reduced/normal form and TranspMatType the type of the reduced/normal form of the transposed matrix.

Initialization

To initialize the solve context functionality for a new normal form NewTrait, one needs to implement the functions

Solve._init_reduce(C::SolveCtx{T, NewTrait}) where T
-Solve._init_reduce_transpose(C::SolveCtx{T, NewTrait}) where T

These should fill the corresponding fields of the solve context C with a "reduced matrix" (that is, a matrix in normal form) of matrix(C), respectively transpose(matrix(C)), and other information necessary to solve a linear system. The fields can be accessed via reduced_matrix, reduced_matrix_of_transpose, etc. New fields may also be added via attributes.

Internal solving functionality

As above, one finally needs to implement the functions

Solve._can_solve_internal_no_check(
-  ::NewTrait, C::SolveCtx{T, NewTrait}, b::MatElem{T}, task::Symbol;
-  side::Symbol = :left
-  ) where T

and

kernel(::NewTrait, C::SolveCtx{T, NewTrait}; side::Symbol = :left)
diff --git a/previews/PR4245/AbstractAlgebra/module/index.html b/previews/PR4245/AbstractAlgebra/module/index.html deleted file mode 100644 index e7e8e886ace5..000000000000 --- a/previews/PR4245/AbstractAlgebra/module/index.html +++ /dev/null @@ -1,94 +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.

number_of_generators(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 = free_module(QQ, 2)
-Vector space of dimension 2 over rationals
-
-julia> n = number_of_generators(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 = free_module(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 = free_module(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 = free_module(QQ, 2)
-Vector space of dimension 2 over rationals
-
-julia> z = zero(M)
-(0//1, 0//1)

Element indexing

getindexMethod
getindex(a::Fac, b) -> Int

If $b$ is a factor of $a$, the corresponding exponent is returned. Otherwise an error is thrown.

source
getindex(A::SMat, i::Int, j::Int)

Given a sparse matrix $A = (a_{ij})_{i, j}$, return the entry $a_{ij}$.

source
getindex(A::SMat, i::Int) -> SRow

Given a sparse matrix $A$ and an index $i$, return the $i$-th row of $A$.

source

Examples

julia> F = free_module(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.

source

Examples

julia> M = free_module(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.

source
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 = free_module(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.

source
invariant_factorsMethod
invariant_factors(m::FPModule{T}) where T <: RingElement

Return a vector of the invariant factors of the module $M$.

source

Examples

julia> M = free_module(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], Hom: invariant factor decomposed module over integers with invariant factors BigInt[0] -> 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/PR4245/AbstractAlgebra/module_homomorphism/index.html b/previews/PR4245/AbstractAlgebra/module_homomorphism/index.html deleted file mode 100644 index e21b1ec175b9..000000000000 --- a/previews/PR4245/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$.

source
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.

source

Examples

julia> M = free_module(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$.

source

Examples

julia> M = free_module(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$

source
M = free_module(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.

source
M = free_module(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.

source
M = free_module(ZZ, 2)
-N = matrix(ZZ, 2, 2, BigInt[1, 0, 0, 1])
-f = ModuleIsomorphism(M, M, N)
-
-g = inv(f)
diff --git a/previews/PR4245/AbstractAlgebra/module_interface/index.html b/previews/PR4245/AbstractAlgebra/module_interface/index.html deleted file mode 100644 index e4b1224775ee..000000000000 --- a/previews/PR4245/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.

number_of_generators(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/PR4245/AbstractAlgebra/module_introduction/index.html b/previews/PR4245/AbstractAlgebra/module_introduction/index.html deleted file mode 100644 index 78128702e6a9..000000000000 --- a/previews/PR4245/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/PR4245/AbstractAlgebra/mpoly_interface/index.html b/previews/PR4245/AbstractAlgebra/mpoly_interface/index.html deleted file mode 100644 index 6e0ef40809f9..000000000000 --- a/previews/PR4245/AbstractAlgebra/mpoly_interface/index.html +++ /dev/null @@ -1,7 +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_ringMethod
polynomial_ring(R::Ring, varnames::Vector{Symbol}; cached=true, internal_ordering=:lex)

Given a coefficient ring R and variable names, say varnames = [:x1, :x2, ...], return a tuple S, [x1, x2, ...] of the polynomial ring $S = R[x1, x2, \dots]$ and its generators $x1, x2, \dots$.

By default (cached=true), the output S will be cached, i.e. if polynomial_ring is invoked again with the same arguments, the same (identical) ring is returned. Setting cached to false ensures a distinct new ring is returned, and will also prevent it from being cached.

The monomial ordering used for the internal storage of polynomials in S can be set with internal_ordering and must be one of :lex, :deglex or :degrevlex.

See also: polynomial_ring(::Ring, ::Vararg), @polynomial_ring.

Example

julia> S, generators = polynomial_ring(ZZ, [:x, :y, :z])
-(Multivariate polynomial ring in 3 variables over integers, AbstractAlgebra.Generic.MPoly{BigInt}[x, y, z])
source

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.

number_of_variables(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).

internal_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/PR4245/AbstractAlgebra/mpolynomial/index.html b/previews/PR4245/AbstractAlgebra/mpolynomial/index.html deleted file mode 100644 index 42baaca03fb4..000000000000 --- a/previews/PR4245/AbstractAlgebra/mpolynomial/index.html +++ /dev/null @@ -1,479 +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 the following constructors.

polynomial_ringMethod
polynomial_ring(R::Ring, varnames::Vector{Symbol}; cached=true, internal_ordering=:lex)

Given a coefficient ring R and variable names, say varnames = [:x1, :x2, ...], return a tuple S, [x1, x2, ...] of the polynomial ring $S = R[x1, x2, \dots]$ and its generators $x1, x2, \dots$.

By default (cached=true), the output S will be cached, i.e. if polynomial_ring is invoked again with the same arguments, the same (identical) ring is returned. Setting cached to false ensures a distinct new ring is returned, and will also prevent it from being cached.

The monomial ordering used for the internal storage of polynomials in S can be set with internal_ordering and must be one of :lex, :deglex or :degrevlex.

See also: polynomial_ring(::Ring, ::Vararg), @polynomial_ring.

Example

julia> S, generators = polynomial_ring(ZZ, [:x, :y, :z])
-(Multivariate polynomial ring in 3 variables over integers, AbstractAlgebra.Generic.MPoly{BigInt}[x, y, z])
source
polynomial_ringMethod
polynomial_ring(R::Ring, varnames...; cached=true, internal_ordering=:lex)
-polynomial_ring(R::Ring, varnames::Tuple; cached=true, internal_ordering=:lex)

Like polynomial_ring(::Ring, ::Vector{Symbol}) with more ways to give varnames as specified in variable_names.

Return a tuple S, generators... with generators[i] corresponding to varnames[i].

Note

In the first method, varnames must not be empty, and if it consists of only one name, the univariate polynomial_ring(R::NCRing, s::VarName) method is called instead.

Examples

julia> S, (a, b, c) = polynomial_ring(ZZ, [:a, :b, :c])
-(Multivariate polynomial ring in 3 variables over integers, AbstractAlgebra.Generic.MPoly{BigInt}[a, b, c])
-
-julia> S, x, y = polynomial_ring(ZZ, :x => (1:2, 1:2), :y => 1:3);
-
-julia> S
-Multivariate polynomial ring in 7 variables x[1, 1], x[2, 1], x[1, 2], x[2, 2], ..., y[3]
-  over integers
-
-julia> x
-2×2 Matrix{AbstractAlgebra.Generic.MPoly{BigInt}}:
- x[1, 1]  x[1, 2]
- x[2, 1]  x[2, 2]
-
-julia> y
-3-element Vector{AbstractAlgebra.Generic.MPoly{BigInt}}:
- y[1]
- y[2]
- y[3]
source
polynomial_ringMethod
polynomial_ring(R::Ring, varnames...; cached=true, internal_ordering=:lex)
-polynomial_ring(R::Ring, varnames::Tuple; cached=true, internal_ordering=:lex)

Like polynomial_ring(::Ring, ::Vector{Symbol}) with more ways to give varnames as specified in variable_names.

Return a tuple S, generators... with generators[i] corresponding to varnames[i].

Note

In the first method, varnames must not be empty, and if it consists of only one name, the univariate polynomial_ring(R::NCRing, s::VarName) method is called instead.

Examples

julia> S, (a, b, c) = polynomial_ring(ZZ, [:a, :b, :c])
-(Multivariate polynomial ring in 3 variables over integers, AbstractAlgebra.Generic.MPoly{BigInt}[a, b, c])
-
-julia> S, x, y = polynomial_ring(ZZ, :x => (1:2, 1:2), :y => 1:3);
-
-julia> S
-Multivariate polynomial ring in 7 variables x[1, 1], x[2, 1], x[1, 2], x[2, 2], ..., y[3]
-  over integers
-
-julia> x
-2×2 Matrix{AbstractAlgebra.Generic.MPoly{BigInt}}:
- x[1, 1]  x[1, 2]
- x[2, 1]  x[2, 2]
-
-julia> y
-3-element Vector{AbstractAlgebra.Generic.MPoly{BigInt}}:
- y[1]
- y[2]
- y[3]
source
polynomial_ring(R::Ring, n::Int, s::Symbol=:x; cached=true, internal_ordering=:lex)

Same as polynomial_ring(::Ring, ["s$i" for i in 1:n]).

Example

julia> S, x = polynomial_ring(ZZ, 3)
-(Multivariate polynomial ring in 3 variables over integers, AbstractAlgebra.Generic.MPoly{BigInt}[x1, x2, x3])
source
@polynomial_ringMacro
@polynomial_ring(R::Ring, varnames...; cached=true, internal_ordering=:lex)

Return polynomial ring from polynomial_ring(::Ring, ::Vararg) and introduce the generators into the current scope.

Examples

julia> S = @polynomial_ring(ZZ, "x#" => (1:2, 1:2), "y#" => 1:3)
-Multivariate polynomial ring in 7 variables x11, x21, x12, x22, ..., y3
-  over integers
-
-julia> x11, x21, x12, x22
-(x11, x21, x12, x22)
-
-julia> y1, y2, y3
-(y1, y2, y3)
-
-julia> (S, [x11 x12; x21 x22], [y1, y2, y3]) == polynomial_ring(ZZ, "x#" => (1:2, 1:2), "y#" => 1:3)
-true
source

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]; internal_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
-
-julia> R, x = polynomial_ring(ZZ, 10); R
-Multivariate polynomial ring in 10 variables x1, x2, x3, x4, ..., x10
-  over integers
-

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.

source
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.

source
finishMethod
finish(M::MPolyBuildCtx)

Finish construction of the polynomial, sort the terms, remove duplicate and zero terms and return the created polynomial.

source

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
-
-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)
-number_of_variables(f::MPolyRing)
-gens(S::MPolyRing)
-gen(S::MPolyRing, i::Int)
internal_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::MPolyRing)

Returns true if $R$ is a univariate polynomial ring, i.e. has exactly one variable, and false otherwise.

source
varsMethod
vars(p::MPolyRingElem{T}) where {T <: RingElement}

Return the variables actually occurring in $p$.

source
var_indexMethod
var_index(p::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.

source
degreeMethod
degree(f::MPolyRingElem{T}, i::Int) where T <: RingElement

Return the degree of the polynomial $f$ in terms of the i-th variable.

source
degreeMethod
degree(f::MPolyRingElem{T}, x::MPolyRingElem{T}) where T <: RingElement

Return the degree of the polynomial $f$ in terms of the variable $x$.

source
degreesMethod
degrees(f::MPolyRingElem{T}) where T <: RingElement

Return an array of the degrees of the polynomial $f$ in terms of each variable.

source
is_constantMethod
is_constant(x::MPolyRingElem{T}) where T <: RingElement

Return true if x is a degree zero polynomial or the zero polynomial, i.e. a constant polynomial.

source
is_termMethod
is_term(x::MPolyRingElem)

Return true if the given polynomial has precisely one term.

source
is_monomialMethod
is_monomial(x::MPolyRingElem)

Return true if the given polynomial has precisely one term whose coefficient is one.

source
is_univariateMethod
is_univariate(p::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.

source
coeffMethod
coeff(f::MPolyRingElem{T}, m::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.

source

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]; internal_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 = internal_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> number_of_variables(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.

source
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.

source
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.

source

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::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).

source
coeffMethod
coeff(a::T, vars::Vector{T}, exps::Vector{Int}) where T <: 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$.

source

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::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).

source
deflateMethod
deflate(f::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$.

source
deflateMethod
deflate(f::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$.

source
deflateMethod
deflate(f::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$.

source
deflateMethod
deflate(f::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$.

source
deflateMethod
deflate(f::T, vars::Vector{T}, shift::Vector{Int}, defl::Vector{Int}) where T <: 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$.

source
inflateMethod
inflate(f::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).

source
inflateMethod
inflate(f::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).

source
inflateMethod
inflate(f::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).

source
inflateMethod
inflate(f::T, vars::Vector{T}, shift::Vector{Int}, defl::Vector{Int}) where T <: 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).

source

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::PolyRing{T}, p::MPolyRingElem{T}) where T <: 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.

source

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::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.

source

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::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.

source
evaluateMethod
evaluate(a::S, vars::Vector{S}, vals::Vector{U}) where {S <: 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.

source

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::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.

source

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 = matrix_ring(ZZ, 2)
-Matrix ring 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$.

source
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.

source
leading_monomialMethod
leading_monomial(p::MPolyRingElem)

Return the leading monomial of $p$. This function throws an ArgumentError if $p$ is zero.

source
leading_termMethod
leading_term(p::MPolyRingElem)

Return the leading term of the polynomial p. This function throws an ArgumentError if $p$ is zero.

source
constant_coefficientMethod
constant_coefficient(p::MPolyRingElem)

Return the constant coefficient of the polynomial $p$ or zero if it doesn't have one.

source
tailMethod
tail(p::MPolyRingElem)

Return the tail of the polynomial $p$, i.e. the polynomial without its leading term (if any).

source

Examples

using AbstractAlgebra
-R,(x,y) = polynomial_ring(ZZ, [:x, :y], internal_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).

source

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).

source

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::MPolyRingElem{T}, x::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.

source

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.

source

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::AbstractUnitRange{Int}, term_range::AbstractUnitRange{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/PR4245/AbstractAlgebra/mseries/index.html b/previews/PR4245/AbstractAlgebra/mseries/index.html deleted file mode 100644 index 17d8609d4467..000000000000 --- a/previews/PR4245/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 ring in 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:

symbolsMethod
symbols(R::MSeriesRing)

Return a vector of symbols, one for each of the variables of the series ring $R$.

source
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.

source
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.

source
characteristicMethod
characteristic(R::FracField{T}) where T <: RingElem

Return the characteristic of the given field.

source
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.

source
gensMethod
gens(R::AbsMSeriesRing)

Return a vector of the generators (variables) of the series ring $R$, starting with the most significant.

source
is_genMethod
is_gen(a::AbsMSeries)

Return true if the series $a$ is a generator of its parent series ring.

source
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.

source
lengthMethod
length(a::AbsMSeries)

Return the number of nonzero terms in the series $a$.

source

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.

source
valuationMethod
valuation(a::AbsMSeries)

Return the valuation of $a$ as a vector of integers, one for each variable.

source

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.

source
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.

source

Truncation

truncateMethod
truncate(a::AbstractAlgebra.AbsMSeries, prec::Vector{Int})

Return $a$ truncated to (absolute) precisions given by the vector prec.

source
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.

source

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.

source

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$.

source
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$.

source
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$.

source

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.

source
diff --git a/previews/PR4245/AbstractAlgebra/ncpolynomial/index.html b/previews/PR4245/AbstractAlgebra/ncpolynomial/index.html deleted file mode 100644 index da9456e5f449..000000000000 --- a/previews/PR4245/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 = :x; 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)
source

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 = matrix_ring(ZZ, 2)
-Matrix ring of degree 2
-  over integers
-
-julia> S, x = polynomial_ring(R, :x)
-(Univariate polynomial ring in x over matrix ring, x)
-
-julia> T, y = polynomial_ring(S, :y)
-(Univariate polynomial ring in y over univariate polynomial ring in x over matrix ring, y)
-
-julia> U, z = R[:z]
-(Univariate polynomial ring in z over matrix ring, 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 = matrix_ring(ZZ, 2)
-Matrix ring of degree 2
-  over integers
-
-julia> S, x = polynomial_ring(R, :x)
-(Univariate polynomial ring in x over matrix ring, x)
-
-julia> T, y = polynomial_ring(S, :y)
-(Univariate polynomial ring in y over univariate polynomial ring in x over matrix ring, 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 ring
-
-julia> V = base_ring(y + 1)
-Univariate polynomial ring in x over matrix ring
-
-julia> v = var(T)
-:y
-
-julia> U = parent(y + 1)
-Univariate polynomial ring in y over univariate polynomial ring in x over matrix ring
-
-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.

source
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.

source
genMethod
gen(R::NCPolyRing)

Return the generator of the given polynomial ring.

source
is_genMethod
is_gen(a::PolynomialElem)

Return true if the given polynomial is the constant generator of its polynomial ring, otherwise return false.

source
is_monomialMethod
is_monomial(a::PolynomialElem)

Return true if the given polynomial is a monomial.

source
is_termMethod
is_term(a::PolynomialElem)

Return true if the given polynomial has one term.

source

Examples

julia> R = matrix_ring(ZZ, 2)
-Matrix ring of degree 2
-  over integers
-
-julia> S, x = polynomial_ring(R, :x)
-(Univariate polynomial ring in x over matrix ring, x)
-
-julia> T, y = polynomial_ring(S, :y)
-(Univariate polynomial ring in y over univariate polynomial ring in x over matrix ring, 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$.

source
mullowMethod
mullow(a::NCPolyRingElem{T}, b::NCPolyRingElem{T}, n::Int) where T <: NCRingElem

Return $a\times b$ truncated to $n$ terms.

source

Examples

julia> R = matrix_ring(ZZ, 2)
-Matrix ring of degree 2
-  over integers
-
-julia> S, x = polynomial_ring(R, :x)
-(Univariate polynomial ring in x over matrix ring, x)
-
-julia> T, y = polynomial_ring(S, :y)
-(Univariate polynomial ring in y over univariate polynomial ring in x over matrix ring, 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().

source
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.

source

Examples

julia> R = matrix_ring(ZZ, 2)
-Matrix ring of degree 2
-  over integers
-
-julia> S, x = polynomial_ring(R, :x)
-(Univariate polynomial ring in x over matrix ring, x)
-
-julia> T, y = polynomial_ring(S, :y)
-(Univariate polynomial ring in y over univariate polynomial ring in x over matrix ring, 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$.

source
shift_rightMethod
shift_right(f::PolynomialElem, n::Int)

Return the polynomial $f$ shifted right by $n$ terms, i.e. divided by $x^n$.

source

Examples

julia> R = matrix_ring(ZZ, 2)
-Matrix ring of degree 2
-  over integers
-
-julia> S, x = polynomial_ring(R, :x)
-(Univariate polynomial ring in x over matrix ring, x)
-
-julia> T, y = polynomial_ring(S, :y)
-(Univariate polynomial ring in y over univariate polynomial ring in x over matrix ring, 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.

source
evaluateMethod
evaluate(a::NCPolyRingElem, b::Union{Integer, Rational, AbstractFloat})

Evaluate the polynomial $a$ at the value $b$ and return the result.

source

We also overload the functional notation so that the polynomial $f$ can be evaluated at $a$ by writing $f(a)$.

Examples

julia> R = matrix_ring(ZZ, 2)
-Matrix ring of degree 2
-  over integers
-
-julia> S, x = polynomial_ring(R, :x)
-(Univariate polynomial ring in x over matrix ring, x)
-
-julia> T, y = polynomial_ring(S, :y)
-(Univariate polynomial ring in y over univariate polynomial ring in x over matrix ring, 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$.

source

Examples

julia> R = matrix_ring(ZZ, 2)
-Matrix ring of degree 2
-  over integers
-
-julia> S, x = polynomial_ring(R, :x)
-(Univariate polynomial ring in x over matrix ring, x)
-
-julia> T, y = polynomial_ring(S, :y)
-(Univariate polynomial ring in y over univariate polynomial ring in x over matrix ring, 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/PR4245/AbstractAlgebra/ncring_interface/index.html b/previews/PR4245/AbstractAlgebra/ncring_interface/index.html deleted file mode 100644 index 493c2d6f9612..000000000000 --- a/previews/PR4245/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/PR4245/AbstractAlgebra/perm/index.html b/previews/PR4245/AbstractAlgebra/perm/index.html deleted file mode 100644 index eaf6a0ee1d50..000000000000 --- a/previews/PR4245/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)
source

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}
source

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}
source

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
source

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]
source

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
source
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
source
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
source

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)
source

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)
source
^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
-()
source
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.

source

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
source
==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
source

Misc

randMethod
rand([rng=GLOBAL_RNG,] G::SymmetricGroup)

Return a random permutation from G.

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
source
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  ⋅  ⋅  ⋅
source
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)
source
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)
source
diff --git a/previews/PR4245/AbstractAlgebra/poly_interface/index.html b/previews/PR4245/AbstractAlgebra/poly_interface/index.html deleted file mode 100644 index 2ce37673d2e4..000000000000 --- a/previews/PR4245/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/PR4245/AbstractAlgebra/polynomial/index.html b/previews/PR4245/AbstractAlgebra/polynomial/index.html deleted file mode 100644 index 6018813956ec..000000000000 --- a/previews/PR4245/AbstractAlgebra/polynomial/index.html +++ /dev/null @@ -1,517 +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 = :x; 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)
source

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 their associated generators.

Examples

julia> T, z = QQ[:z]
-(Univariate polynomial ring in z over rationals, z)
-
-julia> U, x = polynomial_ring(ZZ)
-(Univariate polynomial ring in x over integers, x)

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);
-
-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.

source
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.

source
leading_coefficient(p::MPolyRingElem)

Return the leading coefficient of the polynomial $p$.

source
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.

source
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.

source
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.

source
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$.

source
tailMethod
tail(a::PolynomialElem)

Return the tail of the given polynomial, i.e. the polynomial without its leading term (if any).

source
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.

source
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$.

source
is_genMethod
is_gen(a::PolynomialElem)

Return true if the given polynomial is the constant generator of its polynomial ring, otherwise return false.

source
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.

source
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.

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

Return true if $f$ is a perfect square.

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

Return true if $a$ is a square.

source
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.)

source
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.

source
is_monomialMethod
is_monomial(a::PolynomialElem)

Return true if the given polynomial is a monomial.

source
is_monomial(x::MPolyRingElem)

Return true if the given polynomial has precisely one term whose coefficient is one.

source
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.

source
is_termMethod
is_term(a::PolynomialElem)

Return true if the given polynomial has one term.

source
is_term(x::MPolyRingElem)

Return true if the given polynomial has precisely one term.

source
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.

source
is_constantMethod
is_constant(a::PolynomialElem)

Return true if a is a degree zero polynomial or the zero polynomial, i.e. a constant polynomial.

source

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);
-
-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$.

source
mullowMethod
mullow(a::PolyRingElem{T}, b::PolyRingElem{T}, n::Int) where T <: RingElement

Return $a\times b$ truncated to $n$ terms.

source

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().

source
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.

source

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$.

source
shift_rightMethod
shift_right(f::PolynomialElem, n::Int)

Return the polynomial $f$ shifted right by $n$ terms, i.e. divided by $x^n$.

source

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.

source
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$.

source
inflateMethod
inflate(f::PolyRingElem, n::Int64) -> PolyRingElem

Given a polynomial $f$ in $x$, return $f(x^n)$, i.e. multiply all exponents by $n$.

source
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$.

source
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$.

source
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$.

source

Square root

sqrtMethod
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.

source
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.

source

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.

source
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.

source
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.

source

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().

source
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().

source

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.

source
primpartMethod
primpart(a::PolyRingElem)

Return the primitive part of $a$, i.e. the polynomial divided by its content.

source

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.

source
composeMethod
compose(f::PolyRingElem, g::PolyRingElem; inner)

Compose the polynomial $a$ with the polynomial $b$ and return the result.

  • If inner = :right, then f(g) is returned.
  • If inner = :left, then g(f) is returned.
source
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.

source

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; inner = :second)
-(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::PolynomialElem)

Return the derivative of the polynomial $a$.

source
derivative(f::AbsPowerSeriesRingElem{T})

Return the derivative of the power series $f$.

source
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)
source
derivative(f::MPolyRingElem{T}, j::Int) where {T <: RingElement}

Return the partial derivative of f with respect to $j$-th variable of the polynomial ring.

source
derivative(f::MPolyRingElem{T}, x::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.

source
derivative(x::spoly{T}, n::Int) where T <: Nemo.RingElem

Return the derivative of $x$ with respect to the variable of index $n$.

source
derivative(x::spoly{T}, v::spoly{T}) where T <: Nemo.RingElem

Return the derivative of $x$ with respect to the variable $v$.

source
derivative(a::Generic.PuiseuxSeriesElem{T}) where T <: RingElement

Return the derivative of the given Puiseux series $a$.

source
integralMethod
integral(x::PolyRingElem{T}) where {T <: Union{ResElem, FieldElement}}

Return the integral of the polynomial $x$.

source
integral(f::AbsPowerSeriesRingElem{T})

Return the integral of the power series $f$.

source
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)
source
integral(f::RelPowerSeriesRingElem{T}) -> RelPowerSeriesRingElem

Return the integral of the power series $f$.

source
integral(a::Generic.PuiseuxSeriesElem{T}) where T <: RingElement

Return the integral of the given Puiseux series $a$.

source

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);
-
-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.

source
resultantMethod
resultant(p::PolyRingElem{T}, q::PolyRingElem{T}) where T <: RingElement

Return the resultant of the given polynomials.

source
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$.

source
discriminantMethod
discriminant(a::PolyRingElem)

Return the discriminant of the given polynomial.

source

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.

source
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$.

source

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.

source
rootsMethod
roots(R::Field, f::PolyRingElem)

Returns the roots of the polynomial f in the field R as an array.

source

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.

source

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.

source
power_sums_to_polynomialMethod
power_sums_to_polynomial(P::Vector{T};
-                 parent::PolyRing{T}=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.

source

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))$.

source
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)$.

source

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::AbstractUnitRange{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)

Ring homomorphisms

homMethod
hom(R::AbstractAlgebra.PolyRing, S::NCRing, [coeff_map,] image)

Given a homomorphism coeff_map from C to S, where C is the coefficient ring of R, and given an element image of S, return the homomorphism from R to S whose restriction to C is coeff_map, and which sends the generator of R to image.

If no coefficient map is entered, invoke a canonical homomorphism of C to S, if such a homomorphism exists, and throw an error, otherwise.

Examples

julia> Zx, x = ZZ[:x];
-
-julia> F = hom(Zx, Zx, x + 1);
-
-julia> F(x^2)
-x^2 + 2*x + 1
-
-julia> Fp = GF(3); Fpy, y = Fp[:y];
-
-julia> G = hom(Zx, Fpy, c -> Fp(c), y^3);
-
-julia> G(5*x + 1)
-2*y^3 + 1
source
diff --git a/previews/PR4245/AbstractAlgebra/puiseux/index.html b/previews/PR4245/AbstractAlgebra/puiseux/index.html deleted file mode 100644 index 4b195e123195..000000000000 --- a/previews/PR4245/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.

puiseux_series_ring(R::Ring, prec_max::Int, s::VarName; cached::Bool = true)
puiseux_series_ring(R::Field, prec_max::Int, s::VarName; cached::Bool = true)
puiseux_series_field(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 = puiseux_series_ring(ZZ, 10, :x)
-(Puiseux series ring in x over integers, x + O(x^11))
-
-julia> S, y = puiseux_series_field(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 = puiseux_series_ring(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 = puiseux_series_ring(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.

source
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.

source

Examples

julia> R, t = puiseux_series_ring(QQ, 10, :t)
-(Puiseux series field in t over rationals, t + O(t^11))
-
-julia> S, x = puiseux_series_ring(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
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.

source
inv(f::EllCrvIso) -> EllCrvIso

Return the inverse of the isomorphism $f$.

source
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.

source
 inv(a::LocalizedEuclideanRingElem{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.

source

Examples

julia> R, x = puiseux_series_ring(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(f::AbsPowerSeriesRingElem{T})

Return the derivative of the power series $f$.

source
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)
source
derivative(f::MPolyRingElem{T}, j::Int) where {T <: RingElement}

Return the partial derivative of f with respect to $j$-th variable of the polynomial ring.

source
derivative(f::MPolyRingElem{T}, x::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.

source
derivative(x::spoly{T}, n::Int) where T <: Nemo.RingElem

Return the derivative of $x$ with respect to the variable of index $n$.

source
derivative(x::spoly{T}, v::spoly{T}) where T <: Nemo.RingElem

Return the derivative of $x$ with respect to the variable $v$.

source
derivative(a::Generic.PuiseuxSeriesElem{T}) where T <: RingElement

Return the derivative of the given Puiseux series $a$.

source
integralMethod
integral(f::AbsPowerSeriesRingElem{T})

Return the integral of the power series $f$.

source
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)
source
integral(f::RelPowerSeriesRingElem{T}) -> RelPowerSeriesRingElem

Return the integral of the power series $f$.

source
integral(a::Generic.PuiseuxSeriesElem{T}) where T <: RingElement

Return the integral of the given Puiseux series $a$.

source

Examples

julia> R, x = puiseux_series_ring(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$.

source
expMethod
exp(a::AbsPowerSeriesRingElem)

Return the exponential of the power series $a$.

source
exp(a::RelPowerSeriesRingElem)

Return the exponential of the power series $a$.

source
exp(a::Generic.LaurentSeriesElem)

Return the exponential of the power series $a$.

source
exp(a::Generic.PuiseuxSeriesElem{T}) where T <: RingElement

Return the exponential of the given Puiseux series $a$.

source
sqrtMethod
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.

source
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.

source
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.

source

Examples

julia> R, t = polynomial_ring(QQ, :t)
-(Univariate polynomial ring in t over rationals, t)
-
-julia> S, x = puiseux_series_ring(R, 30, :x)
-(Puiseux series ring in x over univariate polynomial ring, x + O(x^31))
-
-julia> T, z = puiseux_series_ring(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/PR4245/AbstractAlgebra/quotient_module/index.html b/previews/PR4245/AbstractAlgebra/quotient_module/index.html deleted file mode 100644 index feb1297d0be4..000000000000 --- a/previews/PR4245/AbstractAlgebra/quotient_module/index.html +++ /dev/null @@ -1,65 +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.

source

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 = free_module(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 = vector_space(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.

source
dimMethod
dim(N::QuotientModule{T}) where T <: FieldElement

Return the dimension of the given vector quotient space.

source

Examples

julia> M = free_module(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 = vector_space(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/PR4245/AbstractAlgebra/rand/index.html b/previews/PR4245/AbstractAlgebra/rand/index.html deleted file mode 100644 index 9b413b878072..000000000000 --- a/previews/PR4245/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::AbstractUnitRange{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::AbstractUnitRange{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, <:AbstractUnitRange{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::AbstractUnitRange{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/PR4245/AbstractAlgebra/rational/index.html b/previews/PR4245/AbstractAlgebra/rational/index.html deleted file mode 100644 index 9712ffd882e6..000000000000 --- a/previews/PR4245/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 and is_power.

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/PR4245/AbstractAlgebra/real/index.html b/previews/PR4245/AbstractAlgebra/real/index.html deleted file mode 100644 index 72d076bfd74f..000000000000 --- a/previews/PR4245/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/PR4245/AbstractAlgebra/residue/index.html b/previews/PR4245/AbstractAlgebra/residue/index.html deleted file mode 100644 index 60a04add86cd..000000000000 --- a/previews/PR4245/AbstractAlgebra/residue/index.html +++ /dev/null @@ -1,116 +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 of Euclidean rings with type EuclideanRingResidueRingElem{T} or in the case of residue rings that are known to be fields, EuclideanRingResidueFieldElem{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 EuclideanRingResidueRing{T} and those of residue fields have type EuclideanRingResidueField{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.

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)$ together with the canonical projection. 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.

source
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.

source

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);
-
-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: univariate polynomial ring -> residue ring)
-
-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.

source

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);
-
-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.

source

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);
-
-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.

source

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);
-
-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.

source
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.

source

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);
-
-julia> f = rand(R, 0:6)
-4
-
-julia> S, x = polynomial_ring(QQ, :x)
-(Univariate polynomial ring in x over rationals, x)
-
-julia> g = rand(S, 2:2, -10:10)
--1//4*x^2 - 2//7*x + 1
diff --git a/previews/PR4245/AbstractAlgebra/residue_interface/index.html b/previews/PR4245/AbstractAlgebra/residue_interface/index.html deleted file mode 100644 index 3218d0c0bc77..000000000000 --- a/previews/PR4245/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/PR4245/AbstractAlgebra/ring/index.html b/previews/PR4245/AbstractAlgebra/ring/index.html deleted file mode 100644 index 4a5eb3f62bdc..000000000000 --- a/previews/PR4245/AbstractAlgebra/ring/index.html +++ /dev/null @@ -1,35 +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 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!Function
zero!(a)

Return zero(parent(a)), possibly modifying the object a in the process.

source
one!Function
one!(a)

Return one(parent(a)), possibly modifying the object a in the process.

source
add!Function
add!(z, a, b)
-add!(a, b)

Return a + b, possibly modifying the object z in the process. Aliasing is permitted. The two argument version is a shorthand for add!(a, a, b).

source
sub!Function
sub!(z, a, b)
-sub!(a, b)

Return a - b, possibly modifying the object z in the process. Aliasing is permitted. The two argument version is a shorthand for sub!(a, a, b).

source
mul!Function
mul!(z, a, b)
-mul!(a, b)

Return a * b, possibly modifying the object z in the process. Aliasing is permitted. The two argument version is a shorthand for mul!(a, a, b).

source
neg!Function
neg!(z, a)
-neg!(a)

Return -a, possibly modifying the object z in the process. Aliasing is permitted. The unary version is a shorthand for neg!(a, a).

source
inv!Function
inv!(z, a)
-inv!(a)

Return AbstractAlgebra.inv(a), possibly modifying the object z in the process. Aliasing is permitted. The unary version is a shorthand for inv!(a, a).

Note

AbstractAlgebra.inv and Base.inv differ only in their behavior on julia types like Integer and Rational{Int}. The former makes it adhere to the Ring interface.

source
addmul!Function
addmul!(z, a, b, t)
-addmul!(z, a, b)

Return z + a * b, possibly modifying the objects z and t in the process.

The second version is usually a shorthand for addmul!(z, a, b, parent(z)()), but in some cases may be more efficient. For multiple operations in a row that use temporary storage, it is still best to use the four argument version.

source
submul!Function
submul!(z, a, b, t)
-submul!(z, a, b)

Return z - a * b, possibly modifying the objects z and t in the process.

The second version is usually a shorthand for submul!(z, a, b, parent(z)()), but in some cases may be more efficient. For multiple operations in a row that use temporary storage, it is still best to use the four argument version.

source
divexact!Function
divexact!(A::Generic.Mat{AbsSimpleNumFieldElem}, p::ZZRingElem)

Inplace: divide each entry of $A$ by $p$.

source
divexact!(z, a, b)
-divexact!(a, b)

Return divexact(a, b), possibly modifying the object z in the process. Aliasing is permitted. The two argument version is a shorthand for divexact(a, a, b).

source
div!Function
div!(z, a, b)
-div!(a, b)

Return div(a, b), possibly modifying the object z in the process. Aliasing is permitted. The two argument version is a shorthand for div(a, a, b).

Note

AbstractAlgebra.div and Base.div differ only in their behavior on julia types like Integer and Rational{Int}. The former makes it adhere to the Ring interface.

source
rem!Function
rem!(z, a, b)
-rem!(a, b)

Return rem(a, b), possibly modifying the object z in the process. Aliasing is permitted. The two argument version is a shorthand for rem(a, a, b).

source
mod!Function
mod!(M::ZZMatrix, p::ZZRingElem)

Reduces every entry modulo $p$ in-place, i.e. applies the mod function to every entry. Positive residue system.

source
mod!(A::Generic.Mat{AbsSimpleNumFieldElem}, m::ZZRingElem)

Inplace: reduce all entries of $A$ modulo $m$, into the positive residue system.

source
mod!(z, a, b)
-mod!(a, b)

Return mod(a, b), possibly modifying the object z in the process. Aliasing is permitted. The two argument version is a shorthand for mod(a, a, b).

source
mod!(A::SRow{ZZRingElem}, n::Integer) -> SRow{ZZRingElem}

Inplace reduction of all entries of $A$ modulo $n$ to the positive residue system.

source
mod!(A::SRow{ZZRingElem}, n::ZZRingElem) -> SRow{ZZRingElem}

Inplace reduction of all entries of $A$ modulo $n$ to the positive residue system.

source
gcd!Function
gcd!(z, a, b)
-gcd!(a, b)

Return gcd(a, b), possibly modifying the object z in the process. Aliasing is permitted. The two argument version is a shorthand for gcd(a, a, b).

source
lcm!Function
lcm!(z, a, b)
-lcm!(a, b)

Return lcm(a, b), possibly modifying the object z in the process. Aliasing is permitted. The two argument version is a shorthand for lcm(a, a, b).

source

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_irreducibleMethod
is_irreducible(a::RingElement)

Return true if $a$ is irreducible, else return false. Zero and units are by definition never irreducible.

source
is_squarefreeMethod
is_squarefree(a::RingElement)

Return true if $a$ is squarefree, else return false. An element is squarefree if it it is not divisible by any squares except the squares of units.

source
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.

See unit(a::Fac), evaluate(a::Fac).

source
unitMethod
unit(a::Fac{T}) -> T

Return the unit of the factorization.

source
evaluateMethod
evaluate(a::Fac{T}) -> T

Multiply out the factorization into a single element.

source
getindexMethod
getindex(a::Fac, b) -> Int

If $b$ is a factor of $a$, the corresponding exponent is returned. Otherwise an error is thrown.

source
setindex!Method
setindex!(a::Fac{T}, c::Int, b::T)

If $b$ is a factor of $a$, the corresponding entry is set to $c$.

source
diff --git a/previews/PR4245/AbstractAlgebra/ring_interface/index.html b/previews/PR4245/AbstractAlgebra/ring_interface/index.html deleted file mode 100644 index 3ad19fbc6601..000000000000 --- a/previews/PR4245/AbstractAlgebra/ring_interface/index.html +++ /dev/null @@ -1,272 +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 src/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_type(::Type{MyParent})

Return the type of the of base rings for parent objects with the given parent type. For example, base_ring_type(Generic.PolyRing{T}) will return parent_type(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 require 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.

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 unsafe operators

The various operators described in Unsafe ring operators such as add! and mul! have default implementations which are not faster than their regular safe counterparts. Implementors may wish to implement some or all of them for their rings. Note that in general only the variants with the most arguments needs to be implemented. E.g. for add! only add(z,a,b) has to be implemented for any new ring type, as add!(a,b) delegates to add!(a,a,b).

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, base_ring_type, parent, is_domain_type,
-       is_exact_type, canonical_unit, isequal, divexact, zero!, mul!, add!,
-       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_type(::Type{ConstPolyRing{T}}) where T <: RingElement = parent_type(T)
-
-base_ring(R::ConstPolyRing) = R.base_ring::base_ring_type(R)
-
-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
-   check_parent(f, g)
-   R = parent(f)
-   return R(f.c + g.c)
-end
-
-function -(f::ConstPoly{T}, g::ConstPoly{T}) where T <: RingElement
-   check_parent(f, g)
-   R = parent(f)
-   return R(f.c - g.c)
-end
-
-function *(f::ConstPoly{T}, g::ConstPoly{T}) where T <: RingElement
-   check_parent(f, g)
-   R = parent(f)
-   return R(f.c*g.c)
-end
-
-# Comparison
-
-function ==(f::ConstPoly{T}, g::ConstPoly{T}) where T <: RingElement
-   check_parent(f, g)
-   return f.c == g.c
-end
-
-function isequal(f::ConstPoly{T}, g::ConstPoly{T}) where T <: RingElement
-   check_parent(f, g)
-   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
-   check_parent(f, g)
-   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
-
-# 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::AbstractUnitRange{Int}) = R(rand(rng, n))
-
-rand(R::ConstPolyRing, n::AbstractUnitRange{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 constant_polynomial_ring(R::Ring, cached::Bool=true)
-   T = elem_type(R)
-   return ConstPolyRing{T}(R, cached)
-end

The above implementation of constant_polynomial_ring 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(constant_polynomial_ring(S))
diff --git a/previews/PR4245/AbstractAlgebra/ring_introduction/index.html b/previews/PR4245/AbstractAlgebra/ring_introduction/index.html deleted file mode 100644 index 2229553e614d..000000000000 --- a/previews/PR4245/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/PR4245/AbstractAlgebra/series/index.html b/previews/PR4245/AbstractAlgebra/series/index.html deleted file mode 100644 index f2d53aa1b695..000000000000 --- a/previews/PR4245/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::Symbol=: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.

source
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.

source

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.

source
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.

source

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$.

source
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$.

source

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$.

source

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$.

source

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(f::RelPowerSeriesRingElem, g::RelPowerSeriesRingElem; inner)

Compose the series $a$ with the series $b$ and return the result.

  • If inner = :second, then f(g) is returned and g must have positive valuation.
  • If inner = :first, then g(f) is returned and f must have positive valuation.
source

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(f::AbsPowerSeriesRingElem{T})

Return the derivative of the power series $f$.

source
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)
source
derivative(f::MPolyRingElem{T}, j::Int) where {T <: RingElement}

Return the partial derivative of f with respect to $j$-th variable of the polynomial ring.

source
derivative(f::MPolyRingElem{T}, x::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.

source
derivative(x::spoly{T}, n::Int) where T <: Nemo.RingElem

Return the derivative of $x$ with respect to the variable of index $n$.

source
derivative(x::spoly{T}, v::spoly{T}) where T <: Nemo.RingElem

Return the derivative of $x$ with respect to the variable $v$.

source
derivative(a::Generic.PuiseuxSeriesElem{T}) where T <: RingElement

Return the derivative of the given Puiseux series $a$.

source
integralMethod
integral(f::AbsPowerSeriesRingElem{T})

Return the integral of the power series $f$.

source
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)
source
integral(f::RelPowerSeriesRingElem{T}) -> RelPowerSeriesRingElem

Return the integral of the power series $f$.

source
integral(a::Generic.PuiseuxSeriesElem{T}) where T <: RingElement

Return the integral of the given Puiseux series $a$.

source

Special functions

logMethod
log(a::SeriesElem{T}) where T <: FieldElement

Return the logarithm of the power series $a$.

source
log(a::Generic.PuiseuxSeriesElem{T}) where T <: RingElement

Return the logarithm of the given Puiseux series $a$.

source
expMethod
exp(a::AbsPowerSeriesRingElem)

Return the exponential of the power series $a$.

source
exp(a::RelPowerSeriesRingElem)

Return the exponential of the power series $a$.

source
exp(a::Generic.LaurentSeriesElem)

Return the exponential of the power series $a$.

source
exp(a::Generic.PuiseuxSeriesElem{T}) where T <: RingElement

Return the exponential of the given Puiseux series $a$.

source
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.

source

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::AbstractUnitRange{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/PR4245/AbstractAlgebra/series_interface/index.html b/previews/PR4245/AbstractAlgebra/series_interface/index.html deleted file mode 100644 index cd658abbc1aa..000000000000 --- a/previews/PR4245/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/PR4245/AbstractAlgebra/submodule/index.html b/previews/PR4245/AbstractAlgebra/submodule/index.html deleted file mode 100644 index 9867bfbd2f10..000000000000 --- a/previews/PR4245/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::FPModule{T}, gens::Vector{<:FPModuleElem{T}}) where T <: RingElement

Return the submodule of the module m generated by the given generators, given as elements of m.

source
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.

source

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 = free_module(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 = vector_space(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.

source
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.

source
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.

source
dimMethod
dim(N::Submodule{T}) where T <: FieldElement

Return the dimension of the given vector subspace.

source

Examples

julia> M = free_module(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 = vector_space(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
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$.

source

Examples

julia> M = free_module(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/PR4245/AbstractAlgebra/total_fraction/index.html b/previews/PR4245/AbstractAlgebra/total_fraction/index.html deleted file mode 100644 index d1c18addad15..000000000000 --- a/previews/PR4245/AbstractAlgebra/total_fraction/index.html +++ /dev/null @@ -1,107 +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
-
-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
-
-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
-
-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
-
-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
-
-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);
-
-julia> K = total_ring_of_fractions(R)
-Total ring of fractions of residue ring
-
-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
-
-julia> g = rand(S, -1:3, -10:10)
-(4*x + 4)//(-4*x^2 - x + 4)
diff --git a/previews/PR4245/AbstractAlgebra/types/index.html b/previews/PR4245/AbstractAlgebra/types/index.html deleted file mode 100644 index ad46076f9f75..000000000000 --- a/previews/PR4245/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/PR4245/AbstractAlgebra/univpolynomial/index.html b/previews/PR4245/AbstractAlgebra/univpolynomial/index.html deleted file mode 100644 index 9af25c958b8e..000000000000 --- a/previews/PR4245/AbstractAlgebra/univpolynomial/index.html +++ /dev/null @@ -1,26 +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.

universal_polynomial_ringFunction
universal_polynomial_ring(R::Ring; cached::Bool=true, internal_ordering::Symbol=:lex)

Given a base ring R, return an object representing the universal polynomial ring $S = R[\ldots]$ with no variables in it initially.

Examples

julia> S = universal_polynomial_ring(ZZ)
-Universal Polynomial Ring over Integers
-
-julia> x = gen(S, :x)
-x
-
-julia> y, z = gens(S, [:y, :z])
-(y, z)
-
-julia> x*y - z
-x*y - z
source

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 = universal_polynomial_ring(ZZ)
-Universal Polynomial Ring over Integers
-
-julia> x = gen(S, :x)
-x
-
-julia> number_of_generators(S)
-1
-
-julia> y, z = gens(S, [:y, :z])
-(y, z)
-
-julia> number_of_generators(S)
-3

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/PR4245/AbstractAlgebra/visualizing_types/index.html b/previews/PR4245/AbstractAlgebra/visualizing_types/index.html deleted file mode 100644 index 7c49931c3df8..000000000000 --- a/previews/PR4245/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.FracFieldElem{T} (Generic.FracField{T})
  • Generic.Mat{T} (MatSpace{T})
diff --git a/previews/PR4245/AbstractAlgebra/ytabs/index.html b/previews/PR4245/AbstractAlgebra/ytabs/index.html deleted file mode 100644 index dfbf36ccb00c..000000000000 --- a/previews/PR4245/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
source

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,)
source
getindexMethod
getindex(p::Partition, i::Integer)

Return the i-th part (in non-increasing order) of the partition.

source

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₁
source

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.

source

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₂
source
conjMethod
conj(part::Partition, v::Vector)

Return the conjugated partition of part together with permuted vector v.

source

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
source

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)
source
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
source

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 │
-└───┘
source

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 │
-└───┘
source

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
source
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  ⋅  ⋅  ⋅
source
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 │
-└───┘
source

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
source
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.

source
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.

source

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
source
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
source
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
source
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
source

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.

source
partitionseq(seq::BitVector)

Return the essential part of the sequence seq, i.e. a subsequence starting at first true and ending at last false.

source
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.

source
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.
source

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
-
source

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.

source
inMethod
in(t::Tuple{Integer,Integer}, xi::SkewDiagram)

Check if box at position (i,j) belongs to the skew diagram xi.

source
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.

source

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.

source
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.

source
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.

source
diff --git a/previews/PR4245/AlgebraicGeometry/AlgebraicSets/AffineAlgebraicSet/index.html b/previews/PR4245/AlgebraicGeometry/AlgebraicSets/AffineAlgebraicSet/index.html deleted file mode 100644 index ecb66d5d96b6..000000000000 --- a/previews/PR4245/AlgebraicGeometry/AlgebraicSets/AffineAlgebraicSet/index.html +++ /dev/null @@ -1,73 +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::AbsAffineScheme{<: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(intersect(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) -> AbsAffineScheme

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) -> AbsAffineScheme

Return the underlying reduced scheme defining $X$.

This is used to forward the AbsAffineScheme 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 <: AbsAffineScheme

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::AffineScheme; 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 x, y
-      over rational field
-    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/PR4245/AlgebraicGeometry/AlgebraicSets/ProjectiveAlgebraicSet/index.html b/previews/PR4245/AlgebraicGeometry/AlgebraicSets/ProjectiveAlgebraicSet/index.html deleted file mode 100644 index 03f188726a6b..000000000000 --- a/previews/PR4245/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]))
-Projective algebraic set
-  in projective 1-space over QQ with coordinates [x0, x1]
-defined by ideal (x0, x1)
-
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 = proj(ideal([x0*x1^2, x2]))
-Projective scheme
-  over rational field
-defined by ideal (x0*x1^2, x2)
-
-julia> Y = algebraic_set(X)
-Projective algebraic set
-  in projective 2-space over QQ with coordinates [x0, x1, x2]
-defined by ideal (x0*x1^2, x2)
-
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)
-Projective 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
-Projective 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 homogeneous ideal whose radical is the vanishing ideal of X.

source

Methods

Inherited from Projective schemes

Properties

Inherited from Projective schemes

diff --git a/previews/PR4245/AlgebraicGeometry/AlgebraicVarieties/AffineVariety/index.html b/previews/PR4245/AlgebraicGeometry/AlgebraicVarieties/AffineVariety/index.html deleted file mode 100644 index 427b191adec0..000000000000 --- a/previews/PR4245/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 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 ideal (x^3 + y + 1)
-
source
varietyMethod
variety(X::AbsAffineScheme; 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 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/PR4245/AlgebraicGeometry/AlgebraicVarieties/ProjectiveVariety/index.html b/previews/PR4245/AlgebraicGeometry/AlgebraicVarieties/ProjectiveVariety/index.html deleted file mode 100644 index 118d06c9a39e..000000000000 --- a/previews/PR4245/AlgebraicGeometry/AlgebraicVarieties/ProjectiveVariety/index.html +++ /dev/null @@ -1,92 +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{<:MPolyDecRingElem}; check::Bool=true, is_radical::Bool=false) -> 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^3 + s1^3 + s2^3 + s3^3, s0)
-
-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

In addition to what is inherited from Projective Algebraic Sets and Projective schemes, we currently have:

sectional_genusMethod
sectional_genus(X::AbsProjectiveVariety)

Given a subvariety X of some $\mathbb P^n$, return the arithmetic genus of the intersection of X with a general linear subspace of $\mathbb P^n$ of dimension $c+1$.

Examples

julia> X = bordiga()
-Projective variety
-  in projective 4-space over GF(31991) with coordinates [x, y, z, u, v]
-defined by ideal with 4 generators
-
-julia> dim(X)
-2
-
-julia> codim(X)
-2
-
-julia> degree(X)
-6
-
-julia> sectional_genus(X)
-3
source

Properties

In addition to what is inherited from Projective Algebraic Sets and Projective schemes, we currently have:

is_linearly_normalMethod
is_linearly_normal(X::AbsProjectiveVariety)

Return true if X is linearly normal, and false otherwise.

Examples

julia> X = bordiga()
-Projective variety
-  in projective 4-space over GF(31991) with coordinates [x, y, z, u, v]
-defined by ideal with 4 generators
-
-julia> dim(X)
-2
-
-julia> codim(X)
-2
-
-julia> is_linearly_normal(X)
-true
source

Methods

In addition to what is inherited from Projective Algebraic Sets and Projective schemes, we currently have:

canonical_bundleMethod
canonical_bundle(X::AbsProjectiveVariety)

Given a smooth projective variety X, return a module whose sheafification is the canonical bundle of X.

Note

The function does not check smoothness. If you are uncertain, enter is_smooth(X) first.

Examples

julia> R, x = graded_polynomial_ring(QQ, :x => (1:6));
-
-julia> I = ideal(R, [x[1]*x[6] - x[2]*x[5] + x[3]*x[4]]);
-
-julia> GRASSMANNIAN = variety(I);  
-
-julia> Omega = canonical_bundle(GRASSMANNIAN)
-Graded subquotient of submodule of R^1 generated by
-1 -> e[1]
-by submodule of R^1 generated by
-1 -> (x[1]*x[6] - x[2]*x[5] + x[3]*x[4])*e[1]
-
-julia> degrees_of_generators(Omega)
-1-element Vector{FinGenAbGroupElem}:
- [4]
julia> R, (x, y, z) = graded_polynomial_ring(QQ,[:x, :y, :z]);
-
-julia> I = ideal(R, [y^2*z + x*y*z - x^3 - x*z^2 - z^3]);
-
-julia> ELLCurve = variety(I);
-
-julia> Omega = canonical_bundle(ELLCurve)
-Graded subquotient of submodule of R^1 generated by
-1 -> e[1]
-by submodule of R^1 generated by
-1 -> (x^3 - x*y*z + x*z^2 - y^2*z + z^3)*e[1]
-
-julia> degrees_of_generators(Omega)
-1-element Vector{FinGenAbGroupElem}:
- [0]
julia> X = bordiga()
-Projective variety
-  in projective 4-space over GF(31991) with coordinates [x, y, z, u, v]
-defined by ideal with 4 generators
-
-julia> dim(X)
-2
-
-julia> codim(X)
-2
-
-julia> Omega = canonical_bundle(X);
-
-julia> typeof(Omega)
-SubquoModule{MPolyDecRingElem{fpFieldElem, fpMPolyRingElem}}
source
diff --git a/previews/PR4245/AlgebraicGeometry/Curves/AffinePlaneCurves/index.html b/previews/PR4245/AlgebraicGeometry/Curves/AffinePlaneCurves/index.html deleted file mode 100644 index 3b78f58c4fdc..000000000000 --- a/previews/PR4245/AlgebraicGeometry/Curves/AffinePlaneCurves/index.html +++ /dev/null @@ -1,82 +0,0 @@ - -Affine plane curves · Oscar.jl

Affine plane curves

AffinePlaneCurveType
AffinePlaneCurve{BaseField<:Field, RingType<:Ring} <: AbsAffineCurve{BaseField, RingType}

Type for reduced affine plane curves.

Examples

julia> R, (x, y) = polynomial_ring(QQ, [:x, :y]);
-
-julia> F = y^3*x^6 - y^6*x^2;
-
-julia> C = plane_curve(F)
-Affine plane curve
-  defined by 0 = x^5*y - x*y^4
-
source
defining_equationMethod
defining_equation(C::AffinePlaneCurve)

Return the defining equation of C.

source
defining_equation(C::ProjectivePlaneCurve)

Return the defining equation of the (reduced) plane curve C.

source
common_componentsMethod
common_components(C::AffinePlaneCurve, D::AffinePlaneCurve)

Return the affine plane curve consisting of the common components of C and D, or an empty vector if they do not have a common component. This component can be reducible.

Examples

julia> R, (x, y) = polynomial_ring(QQ, [:x, :y]);
-
-julia> C = plane_curve(x*(x+y)*(x^2 + x + 1));
-
-julia> D = plane_curve(x*(x+y)*(x-y));
-
-julia> common_components(C, D)
-1-element Vector{AffinePlaneCurve{QQField, MPolyQuoRing{QQMPolyRingElem}}}:
- scheme(x^2 + x*y)
-
source
multiplicityMethod
multiplicity(C::AffinePlaneCurve, P::AbsAffineRationalPoint)

Return the multiplicity of C at P.

Examples

julia> R, (x, y) = polynomial_ring(QQ, [:x, :y]);
-
-julia> C = plane_curve(x^2*(x+y)*(y^3-x^2));
-
-julia> P = C([2,-2])
-Rational point
-  of scheme(-x^4 - x^3*y + x^2*y^3 + x*y^4)
-with coordinates (2, -2)
-
-julia> multiplicity(C, P)
-1
-
source
tangent_linesMethod
tangent_lines(C::AffinePlaneCurve, P::AbsAffineRationalPoint)

Return the tangent lines at P to C with their multiplicity.

Examples

julia> R, (x, y) = polynomial_ring(QQ, [:x, :y]);
-
-julia> C = plane_curve(x^2*(x+y)*(y^3-x^2));
-
-julia> P = C([0, 0])
-Rational point
-  of scheme(-x^4 - x^3*y + x^2*y^3 + x*y^4)
-with coordinates (0, 0)
-
-julia> tangent_lines(C, P)
-Dict{AffinePlaneCurve{QQField, MPolyQuoRing{QQMPolyRingElem}}, Int64} with 2 entries:
-  scheme(x)     => 3
-  scheme(x + y) => 1
-
source
intersection_multiplicityMethod
intersection_multiplicity(C::AffinePlaneCurve, D::AffinePlaneCurve, P::AbsAffineRationalPoint)

Return the intersection multiplicity of C and D at P.

Examples

julia> R, (x, y) = polynomial_ring(QQ, [:x, :y]);
-
-julia> C = plane_curve((x^2+y^2)*(x^2 + y^2 + 2*y))
-Affine plane curve
-  defined by 0 = x^4 + 2*x^2*y^2 + 2*x^2*y + y^4 + 2*y^3
-
-julia> D = plane_curve((x^2+y^2)*(y^3*x^6 - y^6*x^2))
-Affine plane curve
-  defined by 0 = x^7*y + x^5*y^3 - x^3*y^4 - x*y^6
-
-julia> Q = D([0, -2]);
-
-julia> intersection_multiplicity(C, D, Q)
-1
-
source
is_transverse_intersectionMethod
is_transverse_intersection(C::AffinePlaneCurve, D::AffinePlaneCurve, P::AbsAffineRationalPoint)

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 = plane_curve(x*(x+y))
-Affine plane curve
-  defined by 0 = x^2 + x*y
-
-julia> D = plane_curve((x-y)*(x-2))
-Affine plane curve
-  defined by 0 = x^2 - x*y - 2*x + 2*y
-
-julia> P = C([QQ(0), QQ(0)])
-Rational point
-  of scheme(x^2 + x*y)
-with coordinates (0, 0)
-
-julia> Q = C([QQ(2), QQ(-2)])
-Rational point
-  of scheme(x^2 + x*y)
-with coordinates (2, -2)
-
-julia> is_transverse_intersection(C, D, P)
-false
-
-julia> is_transverse_intersection(C, D, Q)
-true
-
source
projective_closureMethod
projective_closure(C::AffinePlaneCurve) -> ProjectivePlaneCurve

Return the projective closure of C.

source
diff --git a/previews/PR4245/AlgebraicGeometry/Curves/ParametrizationPlaneCurves/index.html b/previews/PR4245/AlgebraicGeometry/Curves/ParametrizationPlaneCurves/index.html deleted file mode 100644 index 3b2e98eda325..000000000000 --- a/previews/PR4245/AlgebraicGeometry/Curves/ParametrizationPlaneCurves/index.html +++ /dev/null @@ -1,59 +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 [Bhm99] and [BDLP17] for details and further references.

Adjoint Ideals of Plane Curves

adjoint_idealMethod
adjoint_ideal(C::ProjectivePlaneCurve{QQField})

Return the Gorenstein adjoint ideal of C.

Examples

julia> R, (x,y,z) = graded_polynomial_ring(QQ, [:x, :y, :z]);
-
-julia> C = ProjectivePlaneCurve(y^4-2*x^3*z+3*x^2*z^2-2*y^2*z^2)
-Projective plane curve
-  defined by 0 = 2*x^3*z - 3*x^2*z^2 - y^4 + 2*y^2*z^2
-
-julia> I = adjoint_ideal(C)
-Ideal generated by
-  -x*z + y^2
-  x*y - y*z
-  x^2 - x*z
-
source

Rational Points on Conics

rational_point_conicMethod
rational_point_conic(D::ProjectivePlaneCurve{QQField})

If the plane 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> C = ProjectivePlaneCurve(y^4-2*x^3*z+3*x^2*z^2-2*y^2*z^2)
-Projective plane curve
-  defined by 0 = 2*x^3*z - 3*x^2*z^2 - y^4 + 2*y^2*z^2
-
-julia> I = adjoint_ideal(C)
-Ideal generated by
-  -x*z + y^2
-  x*y - y*z
-  x^2 - x*z
-
-julia> R, (x,y,z) = graded_polynomial_ring(QQ, [:x, :y, :z]);
-
-julia> D = ProjectivePlaneCurve(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{AbsSimpleNumFieldElem}}:
- -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

parametrizationMethod
parametrization(C::ProjectivePlaneCurve{QQField})

Return a rational parametrization of C.

Examples

julia> R, (x,y,z) = graded_polynomial_ring(QQ, [:x, :y, :z]);
-
-julia> C = ProjectivePlaneCurve(y^4-2*x^3*z+3*x^2*z^2-2*y^2*z^2)
-Projective plane curve
-  defined by 0 = 2*x^3*z - 3*x^2*z^2 - y^4 + 2*y^2*z^2
-
-julia> parametrization(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/PR4245/AlgebraicGeometry/Curves/ProjectiveCurves/index.html b/previews/PR4245/AlgebraicGeometry/Curves/ProjectiveCurves/index.html deleted file mode 100644 index f1755236de79..000000000000 --- a/previews/PR4245/AlgebraicGeometry/Curves/ProjectiveCurves/index.html +++ /dev/null @@ -1,28 +0,0 @@ - -Projective Curves · Oscar.jl

Projective Curves

ProjectiveCurveType
ProjectiveCurve

A reduced projective curve, defined as the vanishing locus of a homogeneous (but not necessarily radical) ideal.

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 = projective_curve(I)
-Projective curve
-  in projective 3-space over QQ with coordinates [w, x, y, z]
-defined by ideal (w*y - x^2, w*z - x*y, x*z - y^2)
-
source
invert_birational_mapFunction
invert_birational_map(phi::Vector{T}, C::ProjectiveCurve) 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
invert_birational_map(phi::Vector{T}, C::ProjectivePlaneCurve) 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 plane 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
geometric_genusFunction
geometric_genus(X::AbsProjectiveScheme{<:Field}; algorithm::Symbol=:default) -> Int

Given a projective curve X return the genus of X, i.e. the integer $p_g = p_a - \delta$ where $p_a$ is the arithmetic genus and \delta the $\delta$-invariant of the curve.

The algorithm keyword can be specified to

  • :normalization to compute $\delta$ a normalization
  • :primary_decomposition to proceed with a primary decomposition

Normalization is usually slower, but not always.

Examples

julia> R, (x,y,z) = graded_polynomial_ring(QQ, [:x, :y, :z]);
-
-julia> C = plane_curve(z*x^2-y^3)
-Projective plane curve
-  defined by 0 = x^2*z - y^3
-
-julia> geometric_genus(C)
-0
-
source
diff --git a/previews/PR4245/AlgebraicGeometry/Curves/ProjectivePlaneCurves/index.html b/previews/PR4245/AlgebraicGeometry/Curves/ProjectivePlaneCurves/index.html deleted file mode 100644 index 191a134a486f..000000000000 --- a/previews/PR4245/AlgebraicGeometry/Curves/ProjectivePlaneCurves/index.html +++ /dev/null @@ -1,7 +0,0 @@ - -Projective Plane Curves · Oscar.jl

Projective Plane Curves

ProjectivePlaneCurveType
ProjectivePlaneCurve <: AbsProjectiveCurve

A reduced curve in the projective plane.

Examples

julia> R, (x,y,z) = graded_polynomial_ring(QQ, [:x, :y, :z]);
-
-julia> C = plane_curve(y^3*x^6 - y^6*x^2*z)
-Projective plane curve
-  defined by 0 = x^5*y - x*y^4*z
-
source

Projective plane curves are modeled in Oscar as projective algebraic sets. See AbsProjectiveAlgebraicSet(@ref). In addition to the methods for algebraic sets and curves the following methods special to plane curves are available.

defining_equationMethod
defining_equation(C::AffinePlaneCurve)

Return the defining equation of C.

source
defining_equation(C::ProjectivePlaneCurve)

Return the defining equation of the (reduced) plane curve C.

source
degreeMethod
degree(C::ProjectivePlaneCurve)

Return the degree of the defining polynomial of C.

source
common_componentsMethod
common_components(C::S, D::S) where {S<:ProjectivePlaneCurve}

Return the projective plane curve consisting of the common components of C and D, or an empty vector if they do not have a common component.

source
multiplicityMethod
multiplicity(C::ProjectivePlaneCurve{S}, P::AbsProjectiveRationalPoint)

Return the multiplicity of C at P.

source
tangent_linesMethod
tangent_lines(C::ProjectivePlaneCurve{S}, P::AbsProjectiveRationalPoint) where S <: FieldElem

Return the tangent lines at P to C with their multiplicity.

source
intersection_multiplicityMethod
intersection_multiplicity(C::S, D::S, P::AbsProjectiveRationalPoint) where S <: ProjectivePlaneCurve

Return the intersection multiplicity of C and D at P.

source
is_transverse_intersectionMethod
is_transverse_intersection(C::S, D::S, P::AbsProjectiveRationalPoint) where S <: ProjectivePlaneCurve

Return true if C and D intersect transversally at P and false otherwise.

source
diff --git a/previews/PR4245/AlgebraicGeometry/FrameWorks/ArchitectureOfAffineSchemes/index.html b/previews/PR4245/AlgebraicGeometry/FrameWorks/ArchitectureOfAffineSchemes/index.html deleted file mode 100644 index 188d6bbe0b2a..000000000000 --- a/previews/PR4245/AlgebraicGeometry/FrameWorks/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 AbsAffineScheme 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

AbsAffineSchemeType
AbsAffineScheme{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::AbsAffineScheme),
  • OO(X::AbsAffineScheme).

A concrete instance of this type is

AffineSchemeType
AffineScheme{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 MyAffineScheme<:AbsAffineScheme 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 AffineScheme in MyAffineScheme and implement the methods

underlying_scheme(X::MyAffineScheme)::AffineScheme # return Y as above

Then all methods implemented for AffineScheme are automatically forwarded to any instance of MyAffineScheme.

Note: The above method necessarily returns an instance of AffineScheme! Of course, it can be overwritten for any higher type MyAffineScheme<:AbsAffineScheme 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:

AbsAffineSchemeMorType
AbsAffineSchemeMor{DomainType<:AbsAffineScheme,
-           CodomainType<:AbsAffineScheme,
-           PullbackType<: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 AffineSchemeMor:

AffineSchemeMorType
AffineSchemeMor{DomainType<:AbsAffineScheme,
-        CodomainType<:AbsAffineScheme,
-        PullbackType<: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::AbsAffineSchemeMor, g::AbsAffineSchemeMor),
  • identity_map(X::AbsAffineScheme),
  • restrict(f::AbsAffineSchemeMor, X::AbsAffineScheme, Y::AbsAffineScheme; check::Bool=true),
  • ==(f::AbsAffineSchemeMor, g::AbsAffineSchemeMor),
  • preimage(f::AbsAffineSchemeMor, Z::AbsAffineScheme).

In particular, for every concrete instance of a type MyAffineScheme<:AbsAffineScheme that implements underlying_scheme, this basic functionality of AffineSchemeMor should run naturally.

We may derive higher types of morphisms of affine schemes MyAffineSchemeMor<:AbsAffineSchemeMor by storing an instance g of AffineSchemeMor inside an instance f of MyAffineSchemeMor and implementing

underlying_morphism(f::MyAffineSchemeMor)::AffineSchemeMor # return g

For example, this allows us to define closed embeddings.

diff --git a/previews/PR4245/AlgebraicGeometry/Miscellaneous/miscellaneous/index.html b/previews/PR4245/AlgebraicGeometry/Miscellaneous/miscellaneous/index.html deleted file mode 100644 index e37ce6cccf4c..000000000000 --- a/previews/PR4245/AlgebraicGeometry/Miscellaneous/miscellaneous/index.html +++ /dev/null @@ -1,30 +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

flag_pluecker_idealFunction
flag_pluecker_ideal(F::Union{Field, MPolyRing}, dimensions::Vector{Int}, n::Int; minimal::Bool=true)

Returns the generators of the defining ideal for the complete flag variety $\text{Fl}(\mathbb{F}, (d_1,\dots,d_k), n)$, where $(d_1,\dots,d_k) =$dimensions, with $d_j\leq n-1$, denotes the rank. That is, the vanishing set of this ideal corresponds to the space of $k$-step flags of linear subspaces $V_1\subset\dots\subset V_k$ in $\mathbb{F}^n$, where $\text{dim}(V_j) = d_{j}$. You can obtain the generators for the complete flag variety of $\mathbb{F}^{n}$ by taking dimensions $=(1,\dots,n-1)$ and n$=n$. We remark that evaluating for F = QQ yields the same set of generators as any field of characteristic $0$.

The first parameter can either be $\mathbb{F}$, or a polynomial ring over $\mathbb{F}$, with $\sum^{k}_{j=1}{n\choose d_j}$ variables. The parameter dimensions needs to be a vector of distinct increasing entries. Evaluating this function with the parameter minimal = true returns the reduced Gröbner basis for the flag Plücker ideal with respect to the degree reverse lexicographical order. For more details, see Theorem 14.6 [MS05]

Examples

Complete flag variety $\text{Fl}(\mathbb{Q}, (1,2,3), 4)$.

julia> flag_pluecker_ideal(QQ,[1,2,3],4)
-Ideal generated by
-  x[[2, 4]]*x[[1, 2, 3]] - x[[2, 3]]*x[[1, 2, 4]] + x[[1, 2]]*x[[2, 3, 4]]
-  x[[1, 4]]*x[[1, 2, 3]] - x[[1, 3]]*x[[1, 2, 4]] + x[[1, 2]]*x[[1, 3, 4]]
-  -x[[3, 4]]*x[[1, 2, 3]] - x[[1, 3]]*x[[2, 3, 4]] + x[[2, 3]]*x[[1, 3, 4]]
-  -x[[1, 4]]*x[[2, 3, 4]] + x[[2, 4]]*x[[1, 3, 4]] - x[[3, 4]]*x[[1, 2, 4]]
-  -x[[1]]*x[[2, 3, 4]] + x[[2]]*x[[1, 3, 4]] - x[[3]]*x[[1, 2, 4]] + x[[4]]*x[[1, 2, 3]]
-  -x[[1, 4]]*x[[2, 3]] + x[[2, 4]]*x[[1, 3]] - x[[3, 4]]*x[[1, 2]]
-  -x[[1]]*x[[2, 3]] + x[[2]]*x[[1, 3]] - x[[3]]*x[[1, 2]]
-  -x[[2]]*x[[3, 4]] + x[[3]]*x[[2, 4]] - x[[4]]*x[[2, 3]]
-  -x[[1]]*x[[3, 4]] + x[[3]]*x[[1, 4]] - x[[4]]*x[[1, 3]]
-  -x[[1]]*x[[2, 4]] + x[[2]]*x[[1, 4]] - x[[4]]*x[[1, 2]]
-

Flag variety $\text{Fl}(\mathbb{Q},(1,3),4)$.

julia> flag_pluecker_ideal(QQ,[1,3],4)
-Ideal generated by
-  -x[[1]]*x[[2, 3, 4]] + x[[2]]*x[[1, 3, 4]] - x[[3]]*x[[1, 2, 4]] + x[[4]]*x[[1, 2, 3]]

An example with a custom ring as input.

julia> R, _ = polynomial_ring(QQ, 8)
-(Multivariate polynomial ring in 8 variables over QQ, QQMPolyRingElem[x1, x2, x3, x4, x5, x6, x7, x8])
-
-julia> flag_pluecker_ideal(R, [1,3], 4; minimal=false)
-Ideal generated by
-  x1*x6 - x2*x5 + x3*x7 - x4*x8
source
grassmann_pluecker_idealFunction
grassmann_pluecker_ideal([ring::MPolyRing,] subspace_dimension::Int, ambient_dimension::Int)

Given a (possibly graded) ring, an ambient dimension $n$ and a subspace dimension $d$, return the ideal in the ring generated by the Plücker relations. If the input ring is not graded, return the ideal in the ring with the standard grading. If the ring is not specified return the ideal in a multivariate polynomial ring over the rationals with variables indexed by elements of ${[n]\choose d}$ with the standard grading.

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 [Stu93].

Examples

julia> grassmann_pluecker_ideal(2, 4)
-Ideal generated by
-  x[[1, 2]]*x[[3, 4]] - x[[1, 3]]*x[[2, 4]] + x[[1, 4]]*x[[2, 3]]
-
-julia> R, x = polynomial_ring(residue_ring(ZZ, 7)[1], :x => (1:2, 1:3))
-(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 generated by
-  x[1, 1]*x[2, 3] + 6*x[2, 1]*x[1, 3] + x[1, 2]*x[2, 2]
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/PR4245/AlgebraicGeometry/Schemes/AffineSchemes/index.html b/previews/PR4245/AlgebraicGeometry/Schemes/AffineSchemes/index.html deleted file mode 100644 index 3a024cd80569..000000000000 --- a/previews/PR4245/AlgebraicGeometry/Schemes/AffineSchemes/index.html +++ /dev/null @@ -1,522 +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)

Construct 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 x, y
-      over rational field
-    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 x, y
-      over rational field
-    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 in 2 variables x, y
-        over rational field
-      by ideal (x)
-    at complement of prime ideal (y)
source

See inclusion_morphism(::AbsAffineScheme, ::AbsAffineScheme) 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::VarName="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 x1, x2 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_names::AbstractVector{<:VarName}) where {BRT<:Ring}

Create 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, [:x, :y, :z])
-Affine space of dimension 3
-  over rational field
-with coordinates [x, y, z]
-
-julia> affine_space(QQ, ['x', 'y', 'z'])
-Affine space of dimension 3
-  over rational field
-with coordinates [x, y, z]
-
-julia> affine_space(QQ, ["x", "y", "z"])
-Affine space of dimension 3
-  over rational field
-with coordinates [x, y, z]
source

Closed subschemes

subschemeMethod
subscheme(X::AbsAffineScheme, 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 x1, x2, x3
-      over rational field
-    by ideal (x1)
-
-julia> subscheme(X,[x1,x2])
-Spectrum
-  of quotient
-    of multivariate polynomial ring in 3 variables x1, x2, x3
-      over rational field
-    by ideal (x1, x2)
source
subschemeMethod
subscheme(X::AbsAffineScheme, 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 x1, x2, x3
-      over rational field
-    by ideal (x1*x2)
source

Intersections

intersectMethod
Base.intersect(X::AbsAffineScheme, Y::AbsAffineScheme)

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 x1, x2, x3
-      over rational field
-    by ideal (x1)
-
-julia> Y2 = subscheme(X,[x2])
-Spectrum
-  of quotient
-    of multivariate polynomial ring in 3 variables x1, x2, x3
-      over rational field
-    by ideal (x2)
-
-julia> intersect(Y1, Y2)
-Spectrum
-  of quotient
-    of multivariate polynomial ring in 3 variables x1, x2, x3
-      over rational field
-    by ideal (x1, x2)
source

Open subschemes

hypersurface_complementMethod
hypersurface_complement(X::AbsAffineScheme, 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 x1, x2, x3
-      over rational field
-    at products of (x1)
source
hypersurface_complementMethod
hypersurface_complement(X::AbsAffineScheme, 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 x1, x2, x3
-      over rational field
-    at products of (x1, x2)
source

Closure

closureMethod
closure(X::AbsAffineScheme, Y::AbsAffineScheme)

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 x1, x2, x3
-      over rational field
-    by ideal (x1)
-
-julia> closure(H, X)
-Spectrum
-  of quotient
-    of multivariate polynomial ring in 3 variables x1, x2, x3
-      over rational field
-    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::AbsAffineScheme)

Return the ambient affine space of $X$.

Use ambient_embedding(::AbsAffineScheme) 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 x, y
-      over rational field
-    by ideal (x)
-
-julia> X == ambient_space(Y)
-true
-
-julia> Z = subscheme(Y, y)
-Spectrum
-  of quotient
-    of multivariate polynomial ring in 2 variables x, y
-      over rational field
-    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 in 2 variables x, y
-        over rational field
-      by ideal (x)
-    at products of (y)
-
-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 generated by
-  x
-
-julia> RmodI, quotient_map = quo(P, I);
-
-julia> Y = spec(RmodI)
-Spectrum
-  of quotient
-    of multivariate polynomial ring in 2 variables x, y
-      over rational field
-    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 x, y
-      over rational field
-    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 in 2 variables x, y
-        over rational field
-      by ideal (x)
-    at products of (y)
-
-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(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$.

source
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 generated by
-  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::AbsAffineScheme)

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
codimMethod
codim(X::AbsAffineScheme)

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 x1, x2, x3
-      over rational field
-    by ideal (x1)
-
-julia> codim(Y)
-1
source
ambient_embeddingMethod
ambient_embedding(X::AbsAffineScheme)

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 x, y
-      over rational field
-    by ideal (x)
-
-julia> inc = ambient_embedding(Y)
-Affine scheme morphism
-  from [x, y]  scheme(x)
-  to   [x, y]  affine 2-space over QQ
-given by the pullback function
-  x -> x
-  y -> y
-
-julia> inc == inclusion_morphism(Y, X)
-true
source
dimMethod
dim(X::AbsAffineScheme)

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::AbsAffineScheme)

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::AbsAffineScheme)

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::AbsAffineScheme, Y::AbsAffineScheme)

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 x1, x2, x3
-      over rational field
-    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 x1, x2, x3
-      over rational field
-    at products of (x1)
-
-julia> is_open_embedding(Z, X)
-true
source
is_closed_embeddingMethod
is_closed_embedding(X::AbsAffineScheme, Y::AbsAffineScheme)

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 x1, x2, x3
-      over rational field
-    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 x1, x2, x3
-      over rational field
-    at products of (x1)
-
-julia> is_closed_embedding(Z, X)
-false
source
isemptyMethod
is_empty(X::AbsAffineScheme)

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
is_subschemeMethod
is_subscheme(X::AbsAffineScheme, Y::AbsAffineScheme)

Check whether $X$ is a subset of $Y$ based on the comparison of their coordinate rings. See inclusion_morphism(::AbsAffineScheme, ::AbsAffineScheme) 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 x1, x2, x3
-      over rational field
-    by ideal (x1*x2)
-
-julia> is_subscheme(X, Y)
-false
-
-julia> is_subscheme(Y, X)
-true
source

Methods

is_normalMethod
is_normal(X::AbsAffineScheme; check::Bool=true) -> Bool

Input:

  • a reduced scheme $X$,
  • if check is true, then confirm that $X$ is reduced; this is expensive.

Output:

Returns whether the scheme $X$ is normal.

Examples

julia> R, (x, y, z) = QQ[:x, :y, :z];
-
-julia> X = spec(R);
-
-julia> is_normal(X)
-true
source
normalizationMethod
normalization(X::AbsAffineScheme) -> Vector{Tuple{AbsAffineScheme, AbsAffineSchemeMor}}

Return the normalization of the reduced affine scheme $X$.

Input:

  • A reduced affine scheme $X$
  • if check is true confirm that $X$ is reduced; this is expensive
  • the keyword argument algorithm is passed on to normalization(::MPolyQuoRing)

Output:

A list of pairs $(Y_i, f_i)$ where $Y_i$ is a normal scheme and $f_i$ is a morphism from $Y_i$ to $X$. The disjoint union of the $Y_i$ is the normalization of $X$ and the $f_i$ are the restrictions of the normalization morphism to $Y_i$.

source

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::AbsAffineScheme)

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/PR4245/AlgebraicGeometry/Schemes/CoveredSchemeMorphisms/index.html b/previews/PR4245/AlgebraicGeometry/Schemes/CoveredSchemeMorphisms/index.html deleted file mode 100644 index 0ddc9bc9d73d..000000000000 --- a/previews/PR4245/AlgebraicGeometry/Schemes/CoveredSchemeMorphisms/index.html +++ /dev/null @@ -1,60 +0,0 @@ - -Morphisms of covered schemes · Oscar.jl

Morphisms of covered schemes

Suppose $f : X \to Y$ is a morphism of AbsCoveredSchemes. Theoretically, and hence also technically, the required information behind $f$ is a list of morphisms of affine schemes $f_i : U_i \to V_{F(i)}$ for some pair of Coverings $\left\{U_i\right\}_{i \in I}$ of $X$ and $\left\{V_j\right\}_{j \in J}$ of $Y$ and a map of indices $F : I \to J$ This information is held by a CoveringMorphism:

CoveringMorphismType
CoveringMorphism

A morphism $f : C → D$ of two coverings. For every patch $U$ of $C$ this provides a map f[U'] of type AffineSchemeMorType from $U' ⊂ U$ to some patch codomain(f[U]) in D for some affine patches $U'$ covering $U$.

Note: For two affine patches $U₁, U₂ ⊂ U$ the codomains of f[U₁] and f[U₂] do not need to coincide! However, given the gluings in C and D, all affine maps have to coincide on their overlaps.

source

The basic functionality of CoveringMorphisms comprises domain and codomain which both return a Covering, together with

getindex(f::CoveringMorphism, U::AbsAffineScheme)

which for $U = U_i$ returns the AbsAffineSchemeMor $f_i : U_i \to V_{F(i)}$.

Note that, in general, neither the domain nor the codomain of the covering_morphism of f : X \to Y need to coincide with the default_covering of $X$, respectively $Y$. In fact, one will usually need to restrict to a refinement of the default_covering of $X$ in order to realize the covering morphism in the first place.

The interface for morphisms of covered schemes

Every AbsCoveredSchemeMorphism $f : X \to Y$ is required to implement the following minimal interface.

domain(f::AbsCoveredSchemeMorphism)                 # returns X
-codomain(f::AbsCoveredSchemeMorphism)               # returns Y
-covering_morphism(f::AbsCoveredSchemeMorphism)      # returns the underlying covering morphism {f_i}

For the user's convenience, also the domain and codomain of the underlying covering_morphism are forwarded as domain_covering and codomain_covering, respectively, together with getindex(phi::CoveringMorphism, U::AbsAffineScheme) as getindex(f::AbsCoveredSchemeMorphism, U::AbsAffineScheme).

The minimal concrete type of an AbsCoveredSchemeMorphism which implements this interface, is CoveredSchemeMorphism.

Special types of morphisms of covered schemes

Closed embeddings

CoveredClosedEmbeddingType
CoveredClosedEmbedding <: AbsCoveredSchemeMorphism

Type for closed embeddings of covered schemes.

In addition to the closed embedding it stores the sheaf of ideals defining the image.

source
image_idealMethod
image_ideal(phi::CoveredClosedEmbedding)

For a closed embedding $\phi \colon X \to Y$ return the sheaf of ideals on $Y$ defining the image of $\phi$.

source

Composite morphisms

CompositeCoveredSchemeMorphismType
CompositeCoveredSchemeMorphism{
-    DomainType<:AbsCoveredScheme,
-    CodomainType<:AbsCoveredScheme,
-    BaseMorphismType
-   } <: AbsCoveredSchemeMorphism{
-                             DomainType,
-                             CodomainType,
-                             BaseMorphismType,
-                             CoveredSchemeMorphism
-                            }

A special concrete type of an AbsCoveredSchemeMorphism of the form $f = hᵣ ∘ hᵣ₋₁ ∘ … ∘ h₁: X → Y$ for arbitrary AbsCoveredSchemeMorphisms $h₁ : X → Z₁$, $h₂ : Z₁ → Z₂$, ..., $hᵣ : Zᵣ₋₁ → Y$.

Since every such morphism $hⱼ$ will in general have an underlying CoveringMorphism with domain and codomain covering actual composition of such a sequence of morphisms will lead to an exponential increase in complexity of these coverings because of the necessary refinements. Nevertheless, the pullback or pushforward of various objects on either $X$ or $Y$ through such a chain of maps is possible stepwise. This type allows one to have one concrete morphism rather than a list of morphisms and to reroute such calculations to iteration over the various maps.

In addition to the usual functionality of the AbsCoveredSchemeMorphism interface, this concrete type has the getters

maps(f::CompositeCoveredSchemeMorphism)

to obtain a list of the $hⱼ$ and map(f, j) to obtain the j-th map directly.

source

Morphisms from rational functions

Suppose $X$ and $Y$ are two irreducible and reduced varieties. Then a morphism $f : X \to Y$ might be given by means of the following data. Let $V \subset Y$ be some dense affine patch with coordinates $x_1,\dots,x_n$ (i.e. the gens of OO(V)).

These $x_i$ extend to rational functions $v_i$ on $Y$ and these pull back to rational functions $f^* v_i = u_i$ on $X$. On every affine patch $U \subset X$ there now exists some maximal Zariski-open subset $W \subset U$ (which need not be affine), such that all the $f^* v_i$ extend to regular functions on $W$. Hence, one can realize the morphisms of affine schemes $f_j : W_j \to V$ for some open covering of $W$.

Similarly, for every other non-empty patch $V_2$ of $Y$ the pullback of gens(OO(V_2)) can be computed from the $f^* v_i$ and extended maximally to some $W \subset U$ for every patch $U$ of $X$. Altogether, this allows to compute a full CoveringMorphism and – at least in theory – an instance of CoveredSchemeMorphism. In practice, however, this computation is usually much too expensive to really be carried out, while the data necessary to compute various pullbacks and/or pushforwards of objects defined on $X$ and $Y$ can be extracted from the $f^* v_i$ more directly.

A lazy concrete data structure to house this kind of morphism is

MorphismFromRationalFunctionsType
MorphismFromRationalFunctions{DomainType<:AbsCoveredScheme, CodomainType<:AbsCoveredScheme}

A lazy type for a dominant morphism $φ : X → Y$ of AbsCoveredSchemes which is given by a set of rational functions $a₁,…,aₙ$ in the fraction field of the base_ring of $𝒪(U)$ for one of the dense open affine_charts $U$ of $X$. The $aᵢ$ represent the pullbacks of the coordinates (gens) of some affine_chart $V$ of the codomain $Y$ under this map.

julia> IP1 = covered_scheme(projective_space(QQ, [:s, :t]))
-Scheme
-  over rational field
-with default covering
-  described by patches
-    1: affine 1-space
-    2: affine 1-space
-  in the coordinate(s)
-    1: [(t//s)]
-    2: [(s//t)]
-
-julia> IP2 = projective_space(QQ, [:x, :y, :z]);
-
-julia> S = homogeneous_coordinate_ring(IP2);
-
-julia> x, y, z = gens(S);
-
-julia> IPC, inc_IPC = sub(IP2, ideal(S, [x^2 - y*z]));
-
-julia> C = covered_scheme(IPC);
-
-julia> U = first(affine_charts(IP1))
-Spectrum
-  of multivariate polynomial ring in 1 variable (t//s)
-    over rational field
-
-julia> V = first(affine_charts(C))
-Spectrum
-  of quotient
-    of multivariate polynomial ring in 2 variables (y//x), (z//x)
-      over rational field
-    by ideal (-(y//x)*(z//x) + 1)
-
-julia> t = first(gens(OO(U)))
-(t//s)
-
-julia> Phi = MorphismFromRationalFunctions(IP1, C, U, V, [t//one(t), 1//t]);
-
-julia> realizations = Oscar.realize_on_patch(Phi, U);
-
-julia> realizations[3]
-Affine scheme morphism
-  from [(t//s)]          AA^1
-  to   [(x//z), (y//z)]  scheme((x//z)^2 - (y//z))
-given by the pullback function
-  (x//z) -> (t//s)
-  (y//z) -> (t//s)^2
-
source

Note that the key idea of this data type is to not use the underlying_morphism together with its covering_morphism, but to find cheaper ways to do computations! The computation of the underlying_morphism is triggered by any call to functions which have not been overwritten with a special method for f::MorphismFromRationalFunctions. However, this computation should be considered as way too expensive besides some small examples.

For instance, if one wants to pull back a prime ideal sheaf $\mathcal I$ on $Y$ along some isomorphism $f : X \to Y$, then one only needs to find one realization $f_j : U_j \to V_{F(j)}$ of $f$ on affine patches $U_j$ of $X$ and $V_{F(j)}$ of $Y$ such that $\mathcal I(V_{F(j)})\neq 0$ and $f_j^* \mathcal I(V_{F(j)}) \neq 0$. Then $f^* \mathcal I$ can be extended uniquely to all of $X$ from $U_j$ and there is no need to realize the full covering_morphism of $f$. In order to facilitate such computations as lazy as possible, there are various fine-grained entry points and caching mechanisms to realize $f$ on open subsets:

realize_on_patchMethod
realize_on_patch(Phi::MorphismFromRationalFunctions, U::AbsAffineScheme)

For $U$ in the domain_covering of Phi construct a list of morphisms $fₖ : U'ₖ → Vₖ$ from PrincipalOpenSubsets $U'ₖ$ of $U$ to patches $Vₖ$ in the codomain_covering so that altogether the fₖ can be assembled to a CoveringMorphism which realizes Phi.

source
realize_on_open_subsetMethod
realize_on_open_subset(Phi::MorphismFromRationalFunctions, U::AbsAffineScheme, V::AbsAffineScheme)

Return a morphism f : U' → V from some PrincipalOpenSubset of U to V such that the restriction of Phi to U' is f. Note that U' need not be maximal with this property!

source
realization_previewMethod
realization_preview(Phi::MorphismFromRationalFunctions, U::AbsAffineScheme, V::AbsAffineScheme)

For a pair (U, V) of patches in the domain_covering and the codomain_covering of Phi, respectively, this returns a list of elements in the fraction field of the ambient_coordinate_ring of U which represent the pullbacks of gens(OO(V)) under Phi to U.

source
random_realizationMethod
random_realization(Phi::MorphismFromRationalFunctions, U::AbsAffineScheme, V::AbsAffineScheme)

For a pair (U, V) of patches in the domain_covering and the codomain_covering of Phi, respectively, this creates a random PrincipalOpenSubset U' on which the restriction f : U' → V of Phi can be realized and returns that restriction. Note that U' need not (and usually will not) be maximal with this property.

source
cheap_realizationMethod
cheap_realization(Phi::MorphismFromRationalFunctions, U::AbsAffineScheme, V::AbsAffineScheme)

For a pair (U, V) of patches in the domain_covering and the codomain_covering of Phi, respectively, this creates a random PrincipalOpenSubset U' on which the restriction f : U' → V of Phi can be realized and returns that restriction. Note that U' need not (and usually will not) be maximal with this property.

This method is cheap in the sense that it simply inverts all representatives of the denominators occurring in the realization_preview(Phi, U, V).

source
realize_maximally_on_open_subsetMethod
realize_maximally_on_open_subset(Phi::MorphismFromRationalFunctions, U::AbsAffineScheme, V::AbsAffineScheme)

For a pair (U, V) of patches in the domain_covering and the codomain_covering of Phi, respectively, this returns a list of morphisms fₖ : U'ₖ → V such that the restriction of Phi to U'ₖ and V is fₖ and altogether the U'ₖ cover the maximal open subset U'⊂ U on which the restriction U' → V of Phi can be realized.

source
realizeMethod
realize(Phi::MorphismFromRationalFunctions)

Computes a full realization of Phi as a CoveredSchemeMorphism. Note that this computation is very expensive and usage of this method should be avoided.

source
diff --git a/previews/PR4245/AlgebraicGeometry/Schemes/CoveredSchemes/index.html b/previews/PR4245/AlgebraicGeometry/Schemes/CoveredSchemes/index.html deleted file mode 100644 index 7b9f71ac6356..000000000000 --- a/previews/PR4245/AlgebraicGeometry/Schemes/CoveredSchemes/index.html +++ /dev/null @@ -1,254 +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}

A scheme $X$ over some base_ring $𝕜$ of type BaseRingType, given by means of affine charts and their gluings.

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: affine 2-space
-    2: affine 2-space
-  in the coordinate(s)
-    1: [x, y]
-    2: [u, v]
-
-julia> V1 = PrincipalOpenSubset(U1, x); # Preparations for gluing
-
-julia> V2 = PrincipalOpenSubset(U2, u);
-
-julia> f = morphism(V1, V2, [1//x, y//x]); # The gluing isomorphism
-
-julia> g = morphism(V2, V1, [1//u, v//u]); # and its inverse
-
-julia> G = Gluing(U1, U2, f, g); # Construct the gluing
-
-julia> add_gluing!(C, G) # Make the gluing part of the Covering
-Covering
-  described by patches
-    1: affine 2-space
-    2: affine 2-space
-  in the coordinate(s)
-    1: [x, y]
-    2: [u, v]
-
-julia> X = CoveredScheme(C) # Create a CoveredScheme from the Gluing
-Scheme
-  over rational field
-with default covering
-  described by patches
-    1: affine 2-space
-    2: affine 2-space
-  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: affine 2-space
-    2: affine 2-space
-    3: affine 2-space
-  in the coordinate(s)
-    1: [(s1//s0), (s2//s0)]
-    2: [(s0//s1), (s2//s1)]
-    3: [(s0//s2), (s1//s2)]
source

Other constructors:

disjoint_unionMethod
disjoint_union(Xs::Vector{<:AbsCoveredScheme}) -> (AbsCoveredScheme, Vector{<:AbsCoveredSchemeMor})

Return the disjoint union of the non-empty vector of covered schemes as a covered scheme.

Input:

  • a vector Xs of covered schemes.

Output:

A pair $(X, \mathrm{injections})$ where $X$ is a covered scheme and $\mathrm{injections}$ is a vector of inclusion morphisms $ı_i\colon X_i \to X$, where $X$ is the disjoint union of the covered schemes $X_i$ in Xs.

Examples

julia> R_1, (x, y, z) = graded_polynomial_ring(QQ, [:x, :y, :z]);
-
-julia> I_1 = ideal(R_1, z*x^2 + y^3);
-
-julia> X_1 = covered_scheme(proj(R_1, I_1))
-Scheme
-  over rational field
-with default covering
-  described by patches
-    1: scheme((y//x)^3 + (z//x))
-    2: scheme((x//y)^2*(z//y) + 1)
-    3: scheme((x//z)^2 + (y//z)^3)
-  in the coordinate(s)
-    1: [(y//x), (z//x)]
-    2: [(x//y), (z//y)]
-    3: [(x//z), (y//z)]
-
-julia> R_2, (u, v) = polynomial_ring(rational_field(), [:u, :v]);
-
-julia> I_2 = ideal(R_2, u + v^2);
-
-julia> X_2 = covered_scheme(spec(R_2, I_2))
-Scheme
-  over rational field
-with default covering
-  described by patches
-    1: scheme(u + v^2)
-  in the coordinate(s)
-    1: [u, v]
-
-julia> X, injections = disjoint_union([X_1, X_2]);
-
-julia> X
-Scheme
-  over rational field
-with default covering
-  described by patches
-    1: scheme((y//x)^3 + (z//x))
-    2: scheme((x//y)^2*(z//y) + 1)
-    3: scheme((x//z)^2 + (y//z)^3)
-    4: scheme(u + v^2)
-  in the coordinate(s)
-    1: [(y//x), (z//x)]
-    2: [(x//y), (z//y)]
-    3: [(x//z), (y//z)]
-    4: [u, v]
-
-julia> injections
-2-element Vector{CoveredSchemeMorphism{CoveredScheme{QQField}, CoveredScheme{QQField}, AbsAffineSchemeMor}}:
- Hom: scheme over QQ covered with 3 patches -> scheme over QQ covered with 4 patches
- Hom: scheme over QQ covered with 1 patch -> scheme over QQ covered with 4 patches
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: scheme((s1//s0) - (s2//s0)^2)
-    2: scheme((s0//s1) - (s2//s1)^2)
-    3: scheme((s0//s2)*(s1//s2) - 1)
-  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{AffineScheme{QQField, MPolyQuoRing{QQMPolyRingElem}}}:
- scheme((s1//s0) - (s2//s0)^2)
- scheme((s0//s1) - (s2//s1)^2)
- scheme((s0//s2)*(s1//s2) - 1)
-
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: scheme((s1//s0) - (s2//s0)^2)
-    2: scheme((s0//s1) - (s2//s1)^2)
-    3: scheme((s0//s2)*(s1//s2) - 1)
-  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: scheme((s1//s0) - (s2//s0)^2)
-    2: scheme((s0//s1) - (s2//s1)^2)
-    3: scheme((s0//s2)*(s1//s2) - 1)
-  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)

Methods

fiber_productMethod
fiber_product(f::AbsCoveredSchemeMorphism, g::AbsCoveredSchemeMorphism)

For a diagram XxY ––> Y | | g V V X–––> Z f this computes the fiber product XxY together with the canonical maps to X and Y and returns the resulting triple.

source
is_normalMethod
is_normal(X::AbsCoveredScheme; check::Bool=true) -> Bool

Input:

  • a reduced scheme $X$,
  • if check is true, then confirm that $X$ is reduced; this is expensive.

Output:

Returns whether the scheme $X$ is normal.

Examples

julia> R, (x, y, z) = QQ[:x, :y, :z];
-
-julia> X = covered_scheme(spec(R));
-
-julia> is_normal(X)
-true
source
normalizationMethod
normalization(X::AbsCoveredScheme; check::Bool=true) -> (AbsCoveredScheme, AbsCoveredSchemeMor, Vector{<:AbsCoveredSchemeMor})

Return the normalization of the reduced scheme $X$.

Input:

  • a reduced scheme $X$,
  • if check is true, then confirm that $X$ is reduced; this is expensive.

Output:

A triple $(Y, \nu\colon Y \to X, \mathrm{injs})$ where $Y$ is a normal scheme, $\nu$ is the normalization, and $\mathrm{injs}$ is a vector of inclusion morphisms $ı_i\colon Y_i \to Y$, where $Y_i$ are the connected components of the scheme $Y$. See Tag 0CDV in [Stacks] or Definition 7.5.1 in [Liu06] for normalization of non-integral schemes.

Examples

julia> R, (x, y, z) = graded_polynomial_ring(QQ, [:x, :y, :z]);
-
-julia> I = ideal(R, z*x^2 + y^3);
-
-julia> X = covered_scheme(proj(R, I))
-Scheme
-  over rational field
-with default covering
-  described by patches
-    1: scheme((y//x)^3 + (z//x))
-    2: scheme((x//y)^2*(z//y) + 1)
-    3: scheme((x//z)^2 + (y//z)^3)
-  in the coordinate(s)
-    1: [(y//x), (z//x)]
-    2: [(x//y), (z//y)]
-    3: [(x//z), (y//z)]
-
-julia> Y, pr_mor = normalization(X);
-
-julia> Y
-Scheme
-  over rational field
-with default covering
-  described by patches
-    1: scheme((y//x)^3 + (z//x))
-    2: scheme((x//y)^2*(z//y) + 1)
-    3: scheme(-T(1)*y + x, T(1)*x + y^2, T(1)^2 + y, x^2 + y^3)
-  in the coordinate(s)
-    1: [(y//x), (z//x)]
-    2: [(x//y), (z//y)]
-    3: [T(1), x, y]
-
-julia> pr_mor
-Covered scheme morphism
-  from scheme over QQ covered with 3 patches
-    1a: [(y//x), (z//x)]   scheme((y//x)^3 + (z//x))
-    2a: [(x//y), (z//y)]   scheme((x//y)^2*(z//y) + 1)
-    3a: [T(1), x, y]       scheme(-T(1)*y + x, T(1)*x + y^2, T(1)^2 + y, x^2 + y^3)
-  to scheme over QQ covered with 3 patches
-    1b: [(y//x), (z//x)]   scheme((y//x)^3 + (z//x))
-    2b: [(x//y), (z//y)]   scheme((x//y)^2*(z//y) + 1)
-    3b: [(x//z), (y//z)]   scheme((x//z)^2 + (y//z)^3)
-given by the pullback functions
-  1a -> 1b
-    (y//x) -> (y//x)
-    (z//x) -> (z//x)
-    ----------------------------------------
-  2a -> 2b
-    (x//y) -> (x//y)
-    (z//y) -> (z//y)
-    ----------------------------------------
-  3a -> 3b
-    (x//z) -> x
-    (y//z) -> y
-
-julia> inclusion_morphisms(pr_mor)
-1-element Vector{CoveredSchemeMorphism{CoveredScheme{QQField}, CoveredScheme{QQField}, AbsAffineSchemeMor}}:
- Hom: scheme over QQ covered with 3 patches -> scheme over QQ covered with 3 patches
source

The modeling of covered schemes and their expected behavior

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: affine 2-space
-    2: affine 2-space
-    3: affine 2-space
-  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 SimplifiedAffineScheme 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 gluings 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/PR4245/AlgebraicGeometry/Schemes/CoveringsAndGluings/index.html b/previews/PR4245/AlgebraicGeometry/Schemes/CoveringsAndGluings/index.html deleted file mode 100644 index 4f0d5118b99f..000000000000 --- a/previews/PR4245/AlgebraicGeometry/Schemes/CoveringsAndGluings/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{<:AbsAffineScheme})

Return a Covering with pairwise disjoint affine charts $Uᵢ$ given by the entries of patches. This Covering will have no gluings except those gluings 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: affine 2-space
-    2: affine 2-space
-  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 gluings of the disjoint union are given by the disjoint union of the charts and gluings 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: affine 2-space
-  in the coordinate(s)
-    1: [x, y]
-
-julia> C2 = Covering(U2)
-Covering
-  described by patches
-    1: affine 2-space
-  in the coordinate(s)
-    1: [u, v]
-
-julia> C = disjoint_union(C1, C2)
-Covering
-  described by patches
-    1: affine 2-space
-    2: affine 2-space
-  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
gluingsMethod
gluings(C::Covering)

Return a dictionary of gluings 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 gluing.

Note: Gluings 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 gluings.

source

Methods

add_gluing!Method
add_gluing!(C::Covering, G::AbsGluing)

Add a gluing 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: affine 2-space
-    2: affine 2-space
-  in the coordinate(s)
-    1: [x, y]
-    2: [u, v]
-
-julia> V1 = PrincipalOpenSubset(U1, x); # Preparations for gluing
-
-julia> V2 = PrincipalOpenSubset(U2, u);
-
-julia> f = morphism(V1, V2, [1//x, y//x]); # The gluing isomorphism
-
-julia> g = morphism(V2, V1, [1//u, v//u]); # and its inverse
-
-julia> G = Gluing(U1, U2, f, g); # Construct the gluing
-
-julia> add_gluing!(C, G) # Make the gluing part of the Covering
-Covering
-  described by patches
-    1: affine 2-space
-    2: affine 2-space
-  in the coordinate(s)
-    1: [x, y]
-    2: [u, v]
-
-julia> C[U1, U2] == G # Check whether the gluing of U1 and U2 in C is G.
-true
source

Gluings

Gluings 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 gluing is

AbsGluingType
AbsGluing

A gluing of two affine schemes $X$ and $Y$ (the patches) along open subsets $U$ in $X$ and $V$ in $Y$ (the gluing_domains) along mutual isomorphisms $f : U ↔ V : g$ (the gluing_morphisms).

source

The available concrete types are

GluingType
Gluing

Concrete instance of an AbsGluing for gluings of affine schemes $X ↩ U ≅ V ↪ Y$ along open subsets $U$ and $V$ of type AffineSchemeOpenSubscheme.

source
SimpleGluingType
SimpleGluing

Concrete instance of an AbsGluing for gluings of affine schemes $X ↩ U ≅ V ↪ Y$ along open subsets $U$ and $V$ of type PrincipalOpenSubset.

source

Constructors

GluingMethod
Gluing(X::AbsAffineScheme, Y::AbsAffineScheme, 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 gluing
-
-julia> V2 = PrincipalOpenSubset(U2, u);
-
-julia> f = morphism(V1, V2, [1//x, y//x]); # The gluing isomorphism
-
-julia> g = morphism(V2, V1, [1//u, v//u]); # and its inverse
-
-julia> G = Gluing(U1, U2, f, g) # Construct the gluing
-Gluing
-  of affine 2-space
-  and affine 2-space
-along the open subsets
-  [x, y]   AA^2 \ scheme(x)
-  [u, v]   AA^2 \ scheme(u)
-given by the pullback function
-  u -> 1/x
-  v -> y/x
-
-julia> G isa SimpleGluing # Since the gluing domains were `PrincipalOpenSubsets`, this defaults to a `SimpleGluing`
-true
-
-julia> # Alternative using AffineSchemeOpenSubschemes as gluing domains:
-
-julia> W1 = AffineSchemeOpenSubscheme(U1, [x]); W2 = AffineSchemeOpenSubscheme(U2, [u]);
-
-julia> h1 = AffineSchemeOpenSubschemeMor(W1, W2, [1//x, y//x]);
-
-julia> h2 = AffineSchemeOpenSubschemeMor(W2, W1, [1//u, v//u]);
-
-julia> H = Gluing(U1, U2, h1, h2)
-Gluing
-  of affine 2-space
-  and affine 2-space
-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
-  affine scheme morphism
-    from [x, y]  AA^2 \ scheme(x)
-    to   [u, v]  affine 2-space
-  given by the pullback function
-    u -> 1/x
-    v -> y/x
-
-julia> H isa Gluing
-true
source

Attributes

patchesMethod
patches(G::AbsGluing)

Return a pair of affine schemes (X, Y) which are glued by G.

source
gluing_domainsMethod
gluing_domains(G::AbsGluing)

Return a pair of open subsets $U$ and $V$ of the respective patches of G which are glued by G along the gluing_morphisms of G.

source
gluing_morphismsMethod
gluing_morphisms(G::AbsGluing)

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 gluing identification.

source
inverseMethod
inverse(G::AbsGluing)

Return the gluing H with patches, gluing_domains, and gluing_morphisms in opposite order compared to G.

source

Methods

composeMethod
compose(G::AbsGluing, H::AbsGluing)

Given gluings X ↩ U ≅ V ↪ Y and Y ↩ V' ≅ W ↪ Z, return the gluing X ↩ V ∩ V' ↪ Z.

WARNING: In general such a gluing will not provide a separated scheme. Use maximal_extension to extend the gluing.

source
maximal_extensionMethod
maximal_extension(G::Gluing)

Given a gluing 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::AbsGluing, f::AbsAffineSchemeMor, g::AbsAffineSchemeMor; check::Bool=true)

Given a gluing $X ↩ U ≅ V ↪ Y$ and isomorphisms $f : X → X'$ and $g: Y → Y'$, return the induced gluing of $X'$ and $Y'$.

source
diff --git a/previews/PR4245/AlgebraicGeometry/Schemes/Cycles/index.html b/previews/PR4245/AlgebraicGeometry/Schemes/Cycles/index.html deleted file mode 100644 index a8a8fe084dfa..000000000000 --- a/previews/PR4245/AlgebraicGeometry/Schemes/Cycles/index.html +++ /dev/null @@ -1,189 +0,0 @@ - -Cycles and divisors · Oscar.jl

Cycles and divisors

Algebraic Cycles

AbsAlgebraicCycleType
AbsAlgebraicCycle{CoveredSchemeType<:AbsCoveredScheme, CoefficientRingType<:Ring}

An algebraic cycle $D$ on a (locally) Noetherian integral scheme $X$ with coefficients in a ring $R$ is a formal linear combination $\sum_i a_i D_i$ with $D_i \subseteq X$ integral, closed subschemes and the $a_i \in R$.

Such a cycle is represented non-uniquely as a formal sum $E = \sum_l b_l \mathcal{I}_l$ of equidimensional ideal sheaves $\mathcal{I}_l \subseteq \mathcal{O}_X$. For an equidimensional ideal sheaf $\mathcal{I}$ its interpretation as a cycle is as follows: Let $V(\mathcal{I})=E_{1} \cup \dots \cup E_{n}$ be the decomposition of the vanishing locus of $\mathcal{I}$ into irreducible components $E_i=V(\mathcal{P}_i)$ with $\mathcal{P}_i$ prime. Then $E$ corresponds to the cycle $D = \sum_{i=1}^{n} \mathrm{colength}_{\mathcal{P}_i}(\mathcal{I})E_i$.

Examples

julia> P2 = projective_space(QQ,2); (s0,s1,s2) = homogeneous_coordinates(P2);
-
-julia> I = ideal_sheaf(P2,ideal([s0,s1^2]))
-Sheaf of ideals
-  on scheme over QQ covered with 3 patches
-    1: [(s1//s0), (s2//s0)]   affine 2-space
-    2: [(s0//s1), (s2//s1)]   affine 2-space
-    3: [(s0//s2), (s1//s2)]   affine 2-space
-with restrictions
-  1: Ideal (1, (s1//s0)^2)
-  2: Ideal ((s0//s1), 1)
-  3: Ideal ((s0//s2), (s1//s2)^2)
-
-julia> D = algebraic_cycle(I)
-Effective algebraic cycle
-  on scheme over QQ covered with 3 patches
-with coefficients in integer ring
-given as the formal sum of
-  1 * sheaf of ideals
-
-julia> irreducible_decomposition(D)
-Effective algebraic cycle
-  on scheme over QQ covered with 3 patches
-with coefficients in integer ring
-given as the formal sum of
-  2 * sheaf of prime ideals
-
source

Constructors

algebraic_cycleMethod
algebraic_cycle(X::AbsCoveredScheme, R::Ring) -> AlgebraicCycle

Return the zero AlgebraicCycle over X with coefficients in R.

Examples

julia> P, (x, y, z) = graded_polynomial_ring(QQ, [:x, :y, :z]);
-
-julia> I = ideal([x^3-y^2*z]);
-
-julia> Y = proj(P, I);
-
-julia> Ycov = covered_scheme(Y);
-
-julia> R = ZZ;
-
-julia> algebraic_cycle(Ycov, R)
-Zero algebraic cycle
-  on scheme over QQ covered with 3 patches
-with coefficients in integer ring
source
algebraic_cycleMethod
algebraic_cycle(I::AbsIdealSheaf, R::Ring) -> AlgebraicCycle

Return the AlgebraicCycle $D = 1 ⋅ I$ with coefficients in $R$ for a sheaf of equidimensional ideals $I$.

Note that $I$ must be equidimensional.

Examples

julia> P, (x, y, z) = graded_polynomial_ring(QQ, [:x, :y, :z]);
-
-julia> I = ideal([x^3-y^2*z]);
-
-julia> Y = proj(P);
-
-julia> II = IdealSheaf(Y, I);
-
-julia> R = ZZ;
-
-julia> algebraic_cycle(II, R)
-Effective algebraic cycle
-  on scheme over QQ covered with 3 patches
-with coefficients in integer ring
-given as the formal sum of
-  1 * sheaf of ideals
-
source
algebraic_cycleMethod
algebraic_cycle(I::AbsIdealSheaf) -> AlgebraicCycle

Return the AlgebraicCycle $D = 1 ⋅ I$ with coefficients in $ℤ$ for a sheaf of equidimensional ideals $I$.

Examples

julia> P, (x, y, z) = graded_polynomial_ring(QQ, [:x, :y, :z]);
-
-julia> I = ideal([x^3-y^2*z]);
-
-julia> Y = proj(P);
-
-julia> II = IdealSheaf(Y, I);
-
-julia> R = ZZ;
-
-julia> algebraic_cycle(II, R)
-Effective algebraic cycle
-  on scheme over QQ covered with 3 patches
-with coefficients in integer ring
-given as the formal sum of
-  1 * sheaf of ideals
source

Properties

ambient_schemeMethod
ambient_scheme(D::AbsAlgebraicCycle)

Return the CoveredScheme $X$ on which D is defined.

source
componentsMethod
components(D::AbsAlgebraicCycle)

Return a list of ideal sheaves such that D is a linear combination of the corresponding cycles.

Note

The order of the components may change in different julia sessions. It is however consistent with the printing.

Note

The ideal sheaves are only guaranteed equidimensional and may carry multiplicities. See irreducible_decomposition(::AbsAlgebraicCycle) for the more conventional decomposition.

source
dimMethod
dim(D::AbsAlgebraicCycle)

Return the dimension of the support of the cycle D.

source
irreducible_decompositionMethod
irreducible_decomposition(D::AbsAlgebraicCycle)

Return a cycle $E$ equal to $D$ but as a formal sum $E = ∑ₖ aₖ ⋅ Iₖ$ where the components $Iₖ$ of $E$ are all sheaves of prime ideals.

source
integralMethod
integral(W::AbsAlgebraicCycle)

Assume $W$ is an algebraic cycle on $X$. This returns the sum of the lengths of all the components of dimension 0 of $W$.

source

Attributes

is_effectiveMethod
is_effective(A::AbsAlgebraicCycle)

Return whether all the coefficients are non-negative.

source
is_primeMethod
is_prime(D::AbsAlgebraicCycle)

An algebraic cycle is called prime if it consists of a single irreducible subvariety.

Note that this property is not stable under base extension.

source

Methods

<=Method
Base.:<=(A::AbsAlgebraicCycle, B::AbsAlgebraicCycle)

\[A \leq B\]

if and only if $B - A$ is effective.

source

Weil Divisors

AbsWeilDivisorType
AbsWeilDivisor{CoveredSchemeType, CoefficientRingType} <: AbsAlgebraicCycle{CoveredSchemeType, CoefficientRingType}

A Weil divisor with coefficients of type CoefficientRingType on a (locally) Noetherian integral scheme $X$ of type CoveredSchemeType.

Examples

julia> P2 = projective_space(QQ,2); (s0,s1,s2) = homogeneous_coordinates(P2);
-
-julia> I = ideal((s0*s1)^2);
-
-julia> II = ideal_sheaf(P2, I);
-
-julia> D = weil_divisor(II)
-Effective weil divisor
-  on scheme over QQ covered with 3 patches
-with coefficients in integer ring
-given as the formal sum of
-  1 * sheaf of ideals
-
-julia> E = irreducible_decomposition(D)
-Effective weil divisor
-  on scheme over QQ covered with 3 patches
-with coefficients in integer ring
-given as the formal sum of
-  2 * prime ideal sheaf on scheme over QQ covered with 3 patches extended from ideal ((s1//s0)) on affine 2-space
-  2 * prime ideal sheaf on scheme over QQ covered with 3 patches extended from ideal ((s0//s1)) on affine 2-space
-
-julia> P = components(E)[1]
-Prime ideal sheaf on Scheme over QQ covered with 3 patches extended from Ideal ((s1//s0)) on Affine 2-space
-
-julia> components(D)[1] == II
-true
-
-julia> D[II] # to get the coefficient
-1
-
-julia> E[P]
-2
source

Constructors

weil_divisorMethod
weil_divisor(X::AbsCoveredScheme, R::Ring) -> WeilDivisor

Return the zero weil divisor on X with coefficients in the ring R.

Examples

julia> P, (x, y, z) = graded_polynomial_ring(QQ, [:x, :y, :z]);
-
-julia> I = ideal([x^3-y^2*z]);
-
-julia> Y = proj(P, I);
-
-julia> Ycov = covered_scheme(Y);
-
-julia> weil_divisor(Ycov, QQ)
-Zero weil divisor
-  on scheme over QQ covered with 3 patches
-with coefficients in rational field
source
weil_divisorMethod
weil_divisor(I::AbsIdealSheaf) -> WeilDivisor

Given an ideal sheaf I of pure codimension $1$, return the weil divisor $D = 1 ⋅ I$ with coefficients in the integer ring.

Example

julia> P, (x, y, z) = graded_polynomial_ring(QQ, [:x, :y, :z]);
-
-julia> Y = proj(P);
-
-julia> I = ideal([(x^3-y^2*z)]);
-
-julia> II = IdealSheaf(Y, I);
-
-julia> weil_divisor(II)
-Effective weil divisor
-  on scheme over QQ covered with 3 patches
-with coefficients in integer ring
-given as the formal sum of
-  1 * sheaf of ideals
-  
-julia> JJ = II^2;
-
-julia> D = weil_divisor(JJ)
-Effective weil divisor
-  on scheme over QQ covered with 3 patches
-with coefficients in integer ring
-given as the formal sum of
-  1 * product of 2 ideal sheaves
-
-julia> irreducible_decomposition(D)
-Effective weil divisor
-  on scheme over QQ covered with 3 patches
-with coefficients in integer ring
-given as the formal sum of
-  2 * sheaf of prime ideals
-
source
weil_divisorMethod
weil_divisor(I::AbsIdealSheaf, R::Ring; check::Bool=true)

Given an ideal sheaf I of pure codimension $1$ and a ring R, return the weil divisor $D = 1 ⋅ I$ with coefficients in R.

source

Methods

Besides the methods for AbsAlgebraicCycle the following are available.

is_in_linear_systemMethod
is_in_linear_system(f::VarietyFunctionFieldElem, D::WeilDivisor; regular_on_complement::Bool=true, check::Bool=true) -> Bool

Return whether the rational function f is in the linear system $|D|$, i.e. if $(f) + D \geq 0$.

Input

  • regular_on_complement – set to true if f is regular on the complement of the support of D.
source
order_of_vanishingMethod
order_of_vanishing(f::VarietyFunctionFieldElem, D::AbsWeilDivisor; check::Bool=true)

Return the order of vanishing of the rational function f on the prime divisor D.

source
intersectMethod
intersect(D::AbsWeilDivisor, E::AbsWeilDivisor; covering::Covering=default_covering(ambient_scheme(D)))

Return the intersection number of the the Weil divisors D and E on a complete smooth surface as defined in [Har77].

Input

The optional keyword argument covering specifies the covering to be used for the computation.

source

Linear Systems

LinearSystemType
LinearSystem

A linear system of a Weil divisor $D$ on a variety $X$, generated by rational functions $f₁,…,fᵣ ∈ K(X)$.

source
weil_divisorMethod
weil_divisor(L::LinearSystem)

Return the divisor $D$ of the linear system $L = |D|$.

source
varietyMethod
variety(L::LinearSystem)

Return the variety on which L is defined.

source
subsystemMethod
subsystem(L::LinearSystem, D::AbsWeilDivisor) -> LinearSystem, MatElem

Given a linear system $L = |E|$ and a divisor $D \leq E$ compute $|D|$ and the matrix representing the inclusion $|D| \hookrightarrow |E|$ with respect to the given bases of both systems.

source

Cartier Divisors

CartierDivisorType
CartierDivisor{CoveredSchemeType<:AbsCoveredScheme, CoeffType<:RingElem}

A Cartier divisor $C$ on a scheme $X$ with coefficients $a_i$ in a ring $R$ is a formal linear combination $\sum_i a_i D_i$ of effective Cartier divisors $D_i$.

The scheme $X$ is of type CoveredSchemeType. The coefficients $a_i$ are of type CoeffType.

source
EffectiveCartierDivisorType
EffectiveCartierDivisor{CoveredSchemeType<:AbsCoveredScheme}

An effective Cartier divisor on a scheme $X$ is a closed subscheme $D \subseteq X$ whose ideal sheaf $\mathcal{I}_D \subseteq \mathcal{O}_X$ is an invertible $\mathcal{O}_X$-module. In particular, $\mathcal{I}_D$ is locally principal.

Internally, $C$ stores a trivializing_covering(C::EffectiveCartierDivisor). The scheme $X$ is of type CoveredSchemeType.

source

Cartier divisors support elementary arithmetic.

Constructors

effective_cartier_divisorMethod
effective_cartier_divisor(I::IdealSheaf;
-                          trivializing_covering::Covering = default_covering(scheme(I)))
-                                                            -> EffectiveCartierDivisor

Return the effective Cartier divisor defined by the ideal sheaf I, given that I is principal in the given covering of the scheme on which it is defined.

Examples

julia> P, (x, y, z) = graded_polynomial_ring(QQ, [:x, :y, :z]);
-
-julia> I = ideal([x^3-y^2*z]);
-
-julia> Y = proj(P);
-
-julia> II = IdealSheaf(Y, I);
-
-julia> effective_cartier_divisor(II)
-Effective cartier divisor
-  on scheme over QQ covered with 3 patches
-    1: [(y//x), (z//x)]   affine 2-space
-    2: [(x//y), (z//y)]   affine 2-space
-    3: [(x//z), (y//z)]   affine 2-space
-defined by
-  sheaf of ideals with restrictions
-    1: Ideal (-(y//x)^2*(z//x) + 1)
-    2: Ideal ((x//y)^3 - (z//y))
-    3: Ideal ((x//z)^3 - (y//z)^2)
source
effective_cartier_divisorMethod
effective_cartier_divisor(IP::AbsProjectiveScheme, f::Union{MPolyDecRingElem, MPolyQuoRingElem})

Return the effective Cartier divisor on the projective scheme $X$ defined by the homogeneous polynomial $f$.

source
cartier_divisorMethod
cartier_divisor(E::EffectiveCartierDivisor) -> CartierDivisor

Convert an EffectiveCartierDivisor into a CartierDivisor with coefficient $1$ in the ring of integers.

Examples

julia> P, (x, y, z) = graded_polynomial_ring(QQ, [:x, :y, :z]);
-
-julia> I = ideal([x^3-y^2*z]);
-
-julia> Y = proj(P);
-
-julia> II = IdealSheaf(Y, I);
-
-julia> E = effective_cartier_divisor(II)
-Effective cartier divisor
-  on scheme over QQ covered with 3 patches
-    1: [(y//x), (z//x)]   affine 2-space
-    2: [(x//y), (z//y)]   affine 2-space
-    3: [(x//z), (y//z)]   affine 2-space
-defined by
-  sheaf of ideals with restrictions
-    1: Ideal (-(y//x)^2*(z//x) + 1)
-    2: Ideal ((x//y)^3 - (z//y))
-    3: Ideal ((x//z)^3 - (y//z)^2)
-
-julia> cartier_divisor(E)
-Cartier divisor
-  on scheme over QQ covered with 3 patches
-with coefficients in integer ring
-defined by the formal sum of
-  1 * effective cartier divisor on scheme over QQ covered with 3 patches
source
cartier_divisorMethod
cartier_divisor(IP::AbsProjectiveScheme, f::Union{MPolyDecRingElem, MPolyQuoRingElem})

Return the (effective) Cartier divisor on the projective scheme $X$ defined by the homogeneous polynomial $f$.

source

Attributes

ideal_sheafMethod
ideal_sheaf(C::EffectiveCartierDivisor)

Return the sheaf of ideals $\mathcal{I}_C \subseteq \mathcal{O}_X$ representing C.

source
ambient_schemeMethod
ambient_scheme(C::EffectiveCartierDivisor)

Return the ambient scheme containing C.

source
ambient_schemeMethod
ambient_scheme(C::CartierDivisor)

Return the ambient scheme containing C.

source
componentsMethod
components(C::CartierDivisor)

Return a list of effective Cartier divisors $C_i$ such that $C$ is a linear combination of the $C_i$.

source
trivializing_coveringMethod
trivializing_covering(C::EffectiveCartierDivisor)

Return the trivializing covering of the effective Cartier divisor C.

A covering $(U_i)_{i \in I}$ is called trivializing for $C$ if $C(U_i)$ is principal for all $i \in I$.

source
diff --git a/previews/PR4245/AlgebraicGeometry/Schemes/GeneralSchemes/index.html b/previews/PR4245/AlgebraicGeometry/Schemes/GeneralSchemes/index.html deleted file mode 100644 index 42229b8bdc5c..000000000000 --- a/previews/PR4245/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 of type 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 of type 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/PR4245/AlgebraicGeometry/Schemes/MorphismsOfAffineSchemes/index.html b/previews/PR4245/AlgebraicGeometry/Schemes/MorphismsOfAffineSchemes/index.html deleted file mode 100644 index 7f027f4f3d22..000000000000 --- a/previews/PR4245/AlgebraicGeometry/Schemes/MorphismsOfAffineSchemes/index.html +++ /dev/null @@ -1,294 +0,0 @@ - -Morphisms of affine schemes · Oscar.jl

Morphisms of affine schemes

Constructors

General constructors

morphismMethod
morphism(X::AbsAffineScheme, Y::AbsAffineScheme, 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> morphism(X, Y, gens(OO(X)))
-Affine scheme 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::AbsAffineScheme{<: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)
-Affine scheme 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::AbsAffineScheme, Y::AbsAffineScheme; 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 x1, x2, x3
-      over rational field
-    by ideal (x1)
-
-julia> f = inclusion_morphism(Y, X)
-Affine scheme morphism
-  from [x1, x2, x3]  scheme(x1)
-  to   [x1, x2, x3]  affine 3-space over QQ
-given by the pullback function
-  x1 -> x1
-  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 generated by
-  x1
-
-julia> base_ring(I) == OO(X)
-true
source
composeMethod
compose(f::AbsAffineSchemeMor, g::AbsAffineSchemeMor)

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 x1, x2, x3
-      over rational field
-    by ideal (x1)
-
-julia> m1 = inclusion_morphism(Y, X)
-Affine scheme morphism
-  from [x1, x2, x3]  scheme(x1)
-  to   [x1, x2, x3]  affine 3-space over QQ
-given by the pullback function
-  x1 -> x1
-  x2 -> x2
-  x3 -> x3
-
-julia> m2 = identity_map(X)
-Affine scheme 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)
-Affine scheme morphism
-  from [x1, x2, x3]  scheme(x1)
-  to   [x1, x2, x3]  scheme(x1)
-given by the pullback function
-  x1 -> 0
-  x2 -> x2
-  x3 -> x3
-
-julia> compose(m3, compose(m1, m2)) == m1
-true
source
restrictMethod
restrict(f::AbsAffineSchemeMor, D::AbsAffineScheme, Z::AbsAffineScheme; check::Bool=true)

This method restricts the domain of the morphism $f$ to $D$ and its codomain to $Z$.

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 x1, x2, x3
-      over rational field
-    by ideal (x1)
-
-julia> restrict(identity_map(X), Y, Y) == identity_map(Y)
-true
source
restrict(f::SchemeMor, U::Scheme, V::Scheme; check::Bool=true)

Return the restriction $g: U → V$ of $f$ to $U$ and $V$.

source

Attributes

General attributes

domainMethod
domain(f::AbsAffineSchemeMor)

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 x1, x2, x3
-      over rational field
-    by ideal (x1)
-
-julia> f = inclusion_morphism(X, Y)
-Affine scheme morphism
-  from [x1, x2, x3]  scheme(x1)
-  to   [x1, x2, x3]  affine 3-space over QQ
-given by the pullback function
-  x1 -> x1
-  x2 -> x2
-  x3 -> x3
-
-julia> domain(f)
-Spectrum
-  of quotient
-    of multivariate polynomial ring in 3 variables x1, x2, x3
-      over rational field
-    by ideal (x1)
source
codomainMethod
codomain(f::AbsAffineSchemeMor)

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 x1, x2, x3
-      over rational field
-    by ideal (x1)
-
-julia> f = inclusion_morphism(X, Y)
-Affine scheme morphism
-  from [x1, x2, x3]  scheme(x1)
-  to   [x1, x2, x3]  affine 3-space over QQ
-given by the pullback function
-  x1 -> x1
-  x2 -> x2
-  x3 -> x3
-
-julia> codomain(f)
-Affine space of dimension 3
-  over rational field
-with coordinates [x1, x2, x3]
source
pullbackMethod
pullback(f::AbsAffineSchemeMor)

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 x1, x2, x3
-      over rational field
-    by ideal (x1)
-
-julia> pullback(inclusion_morphism(X, Y))
-Ring homomorphism
-  from multivariate polynomial ring in 3 variables over QQ
-  to quotient of multivariate polynomial ring by ideal (x1)
-defined by
-  x1 -> x1
-  x2 -> x2
-  x3 -> x3
source
graphMethod
graph(f::AbsAffineSchemeMor)

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 x1, x2, x3
-      over rational field
-    by ideal (x1)
-
-julia> f = inclusion_morphism(X, Y)
-Affine scheme morphism
-  from [x1, x2, x3]  scheme(x1)
-  to   [x1, x2, x3]  affine 3-space over QQ
-given by the pullback function
-  x1 -> x1
-  x2 -> x2
-  x3 -> x3
-
-julia> graph(f)
-(scheme(x1, -x1, x2 - x2, x3 - x3), Hom: scheme(x1, -x1, x2 - x2, x3 - x3) -> scheme(x1), Hom: scheme(x1, -x1, x2 - x2, x3 - x3) -> affine 3-space over QQ with coordinates [x1, x2, x3])
source
graph(TropC::TropicalCurve{minOrMax,false})

Return the graph of an abstract tropical curve TropC. Same as polyhedral_complex(tc).

source

Special attributes

In addition to the standard getters and methods for instances of AffineSchemeMor, 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::AbsAffineSchemeMor)

This method checks if a morphism is an isomorphism.

source
is_inverse_ofMethod
is_inverse_of(f::AbsAffineSchemeMor, g::AbsAffineSchemeMor)

This method checks if a morphism $f$ is the inverse of a morphism $g$.

source
is_identity_mapMethod
is_identity_map(f::AbsAffineSchemeMor)

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 x1, x2, x3
-      over rational field
-    by ideal (x1)
-
-julia> is_identity_map(inclusion_morphism(Y, X))
-false
source

Methods

fiber_productMethod
fiber_product(f::AbsAffineSchemeMor, g::AbsAffineSchemeMor)

For morphisms $f : X → Z$ and $g : Y → Z$ return the fiber product $X×Y$ over $Z$ together with its two canonical projections.

Whenever you have another set of maps a: W → X and b : W → Y forming a commutative square with f and g, you can use induced_map_to_fiber_product to create the resulting map W → X×Y.

source
productMethod
product(X::AbsAffineScheme, Y::AbsAffineScheme)

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::AbsAffineScheme{<: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 SimplifiedAffineScheme $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/PR4245/AlgebraicGeometry/Schemes/MorphismsOfProjectiveSchemes/index.html b/previews/PR4245/AlgebraicGeometry/Schemes/MorphismsOfProjectiveSchemes/index.html deleted file mode 100644 index 9bee5391c02e..000000000000 --- a/previews/PR4245/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

morphismMethod
morphism(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
morphismMethod
morphism(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
morphismMethod
morphism(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::AbsProjectiveSchemeMorphism)

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 = proj(P, I);
-
-julia> f = identity_map(Y)
-Projective scheme 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: scheme(-(y//x)^2*(z//x) + 1)
-    2: scheme((x//y)^3 - (z//y))
-    3: scheme((x//z)^3 - (y//z)^2)
-  in the coordinate(s)
-    1: [(y//x), (z//x)]
-    2: [(x//y), (z//y)]
-    3: [(x//z), (y//z)]
source
diff --git a/previews/PR4245/AlgebraicGeometry/Schemes/ProjectiveSchemes/index.html b/previews/PR4245/AlgebraicGeometry/Schemes/ProjectiveSchemes/index.html deleted file mode 100644 index a1b5a303cf18..000000000000 --- a/previews/PR4245/AlgebraicGeometry/Schemes/ProjectiveSchemes/index.html +++ /dev/null @@ -1,213 +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 = proj(S, I)
-Projective scheme
-  over rational field
-defined by ideal (x + y)
-
-julia> homogeneous_coordinate_ring(X)
-Quotient
-  of multivariate polynomial ring in 3 variables over QQ graded by
-    x -> [1]
-    y -> [1]
-    z -> [1]
-  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 generated by
-  x + y
-
-julia> X = proj(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 generated by
-  x + y
-
-julia> X = proj(S, I)
-Projective scheme
-  over rational field
-defined by ideal (x + y)
-
-julia> homogeneous_coordinate_ring(X)
-Quotient
-  of multivariate polynomial ring in 3 variables over QQ graded by
-    x -> [1]
-    y -> [1]
-    z -> [1]
-  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 = proj(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 = proj(S)
-Projective space of dimension 2
-  over quotient of multivariate polynomial ring by ideal (u^2 + v^2)
-with homogeneous coordinates [x, y, z]
-
-julia> defining_ideal(P)
-Ideal with 0 generators
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 = proj(S)
-Projective space of dimension 2
-  over quotient of multivariate polynomial ring by ideal (u^2 + v^2)
-with homogeneous coordinates [x, y, z]
-
-julia> affine_cone(P)
-(scheme(u^2 + v^2), Map: S -> quotient of multivariate polynomial ring)
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 = proj(S)
-Projective space of dimension 2
-  over quotient of multivariate polynomial ring by ideal (u^2 + v^2)
-with homogeneous coordinates [x, y, z]
-
-julia> Oscar.homogeneous_coordinates_on_affine_cone(P)
-3-element Vector{MPolyQuoRingElem{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}}:
- x
- y
- z
-
-julia> gens(OO(affine_cone(P)[1])) # all coordinates on the affine cone
-5-element Vector{MPolyQuoRingElem{MPolyDecRingElem{QQFieldElem, 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: affine 2-space
-    2: affine 2-space
-    3: affine 2-space
-  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 proj(S) for some graded polynomial ring or a graded affine algebra S, we provide the following constructors:

proj(S::MPolyDecRing)
-proj(S::MPolyDecRing, I::MPolyIdeal{T}) where {T<:MPolyDecRingElem}
-proj(I::MPolyIdeal{<:MPolyDecRingElem})
-proj(Q::MPolyQuoRing{<:MPolyDecRingElem})

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_genusMethod
arithmetic_genus(X::AbsProjectiveScheme{<:Field}) -> Int

Return the arithmetic genus of X, i.e. the integer $(-1)^n (h_X(0) - 1)$ where $h_X$ is the Hilbert polynomial of X and $n$ its dimension.

source

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::AbsAffineScheme)

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
homogenization_mapMethod
homogenization_map(P::AbsProjectiveScheme, U::AbsAffineScheme)

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 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: affine 4-space
-    2: affine 4-space
-    3: affine 4-space
-  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:

is_smoothMethod
is_smooth(P::AbsProjectiveScheme; algorithm::Symbol=:default) -> Bool

Check whether the scheme P is smooth.

Algorithms

There are three possible algorithms for checking smoothness, determined by the value of the keyword argument algorithm:

  • :projective_jacobian - uses the Jacobian criterion for projective schemes, see Exercise 4.2.10 of [Liu06],
  • :covered_jacobian - uses covered version of the Jacobian criterion,
  • :affine_cone - checks that the affine cone is smooth outside the origin.

The :projective_jacobian and the :covered algorithms only work for equidimensional schemes. The algorithms first check for equidimensionality, which can be expensive. If you already know that the scheme is equidimensional, then you can avoid recomputing that by writing set_attribute!(P, :is_equidimensional, true) before checking for smoothness.

The algorithms :covered_jacobian and :affine_cone only work when the base ring is a field.

The default algorithm is :projective_jacobian if the scheme is equidimensional, otherwise it is :affine_cone.

Examples

julia> A, (x, y, z) = grade(QQ[:x, :y, :z][1]);
-
-julia> B, _ = quo(A, ideal(A, [x^2 + y^2]));
-
-julia> C = proj(B)
-Projective scheme
-  over rational field
-defined by ideal (x^2 + y^2)
-
-julia> is_smooth(C)
-false
-
-julia> is_smooth(C; algorithm=:covered_jacobian)
-false
source
is_empty(P::AbsProjectiveScheme{<:Field})
-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/PR4245/AlgebraicGeometry/Schemes/RationalPointsAffine/index.html b/previews/PR4245/AlgebraicGeometry/Schemes/RationalPointsAffine/index.html deleted file mode 100644 index 0fed13c1e006..000000000000 --- a/previews/PR4245/AlgebraicGeometry/Schemes/RationalPointsAffine/index.html +++ /dev/null @@ -1,20 +0,0 @@ - -Rational Points on Affine Schemes · Oscar.jl

Rational Points on Affine Schemes

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) -> AbsAffineScheme

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/PR4245/AlgebraicGeometry/Schemes/RationalPointsProjective/index.html b/previews/PR4245/AlgebraicGeometry/Schemes/RationalPointsProjective/index.html deleted file mode 100644 index fc06ef172025..000000000000 --- a/previews/PR4245/AlgebraicGeometry/Schemes/RationalPointsProjective/index.html +++ /dev/null @@ -1,8 +0,0 @@ - -Rational Points on Projective Schemes · Oscar.jl

Rational Points on Projective Schemes

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
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/PR4245/AlgebraicGeometry/Schemes/Sheaves/index.html b/previews/PR4245/AlgebraicGeometry/Schemes/Sheaves/index.html deleted file mode 100644 index 76ff2b81d915..000000000000 --- a/previews/PR4245/AlgebraicGeometry/Schemes/Sheaves/index.html +++ /dev/null @@ -1,37 +0,0 @@ - -Sheaves on covered schemes · Oscar.jl

Sheaves on covered schemes

Oscar supports modeling sheaves by means of a covering by affine charts.

Presheaves

AbsPreSheafType
AbsPreSheaf{SpaceType, OpenType, OutputType, RestrictionType}

Abstract type for a sheaf ℱ on a space X.

  • SpaceType is a parameter for the type of the space $X$ on which $ℱ$ is defined.

  • OpenType is a type (most probably abstract!) for the open sets $U ⊂ X$ which are admissible as input for $ℱ(U)$.

  • OutputType is a type (most probably abstract!) for the values that $ℱ$ takes on admissible open sets $U$.

  • RestrictionType is a parameter for the type of the restriction maps $ℱ(V) → ℱ(U)$ for $U ⊂ V ⊂ X$ open.

For any instance F of AbsPreSheaf on a topological space X the following methods are implemented:

  • F(U) for admissible open subsets $U ⊂ X$: This returns the value $ℱ(U)$ of the sheaf F on U. Note that due to technical limitations, not every type of open subset might be admissible.

  • restriction_map(F, U, V) for admissible open subsets $V ⊂ U ⊂ X$: This returns the restriction map $ρ : ℱ(U) → ℱ(V)$.

source
PreSheafOnSchemeType
PreSheafOnScheme

A basic minimal implementation of the interface for AbsPreSheaf; to be used internally.

source

Structure sheaves

StructureSheafOfRingsType
StructureSheafOfRings <: AbsPreSheaf

On an AbsCoveredScheme $X$ this returns the sheaf $𝒪$ of rings of regular functions on $X$.

Note that due to technical reasons, the admissible open subsets are restricted to the following:

  • U::AbsAffineScheme among the basic_patches of the default_covering of X;
  • U::PrincipalOpenSubset with ambient_scheme(U) in the basic_patches of the default_covering of X;
  • W::AffineSchemeOpenSubscheme with ambient_scheme(W) in the basic_patches of the default_covering of X.

One can call the restriction maps of $𝒪$ across charts, implicitly using the identifications given by the gluings in the default_covering.

source

Ideal sheaves

AbsIdealSheafType
AbsIdealSheaf <: AbsPreSheaf

A sheaf of ideals $I$ on an AbsCoveredScheme $X$.

For an affine open subset $U ⊂ X$ call $I(U)$ to obtain an ideal in OO(U) representing I.

source
IdealSheafType
IdealSheaf <: AbsIdealSheaf

A sheaf of ideals $ℐ$ on an AbsCoveredScheme $X$ which is specified by a collection of concrete ideals on some open covering of $X$.

source
PrimeIdealSheafFromChartType

raw PrimeIdealSheafFromChart

Type for sheaves of prime ideals $P$ on a covered scheme $X$ constructed from a prime ideal of the coordinate ring of a chart. Essentially this is a scheme theoretic point.

For $U$ an affine chart of $X$, the ideal $P(U)$ is computed using the gluings. The implementation is lazy.

source

Coherent sheaves of modules

SheafOfModulesType
SheafOfModules <: AbsPreSheaf

A sheaf of modules $ℳ$ on an AbsCoveredScheme $X$.

Note that due to technical reasons, the admissible open subsets are restricted to the following:

  • U::AbsAffineScheme among the basic_patches of the default_covering of X;
  • U::PrincipalOpenSubset with ambient_scheme(U) in the basic_patches of the default_covering of X.

One can call the restriction maps of $ℳ$ across charts implicitly using the identifications given by the gluings in the default_covering.

source
twisting_sheafMethod
twisting_sheaf(IP::AbsProjectiveScheme{<:Field}, d::Int)

For a ProjectiveScheme $ℙ$ return the $d$-th twisting sheaf $𝒪(d)$ as a CoherentSheaf on $ℙ$.

Examples

julia> P = projective_space(QQ,3)
-Projective space of dimension 3
-  over rational field
-with homogeneous coordinates [s0, s1, s2, s3]
-
-julia> twisting_sheaf(P, 4)
-Coherent sheaf of modules
-  on scheme over QQ covered with 4 patches
-    1: [(s1//s0), (s2//s0), (s3//s0)]   affine 3-space
-    2: [(s0//s1), (s2//s1), (s3//s1)]   affine 3-space
-    3: [(s0//s2), (s1//s2), (s3//s2)]   affine 3-space
-    4: [(s0//s3), (s1//s3), (s2//s3)]   affine 3-space
-with restrictions
-  1: free module of rank 1 over Multivariate polynomial ring in 3 variables over QQ
-  2: free module of rank 1 over Multivariate polynomial ring in 3 variables over QQ
-  3: free module of rank 1 over Multivariate polynomial ring in 3 variables over QQ
-  4: free module of rank 1 over Multivariate polynomial ring in 3 variables over QQ
source
tautological_bundleMethod
tautological_bundle(IP::AbsProjectiveScheme{<:Field})

For a ProjectiveScheme $ℙ$ return the sheaf $𝒪(-1)$ as a CoherentSheaf on $ℙ$.

Examples

julia> P = projective_space(QQ,3)
-Projective space of dimension 3
-  over rational field
-with homogeneous coordinates [s0, s1, s2, s3]
-
-julia> tautological_bundle(P)
-Coherent sheaf of modules
-  on scheme over QQ covered with 4 patches
-    1: [(s1//s0), (s2//s0), (s3//s0)]   affine 3-space
-    2: [(s0//s1), (s2//s1), (s3//s1)]   affine 3-space
-    3: [(s0//s2), (s1//s2), (s3//s2)]   affine 3-space
-    4: [(s0//s3), (s1//s3), (s2//s3)]   affine 3-space
-with restrictions
-  1: free module of rank 1 over Multivariate polynomial ring in 3 variables over QQ
-  2: free module of rank 1 over Multivariate polynomial ring in 3 variables over QQ
-  3: free module of rank 1 over Multivariate polynomial ring in 3 variables over QQ
-  4: free module of rank 1 over Multivariate polynomial ring in 3 variables over QQ
source
cotangent_sheafMethod
cotangent_sheaf(X::AbsCoveredScheme)

For an AbsCoveredScheme $X$, return the sheaf $Ω¹(X)$ of Kaehler-differentials on $X$ as a CoherentSheaf.

source
free_moduleMethod
free_module(R::StructureSheafOfRings, n::Int)

Return the sheaf of free $𝒪$-modules $𝒪ⁿ$ for a structure sheaf of rings $𝒪 = R$.

source
projectivizationMethod
projectivization(E::AbsCoherentSheaf;
-    var_names::Vector{String}=Vector{String}(),
-    check::Bool=true
-  )

For a locally free sheaf $E$ on an AbsCoveredScheme $X$ this produces the associated projectivization $ℙ (E) → X$ as a CoveredProjectiveScheme.

A list of names for the variables of the relative homogeneous coordinate rings can be provided with var_names.

!!! note: The sheaf $E$ needs to be locally free so that a trivializing_covering can be computed. The check for this can be turned off by setting check=false.

source
diff --git a/previews/PR4245/AlgebraicGeometry/Schemes/intro/index.html b/previews/PR4245/AlgebraicGeometry/Schemes/intro/index.html deleted file mode 100644 index 7c073732c660..000000000000 --- a/previews/PR4245/AlgebraicGeometry/Schemes/intro/index.html +++ /dev/null @@ -1,2 +0,0 @@ - -Introduction · Oscar.jl
diff --git a/previews/PR4245/AlgebraicGeometry/SheafCohomology/sheaf_cohomology/index.html b/previews/PR4245/AlgebraicGeometry/SheafCohomology/sheaf_cohomology/index.html deleted file mode 100644 index e4aad309e12f..000000000000 --- a/previews/PR4245/AlgebraicGeometry/SheafCohomology/sheaf_cohomology/index.html +++ /dev/null @@ -1,59 +0,0 @@ - -Sheaves on Projective Space · Oscar.jl

Sheaves on Projective Space

We present two algorithms for computing sheaf cohomology over projective $n$-space. The algorithms are based on Tate resolutions via the Bernstein-Gelfand-Gelfand-correspondence as introduced in [EFS03] and on local cohomology (see [Eis98]), respectively. While the first algorithm makes use of syzygy computations over the exterior algebra, the second algorithm is based on syzygy computations over the symmetric algebra (see [DE02] for a tutorial). Thus, in most examples, the first algorithm is much faster.

sheaf_cohomologyMethod
sheaf_cohomology(M::ModuleFP{T}, l::Int, h::Int; algorithm::Symbol = :bgg) where {T <: MPolyDecRingElem}

If M is a graded module over a standard graded multivariate polynomial ring with coefficients in a field K, say, and $\mathcal F = \widetilde{M}$ is the coherent sheaf associated to M on the corresponding projective space $\mathbb P^n(K)$, consider the cohomology groups $H^i(\mathbb P^n(K), \mathcal F(d))$ as vector spaces over $K$, and return their dimensions $h^i(\mathbb P^n(K), \mathcal F(d))$ in the range of twists $d$ indicated by l and h. The result is presented as a table, where '-' indicates that $h^i(\mathbb P^n(K), \mathcal F(d)) = 0$. The line starting with chi lists the Euler characteristic of each twist under consideration. The values in the table can be accessed as shown in the first example below. Note that this example addresses the cotangent bundle on projective 3-space, while the second example is concerned with the structure sheaf of projective 4-space.

The keyword algorithm can be set to

  • :bgg (use the Tate resolution via the Bernstein-Gelfand-Gelfand correspondence),
  • :loccoh (use local cohomology).
Note

Due to the shape of the Tate resolution, the algorithm addressed by bgg does not compute all values in the given range l $<$ h. The missing values are indicated by a *. To determine all values in the range l $<$ h, enter sheaf_cohomology(M, l-ngens(base_ring(M)), h+ngens(base_ring(M))).

julia> R, x = polynomial_ring(QQ, :x => 1:4);
-
-julia> S, _= grade(R);
-
-julia> I = ideal(S, gens(S))
-Ideal generated by
-  x[1]
-  x[2]
-  x[3]
-  x[4]
-
-julia> FI = free_resolution(I)
-Free resolution of I
-S^4 <---- S^6 <---- S^4 <---- S^1 <---- 0
-0         1         2         3         4
-
-julia> M = cokernel(map(FI, 2));
-
-julia> tbl = sheaf_cohomology(M, -6, 2)
-twist:  -6  -5  -4  -3  -2  -1   0   1   2
-------------------------------------------
-3:      70  36  15   4   -   -   -   -   *
-2:       *   -   -   -   -   -   -   -   -
-1:       *   *   -   -   -   -   1   -   -
-0:       *   *   *   -   -   -   -   -   6
-------------------------------------------
-chi:     *   *   *   4   -   -   1   -   *
-
-julia> tbl[0, 2]
-6
-
-julia> tbl[1, 0]
-1
-
-julia> sheaf_cohomology(M, -9, 5)
-twist:   -9   -8   -7   -6   -5   -4   -3   -2   -1    0    1    2    3    4    5
----------------------------------------------------------------------------------
-3:      280  189  120   70   36   15    4    -    -    -    -    -    *    *    *
-2:        *    -    -    -    -    -    -    -    -    -    -    -    -    *    *
-1:        *    *    -    -    -    -    -    -    -    1    -    -    -    -    *
-0:        *    *    *    -    -    -    -    -    -    -    -    6   20   45   84
----------------------------------------------------------------------------------
-chi:      *    *    *   70   36   15    4    -    -    1    -    6    *    *    *
julia> R, x = polynomial_ring(QQ, :x => 1:5);
-
-julia> S, _  = grade(R);
-
-julia> F = graded_free_module(S, 1);
-
-julia> sheaf_cohomology(F, -8, 3, algorithm = :loccoh)
-twist:  -8  -7  -6  -5  -4  -3  -2  -1   0   1   2   3
-------------------------------------------------------
-4:      35  15   5   1   -   -   -   -   -   -   -   -
-3:       -   -   -   -   -   -   -   -   -   -   -   -
-2:       -   -   -   -   -   -   -   -   -   -   -   -
-1:       -   -   -   -   -   -   -   -   -   -   -   -
-0:       -   -   -   -   -   -   -   -   1   5  15  35
-------------------------------------------------------
-chi:    35  15   5   1   -   -   -   -   1   5  15  35
source
diff --git a/previews/PR4245/AlgebraicGeometry/Surfaces/AdjunctionProcess/index.html b/previews/PR4245/AlgebraicGeometry/Surfaces/AdjunctionProcess/index.html deleted file mode 100644 index 7f8f44281fb1..000000000000 --- a/previews/PR4245/AlgebraicGeometry/Surfaces/AdjunctionProcess/index.html +++ /dev/null @@ -1,43 +0,0 @@ - -Adjunction Process for Surfaces · Oscar.jl

Adjunction Process for Surfaces

A surface in this section is a smooth projective surface over $\mathbb C$.

Blowing up a surface in a point means to replace the point by an exceptional curve. Each such curve $E$ is a smooth, rational curve with self-intersection number $E^{2}=-1$. We speak of a $(-1)$-curve. A surface is minimal if it contains no $(-1)$-curves. That is, the surface cannot be obtained by blowing up a point on another surface. A surface $X_{\text{min}}$ is called a minimal model of a surface $X$ if $X_{\text{min}}$ is minimal and $X$ can be obtained from $X_{\text{min}}$ by repeatedly blowing up a point. Each surface $X$ has a minimal model which is unique if $X$ has non-negative Kodaira dimension. The Enriques-Kodaira classification classifies surfaces according to their minimal models. See [BHPV-D-V04] for more on this.

Given a surface, we may apply the adjunction process of Van de Ven and Sommese [SV-D-V87] to discover a minimal model. To describe this process, consider a surface $X \subset \mathbb P^{n}$ of codimension $c$. Let $S$ and $S_{X}$ denote the homogeneous coordinate rings of $\mathbb P^{n}$ and $X$, respectively. Consider $\omega_{X}=\text{Ext}^{c}_{S}(S_{X},S(-n-1)),$ the graded dualizing module of $S_{X}$. A basis of the graded piece $(\omega_{X})_{{1}}$ corresponds to the linear system $|K_X +H|$, where $K_X$ is a canonical divisor on $X$ and $H$ is the hyperplane class. Except for some exceptional cases, this linear system defines a birational morphism $\varphi_{|K_X+H|}\colon X \to X'$ onto another smooth projective surface $X'$ such that $\varphi_{|K_X+H|}$ blows down precisely all $(-1)$-lines on $X$. As shown by Van de Ven and Sommese, in the exceptional cases,

  • $X$ is a linearly or quadratically embedded $ \mathbb P^{2}$ or $X$ is ruled by lines, in which case $|K_X+H| = \emptyset$,
  • $X$ is an anti-canonically embedded del Pezzo surface, in which case $\varphi_{|K_X+H|}$ maps $X$ to a point,
  • $X$ is a conic bundle, in which case $\varphi_{|K_{X}+H|}\colon X \to B$ maps $X$ to a curve $B$ such that the fibers of $\varphi_{|K_{X}+H|}$ are the conics, or
  • $X$ is a surface in one of four explicit families identified by Sommese and Van de Ven, and $\varphi_{|K_X+H|}\colon X \to X'$ is not birational, but finite to one.

If we are not in one of these cases, a $(-1)$-conic $C$ in $X$ is mapped to a $(-1)$-line in $X'$ since $(K_X+H)\;\!. \;\! C=-1+2=1$. Thus, the adjunction process, which consists of applying the adjunction maps $\varphi_{|K_X+H|}$, $\varphi_{|K_{X'}+H'|}$ and so on, yields finitely many surfaces $X \rightarrow X^{\prime} \rightarrow X^{\prime\prime} \rightarrow \dots$ which are called the adjoint surfaces of $X$. The last adjoint surface is either minimal or belongs to one of the exceptional cases. In particular, if $X$ has non-negative Kodaira dimension, the adjunction process yields the uniquely determined minimal model of $X$.

Note

If $X$ is rational, the last adjoint surface is either $\mathbb P^{2}$, the Veronese surface, a Hirzebruch surface, a Del Pezzo surface, a conic bundle, or one of the four explicit families identified by Sommese and Van de Ven.

Note

In explicit computations, we consider surfaces which are defined by polynomial equations with coefficients in a subfield of $\mathbb C$ which can be handled by OSCAR.

Note

The surfaces in the examples below are taken from the OSCAR data base of nongeneral type surfaces in $\mathbb P^4$. To ease subsequent computations, the surfaces in the data base where constructed over finite fields. Note, however, that the recipes used in the constructions also work in characteristic zero. So all computations can be confirmed in characteristic zero, although this may be time consuming.

Adjunction Process

What we describe here goes back to joint work of Wolfram Decker and Frank-Olaf Schreyer. See [DES93], [DS00].

adjunction_processFunction
adjunction_process(X::AbsProjectiveVariety, steps::Int=0)

Given a smooth surface X and a non-negative integer steps, return data which describes the adjunction process for X: If steps == 0, carry out the complete process. Otherwise, carry out the indicated number of steps only.

More precisely, if $X^{(0)} = X \rightarrow X^{(1)}\rightarrow \dots \rightarrow X^{(r)}$ is the sequence of successive adjunction maps and adjoint surfaces in the completed adjunction process, return a quadruple L, say, where:

L[1] is a vector of tuples of numerical data: For each step $X^{(i)}\rightarrow X^{(i+1)}$, return the tuple $(n^{(i)}, d^{(i)}, \pi^{(i)}, s^{(i)}),$ where $n^{(i)}$ is the dimension of the ambient projective space of $X^{(i)}$, $d^{(i)}$ is the degree of $X^{(i)}$, $\pi^{(i)}$ is the sectional genus of $X^{(i)}$, and $s^{(i)}$ is the number of exceptional $(-1)$-lines on $X^{(i)}$ which are blown down to points in $ X^{(i+1)}$.

L[2] is a vector of adjoint matrices: For each step $X^{(i)}\rightarrow X^{(i+1)}$, return a presentation matrix of $S_X^{(i)}(1)$ considered as a module over $S_X^{(i+1)}$, where the $S_X^{(i)}$ are the homogeneous coordinate rings of the $X^{(i)}$. If X is rational, these matrices can be used to compute a rational parametrization of X.

L[3] is a vector of zero-dimensional projective algebraic sets: For each step $X^{(i)}\rightarrow X^{(i+1)}$, return the union of points in $ X^{(i+1)}$ which are obtained by blowing down the exceptional $(-1)$-lines on $X^{(i)}$.

L[4] is a projective variety: Return the last adjoint surface $X^{(r)}$.

Note

The function does not check whether X is smooth. If you are uncertain, enter is_smooth(X) first.

Warning

At current state, the adjunction process is only implemented for rational and Enriques surfaces which are linearly normal in the given embedding. The function does not check whether X is rational or an Enriques surface. In fact, at current state, OSCAR does not offer direct checks for this. Note, however, that the adjunction process will give an answer to this question a posteriori in cases where it terminates with a surface which is known to be rational or an Enriques surface.

Examples

julia> X = bordiga()
-Projective variety
-  in projective 4-space over GF(31991) with coordinates [x, y, z, u, v]
-defined by ideal with 4 generators
-
-
-julia> dim(X)
-2
-
-julia> codim(X)
-2
-
-julia> L = adjunction_process(X);
-
-julia> L[1]
-2-element Vector{NTuple{4, ZZRingElem}}:
- (4, 6, 3, 0)
- (2, 1, 0, 10)
-
-julia> L[4]
-Projective variety
-  in projective 2-space over GF(31991) with coordinates [z[1], z[2], z[3]]
-defined by ideal (0)
-
-julia> L[3][1]
-Projective algebraic set
-  in projective 2-space over GF(31991) with coordinates [z[1], z[2], z[3]]
-defined by ideal with 5 generators
-
-julia> dim(L[3][1])
-0
-
-julia> degree(L[3][1])
-10
julia> X = rational_d9_pi7();
-
-julia> L = adjunction_process(X);
-
-julia> L[1]
-3-element Vector{NTuple{4, ZZRingElem}}:
- (4, 9, 7, 0)
- (6, 9, 4, 6)
- (3, 3, 1, 3)
Note

Inspecting the returned numerical data in the first example above, we see that the Bordiga surface is the blow-up of the projective plane in 10 points, embedded into projective 4-space by the linear system $H = 4L -\sum_{i=1}^{10} E_i$. Here, $L$ is the preimage of a line and the $E_i$ are the exceptional divisors. In the second example, we see from the output that the terminal object of the adjunction process is a Del Pezzo surface in projective 3-space, that is, the blow-up of the projective plane in 6 points. In sum, we see that X is the blow-up of the projective plane in 15 points, embedded into projective 4-space by the linear system $H = 9L - \sum_{i=1}^{6} 3E_i - \sum_{i=7}^{9} 2E_i - \sum_{i=10}^{15} E_i$.

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/PR4245/AlgebraicGeometry/Surfaces/K3Surfaces/index.html b/previews/PR4245/AlgebraicGeometry/Surfaces/K3Surfaces/index.html deleted file mode 100644 index 3665667d8deb..000000000000 --- a/previews/PR4245/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 [Huy16] 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_verbosity_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 [Shi15] 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/PR4245/AlgebraicGeometry/Surfaces/ParametrizationSurfaces/index.html b/previews/PR4245/AlgebraicGeometry/Surfaces/ParametrizationSurfaces/index.html deleted file mode 100644 index 9257836e14b4..000000000000 --- a/previews/PR4245/AlgebraicGeometry/Surfaces/ParametrizationSurfaces/index.html +++ /dev/null @@ -1,35 +0,0 @@ - -Rational Parametrization of Rational Surfaces · Oscar.jl

Rational Parametrization of Rational Surfaces

What we present here relies on the function adjunction_process discussed in the previous section.

Parametrization

parametrizationMethod
parametrization(X::AbsProjectiveVariety)

Given a smooth rational surface X which is linearly normal in the given embedding, return a rational parametrization of X.

Note

The function does not check whether X is smooth. If you are uncertain, enter is_smooth(X) first.

Note

The function does not check rationality. In fact, at current state, OSCAR does not offer a direct check for this.

Note

The function makes use of the adjunction process. It returns an error message if the terminal object of the adjunction process is not the projective plane. See the OSCAR documentation for information on the adjunction process.

Examples

julia> X = bordiga()
-Projective variety
-  in projective 4-space over GF(31991) with coordinates [x, y, z, u, v]
-defined by ideal with 4 generators
-
-julia> dim(X)
-2
-
-julia> codim(X)
-2
-
-julia> phi = parametrization(X);
-
-julia> domain(phi)
-Multivariate polynomial ring in 5 variables over GF(31991) graded by
-  x -> [1]
-  y -> [1]
-  z -> [1]
-  u -> [1]
-  v -> [1]
-
-julia> codomain(phi)
-Multivariate polynomial ring in 3 variables over GF(31991) graded by
-  z[1] -> [1]
-  z[2] -> [1]
-  z[3] -> [1]
-
-julia> [degree(phi(x)) for x in gens(ambient_coordinate_ring(X))]
-5-element Vector{FinGenAbGroupElem}:
- [4]
- [4]
- [4]
- [4]
- [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/PR4245/AlgebraicGeometry/Surfaces/SurfacesP4/index.html b/previews/PR4245/AlgebraicGeometry/Surfaces/SurfacesP4/index.html deleted file mode 100644 index e98d844c3dd6..000000000000 --- a/previews/PR4245/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. Hard coded OSCAR examples for these surfaces 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/PR4245/AlgebraicGeometry/Surfaces/duValSing/index.html b/previews/PR4245/AlgebraicGeometry/Surfaces/duValSing/index.html deleted file mode 100644 index 79e8536762a4..000000000000 --- a/previews/PR4245/AlgebraicGeometry/Surfaces/duValSing/index.html +++ /dev/null @@ -1,84 +0,0 @@ - -Classifier/identifier specifically for du Val singularities · Oscar.jl

Classifier/identifier specifically for du Val singularities

has_du_val_singularitiesFunction
has_du_val_singularities(X::Scheme)

Return whether the given $X$ has at most du Val (surface) singularities.

Example:

julia> R,(x,y,z,w) = QQ[:x, :y, :z, :w]
-(Multivariate polynomial ring in 4 variables over QQ, QQMPolyRingElem[x, y, z, w])
-
-julia> I = ideal(R,[w,x^2+y^3+z^4])
-Ideal generated by
-  w
-  x^2 + y^3 + z^4
-
-julia> Rq, _ = quo(R,I)
-(Quotient of multivariate polynomial ring by ideal (w, x^2 + y^3 + z^4), Map: R -> Rq)
-
-julia> X = spec(Rq)
-Spectrum
-  of quotient
-    of multivariate polynomial ring in 4 variables x, y, z, w
-      over rational field
-    by ideal (w, x^2 + y^3 + z^4)
-
-julia> has_du_val_singularities(X)
-true
-
source
is_du_val_singularityFunction
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
is_du_val_singularity(X::AbsAffineScheme, I::Ideal)

Return whether the given $X$ has at most du Val (surface) singularities at the geometric points specified by the ideal $I$.

Note: For the ideal $I$ in a ring $R$, dim(R/I) = 0 is asserted

Example:

julia> R,(x,y,z,w) = QQ[:x, :y, :z, :w]
-(Multivariate polynomial ring in 4 variables over QQ, QQMPolyRingElem[x, y, z, w])
-
-julia> I = ideal(R,[w,x^2+y^3+z^4])
-Ideal generated by
-  w
-  x^2 + y^3 + z^4
-
-julia> Rq, _ = quo(R,I)
-(Quotient of multivariate polynomial ring by ideal (w, x^2 + y^3 + z^4), Map: R -> Rq)
-
-julia> J = ideal(R,[x,y,z,w])
-Ideal generated by
-  x
-  y
-  z
-  w
-
-julia> X = spec(Rq)
-Spectrum
-  of quotient
-    of multivariate polynomial ring in 4 variables x, y, z, w
-      over rational field
-    by ideal (w, x^2 + y^3 + z^4)
-
-julia> is_du_val_singularity(X,J)
-true
-
source
decide_du_val_singularityFunction
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
decide_du_val_singularity(X::AbsAffineScheme, I::Ideal)

Return a vector of tuples $T$ with the following data:

  • T[1]::Bool answers whether $X$ has at most du Val (surface) singularities at the geometric points specified by the ideal $I$.
  • T[2]::Ideal is $I_P$ the associated prime of I (possibly over a suitable field extension) describing some geometrically irreducible point
  • T[3]::Tuple contains the type of the singularity at $P$ e.g. (:A, 3)
  • T[4]::Int number of conjugate points

If $X$ has a least one singularity which is not du Val, the returned vector contains a single tuple $T$, with the following values:

  • T[1] is false
  • T[2] represents a point at which some non-du-Val singularity is present
  • T[3] is the empty tuple
  • T[4] = 1

Note: For the ideal $I$ in a ring $R$, dim(R/I) = 0 is asserted

Example:

julia> R,(x,y,z,w) = QQ[:x, :y, :z, :w]
-(Multivariate polynomial ring in 4 variables over QQ, QQMPolyRingElem[x, y, z, w])
-
-julia> I = ideal(R,[w,x^2+y^3+z^4])
-Ideal generated by
-  w
-  x^2 + y^3 + z^4
-
-julia> Rq, _ = quo(R,I)
-(Quotient of multivariate polynomial ring by ideal (w, x^2 + y^3 + z^4), Map: R -> Rq)
-
-julia> J = ideal(R,[x,y,z,w])
-Ideal generated by
-  x
-  y
-  z
-  w
-
-julia> X = spec(Rq)
-Spectrum
-  of quotient
-    of multivariate polynomial ring in 4 variables x, y, z, w
-      over rational field
-    by ideal (w, x^2 + y^3 + z^4)
-
-julia> decide_du_val_singularity(X,J)
-1-element Vector{Any}:
- (true, Ideal (w, z, y, x), (:E, 6), 1)
source
diff --git a/previews/PR4245/AlgebraicGeometry/ToricVarieties/AlgebraicCycles/index.html b/previews/PR4245/AlgebraicGeometry/ToricVarieties/AlgebraicCycles/index.html deleted file mode 100644 index 5ac0dc4ffe7f..000000000000 --- a/previews/PR4245/AlgebraicGeometry/ToricVarieties/AlgebraicCycles/index.html +++ /dev/null @@ -1,216 +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 [CLS11]:

  • By therorem 12.5.3 of [CLS11], there is an isomorphism

among the Chow ring and the cohomology ring. Note that the cohomology ring is naturally graded (cf. last paragraph on page 593 in [CLS11]). 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.

  • By therorem 12.5.3 of [CLS11], the Chow ring is isomorphic

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.

  • Finally, by lemma 12.5.1 of [CLS11], generators of the

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::NormalToricVarietyType, 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 toric variety
-
-julia> chow_ring(P2)
-Quotient
-  of multivariate polynomial ring in 3 variables x1, x2, x3
-    over rational field
-  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::NormalToricVarietyType, 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 toric variety
-
-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 toric variety
-
-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 toric variety
-
-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 toric variety
-
-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 toric variety
-
-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. Special constructors). 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 toric variety
-
-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, simplicial toric variety
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 toric variety
-
-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 toric variety
-
-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 generated by
-  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 x1, x2, x3, x4, x5
-    over rational field
-  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 toric variety
-
-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 toric variety
-
-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 toric variety
-
-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 toric variety
-
-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::NormalToricVarietyType)

Return the Chow ring of the simplicial toric variety v.

While [CLS11] focus on simplicial and complete varieties to define the Chow ring, it was described in [Peg14] 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 [FY04].

Examples

julia> p2 = projective_space(NormalToricVariety, 2);
-
-julia> is_complete(p2)
-true
-
-julia> ngens(chow_ring(p2))
-3
-
-julia> v = normal_toric_variety(incidence_matrix([[1], [2], [3]]), [[1, 0], [0, 1], [-1, -1]])
-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 x_{1}, x_{2}, x_{3}
-    over rational field
-  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 x_{Edge(2, 1)}, x_{Edge(3, 1)}, x_{Edge(3, 2)}
-    over rational field
-  by ideal with 5 generators
source
gens_of_rational_equivalence_classesMethod
gens_of_rational_equivalence_classes(v::NormalToricVarietyType)

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 [CLS11]). 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::NormalToricVarietyType)

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/PR4245/AlgebraicGeometry/ToricVarieties/BlowupMorphisms/index.html b/previews/PR4245/AlgebraicGeometry/ToricVarieties/BlowupMorphisms/index.html deleted file mode 100644 index ab660f9adae7..000000000000 --- a/previews/PR4245/AlgebraicGeometry/ToricVarieties/BlowupMorphisms/index.html +++ /dev/null @@ -1,206 +0,0 @@ - -Toric Blowups (Experimental) · Oscar.jl

Toric Blowups (Experimental)

It is a common goal in algebraic geometry to resolve singularities. Certainly, toric varieties and their subvarieties are no exception and we provide a growing set of functionality for such tasks.

In general, resolutions of toric varieties need not be toric. Indeed, some of the functionality below requires fully-fledge schemes machinery, which – as of October 2023 – is still in Oscar's experimental state. For this reason, the methods below should be considered experimental.

We focus mainly on toric blowups given by a star subdivision of a polyhedral fan along a primitive vector, see 11.1 Star Subdivisions in [CLS11]. Below, we refer to this new primitive vector as new_ray. The main constructor is the following

  • blow_up(Y::NormalToricVariety, new_ray::AbstractVector{<:IntegerUnion}; coordinate_name::String)

This will also construct the underlying toric morphism. We can specify the name for the coordinate in the Cox ring that is assigned to new_ray using the optional argument coordinate_name.

More generally, we can construct a blowup along a closed subscheme given by an ideal in the Cox ring or by an ideal sheaf of the corresponding covered scheme. In general, this will result in a non-toric variety.

Constructors

The following methods blow up toric varieties. The closed subscheme along which the blowup is constructed can be provided in different formats. We discuss the methods in ascending generality.

For our most specialized blowup method, we focus on the n-th cone in the fan of the variety v in question. This cone need not be maximal. The ensuing star subdivision will subdivide this cone about its "diagonal" (the sum of all its rays). The result of this will always be a toric variety:

blow_upMethod
blow_up(v::NormalToricVariety, n::Int; coordinate_name::String = "e")

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 morphism.

By default, we pick "e" as the name of the homogeneous coordinate for the exceptional prime divisor. As third optional argument one can supply a custom variable name.

Examples

julia> P3 = projective_space(NormalToricVariety, 3)
-Normal toric variety
-
-julia> f = blow_up(P3, 5)
-Toric blowup morphism
-
-julia> bP3 = domain(f)
-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]
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source

More generally, we can provide a primitive element in the fan of the variety in question and construct a toric morphism as in Section 11.1 Star Subdivisions in [CLS11]. The resulting star subdivision leads to a polyhedral fan, or put differently, the blowup is always toric:

blow_upMethod
blow_up(v::NormalToricVariety, new_ray::AbstractVector{<:IntegerUnion}; coordinate_name::String)

Blow up the toric variety by subdividing the fan of the variety with the provided new ray. This function returns the corresponding morphism.

Note that this ray must be a primitive element in the lattice Z^d, with d the dimension of the fan. In particular, it is currently impossible to blow up along a ray which corresponds to a non-Q-Cartier divisor.

By default, we pick "e" as the name of the homogeneous coordinate for the exceptional prime divisor. As optional argument one can supply a custom variable name.

Warning

This function is type unstable. The type of the field center_unnormalized is always a subtype of AbsIdealSheaf (meaning that center_unnormalized(f) isa Oscar.AbsIdealSheaf is always true). Sometimes, the function computes and sets the field center_unnormalized for the output f, giving it the type ToricIdealSheafFromCoxRingIdeal (meaning that center_unnormalized(f) isa Oscar.ToricIdealSheafFromCoxRingIdeal is true and center_unnormalized(f) isa IdealSheaf is false). If it does not, then calling center_unnormalized(f) computes and sets the field center_unnormalized and it will have the type IdealSheaf (meaning that center_unnormalized(f) isa Oscar.ToricIdealSheafFromCoxRingIdeal is false and center_unnormalized(f) isa IdealSheaf is true).

Examples

In the example below center_unnormalized(f) has type ToricIdealSheafFromCoxRingIdeal and we can access the corresponding ideal in the Cox ring using Oscar.ideal_in_cox_ring.

julia> P3 = projective_space(NormalToricVariety, 3)
-Normal toric variety
-
-julia> f = blow_up(P3, [0, 2, 3])
-Toric blowup morphism
-
-julia> bP3 = domain(f)
-Normal toric variety
-
-julia> cox_ring(bP3)
-Multivariate polynomial ring in 5 variables over QQ graded by
-  x1 -> [1 0]
-  x2 -> [1 2]
-  x3 -> [1 3]
-  x4 -> [1 0]
-  e -> [0 -1]
-
-julia> typeof(center_unnormalized(f))
-Oscar.ToricIdealSheafFromCoxRingIdeal{NormalToricVariety, AbsAffineScheme, Ideal, Map}
-
-julia> Oscar.ideal_in_cox_ring(center_unnormalized(f))
-Ideal generated by
-  x2^2
-  x3^3

In the below example, center_unnormalized(f) has type IdealSheaf and we cannot access the corresponding ideal in the Cox ring.

Examples

julia> rs = [1 1; -1 1]
-2×2 Matrix{Int64}:
-  1  1
- -1  1
-
-julia> max_cones = incidence_matrix([[1, 2]])
-1×2 IncidenceMatrix
-[1, 2]
-
-julia> v = normal_toric_variety(max_cones, rs)
-Normal toric variety
-
-julia> f = blow_up(v, [0, 1])
-Toric blowup morphism
-
-julia> center_unnormalized(f)
-Sheaf of ideals
-  on normal, non-smooth toric variety
-with restriction
-  1: Ideal (x_3_1, x_2_1, x_1_1)
-
-julia> typeof(center_unnormalized(f))
-IdealSheaf{NormalToricVariety, AbsAffineScheme, Ideal, Map}
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source

Most generally, we encode the closed subscheme along which we blow up by a homogeneous ideal in the Cox ring. Such blowups are often non-toric, i.e. the return value of the following method could well be non-toric.

blow_upMethod
blow_up(v::NormalToricVariety, I::MPolyIdeal; coordinate_name::String = "e")

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 prime divisor. As third optional argument one can supply a custom variable name.

Examples

julia> P3 = projective_space(NormalToricVariety, 3)
-Normal toric variety
-
-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 generated by
-  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]
-
-julia> I2 = ideal([x2 * x3])
-Ideal generated by
-  x2*x3
-
-julia> b2P3 = blow_up(P3, I2);
-
-julia> codomain(b2P3) === P3
-true
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source

Instead of providing the ideal, it is possible to turn a homogeneous ideal in the Cox ring into an ideal sheaf. Consequently, we also provide the support for the following method.

blow_upMethod
blow_up(m::NormalToricVariety, I::ToricIdealSheafFromCoxRingIdeal; coordinate_name::String = "e")

Blow up the toric variety along a toric ideal sheaf.

Warning

This function is type unstable. The type of the domain of the output f is always a subtype of AbsCoveredScheme (meaning that domain(f) isa AbsCoveredScheme is always true). Sometimes, the type of the domain will be a toric variety (meaning that domain(f) isa NormalToricVariety is true) if the algorithm can successfully detect this. In the future, the detection algorithm may be improved so that this is successful more often.

Examples

julia> P3 = projective_space(NormalToricVariety, 3)
-Normal toric variety
-
-julia> x1, x2, x3, x4 = gens(cox_ring(P3))
-4-element Vector{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}:
- x1
- x2
- x3
- x4
-
-julia> II = ideal_sheaf(P3, ideal([x1*x2]))
-Sheaf of ideals
-  on normal toric variety
-with restrictions
-  1: Ideal (x_1_1*x_2_1)
-  2: Ideal (x_2_2)
-  3: Ideal (x_1_3)
-  4: Ideal (x_1_4*x_2_4)
-
-julia> f = blow_up(P3, II)
-Blowup
-  of normal toric variety
-  in sheaf of ideals with restrictions
-    1b: Ideal (x_1_1*x_2_1)
-    2b: Ideal (x_2_2)
-    3b: Ideal (x_1_3)
-    4b: Ideal (x_1_4*x_2_4)
-with domain
-  scheme over QQ covered with 4 patches
-    1a: [x_1_1, x_2_1, x_3_1]   scheme(0)
-    2a: [x_1_2, x_2_2, x_3_2]   scheme(0)
-    3a: [x_1_3, x_2_3, x_3_3]   scheme(0)
-    4a: [x_1_4, x_2_4, x_3_4]   scheme(0)
-and exceptional divisor
-  effective cartier divisor defined by
-    sheaf of ideals with restrictions
-      1a: Ideal (x_1_1*x_2_1)
-      2a: Ideal (x_2_2)
-      3a: Ideal (x_1_3)
-      4a: Ideal (x_1_4*x_2_4)
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source

Attributes

underlying_morphismMethod
underlying_morphism(bl::ToricBlowupMorphism)

Return the underlying toric morphism of a toric blowup. Access to other attributes such as domain, codomain, covering_morphism are executed via underlying_morphism.

Examples

julia> P3 = projective_space(NormalToricVariety, 3)
-Normal toric variety
-
-julia> f = blow_up(P3, [0, 1, 1])
-Toric blowup morphism
-
-julia> Oscar.underlying_morphism(f)
-Toric morphism
source
index_of_new_rayMethod
index_of_new_ray(bl::ToricBlowupMorphism)

Return the index of the new ray used in the construction of the toric blowup.

Examples

julia> P3 = projective_space(NormalToricVariety, 3)
-Normal toric variety
-
-julia> f = blow_up(P3, [0, 1, 1])
-Toric blowup morphism
-
-julia> index_of_new_ray(f)
-5
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
center_dataMethod
center_data(bl::ToricBlowupMorphism)

Returns the ideal, ideal sheaf or ray that was used to construct the morphism.

Examples

julia> P3 = projective_space(NormalToricVariety, 3)
-Normal toric variety
-
-julia> f = blow_up(P3, [0, 2, 3])
-Toric blowup morphism
-
-julia> center_data(f)
-3-element Vector{Int64}:
- 0
- 2
- 3
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
center_unnormalizedMethod
center_unnormalized(bl::ToricBlowupMorphism)

Returns an ideal sheaf I such that the normalization of the blowup along I gives the morphism bl.

Examples

julia> P3 = projective_space(NormalToricVariety, 3)
-Normal toric variety
-
-julia> f = blow_up(P3, [0, 2, 3])
-Toric blowup morphism
-
-julia> center_unnormalized(f)
-Sheaf of ideals
-  on normal, smooth toric variety
-with restrictions
-  1: Ideal (x_2_1^2, x_3_1^3)
-  2: Ideal (x_2_2^2, x_3_2^3)
-  3: Ideal (1)
-  4: Ideal (1)
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
exceptional_prime_divisorMethod
exceptional_prime_divisor(bl::ToricBlowupMorphism)

Return the exceptional prime Weil divisor (as a toric divisor) of the ray used to construct the toric blowup. Note that this divisor need not be Cartier and this divisor need not coincide with the locus where the morphism is not an isomorphism.

Examples

julia> P3 = projective_space(NormalToricVariety, 3)
-Normal toric variety
-
-julia> f = blow_up(P3, [0, 2, 3])
-Toric blowup morphism
-
-julia> E = exceptional_prime_divisor(f)
-Torus-invariant, prime divisor on a normal toric variety
-
-julia> is_cartier(E)
-false
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source

Based on underlying_morphism, also the following attributes of toric morphisms are supported for toric blowups:

  • grid_morphism(bl::ToricBlowupMorphism),
  • morphism_on_torusinvariant_weil_divisor_group(bl::ToricBlowupMorphism),
  • morphism_on_torusinvariant_cartier_divisor_group(bl::ToricBlowupMorphism),
  • morphism_on_class_group(bl::ToricBlowupMorphism),
  • morphism_on_picard_group(bl::ToricBlowupMorphism).

The total and strict transform of ideal sheaves along blowups, not necessarily toric, can be computed:

total_transformMethod
total_transform(f::AbsSimpleBlowupMorphism, II::IdealSheaf)

Computes the total transform of an ideal sheaf along a blowup.

In particular, this applies in the toric setting. However, note that currently (October 2023), ideal sheaves are only supported on smooth toric varieties.

Examples

julia> P2 = projective_space(NormalToricVariety, 2)
-Normal toric variety
-
-julia> bl = blow_up(P2, [1, 1])
-Toric blowup morphism
-
-julia> S = cox_ring(P2);
-
-julia> x, y, z = gens(S);
-
-julia> I = ideal_sheaf(P2, ideal([x*y]))
-Sheaf of ideals
-  on normal, smooth toric variety
-with restrictions
-  1: Ideal (x_1_1*x_2_1)
-  2: Ideal (x_2_2)
-  3: Ideal (x_1_3)
-
-julia> total_transform(bl, I)
-Sheaf of ideals
-  on normal toric variety
-with restrictions
-  1: Ideal (x_1_1*x_2_1^2)
-  2: Ideal (x_1_2^2*x_2_2)
-  3: Ideal (x_2_3)
-  4: Ideal (x_1_4)
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source

Arithmetics

Toric blowups can be added, subtracted and multiplied by rational numbers. The results of such operations will not be toric morphisms, i.e. they no longer correspond to the blowup of a certain closed subscheme. Arithmetics among toric blowups and general toric morphisms is also supported, as well as equality for toric blowups.

diff --git a/previews/PR4245/AlgebraicGeometry/ToricVarieties/CohomologyClasses/index.html b/previews/PR4245/AlgebraicGeometry/ToricVarieties/CohomologyClasses/index.html deleted file mode 100644 index 7c2269a567bd..000000000000 --- a/previews/PR4245/AlgebraicGeometry/ToricVarieties/CohomologyClasses/index.html +++ /dev/null @@ -1,212 +0,0 @@ - -Cohomology Classes · Oscar.jl

Cohomology Classes

Constructors

General constructors

cohomology_classMethod
cohomology_class(v::NormalToricVarietyType, 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 toric variety
-
-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 toric variety
-
-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 toric variety
-
-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 toric variety
-
-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 toric variety
-
-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, simplicial, complete toric variety
source
coefficientsMethod
coefficients(c::CohomologyClass)

Return the coefficients of the cohomology class c.

Examples

julia> dP2 = del_pezzo_surface(NormalToricVariety, 2)
-Normal toric variety
-
-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 toric variety
-
-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 toric variety
-
-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 toric variety
-
-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 generated by
-  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 x1, x2, x3, x4, x5
-    over rational field
-  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; check::Bool = true)

Integrate the cohomolgy class c over the normal toric variety toric_variety(c).

The theory underlying this method requires that the toric variety in question is simplicial and complete. The check of completeness may take a long time to complete. If desired, this can be switched off by setting the optional argument check to the value false.

Examples

julia> dP3 = del_pezzo_surface(NormalToricVariety, 3)
-Normal toric variety
-
-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 toric variety
-
-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 = incidence_matrix([[1,3,4], [1,3,5], [1,4,5], [2,3,4], [2,3,5], [2,4,5]]);
-
-julia> X = normal_toric_variety(max_cones, ray_generators; 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 multivariate polynomial ring in 5 variables over QQ graded by
-    x1 -> [1]
-    x2 -> [1]
-    x3 -> [1]
-    x4 -> [1]
-    x5 -> [1]
-  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::NormalToricVarietyType; check::Bool = true)

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 toric variety
-
-julia> length(intersection_form(F3))
-10
source
chern_classMethod
chern_class(v::NormalToricVariety, k::Int; check::Bool = true)

Computes the k-th Chern class of the tangent bundle of a normal toric variety that is both smooth and complete. Since these checks can be computationally very demanding, we provide an optional argument check. Once set to false, this method skips those tests.

The implemented algorithm uses proposition 13.1.2 in [CLS11].

Examples

julia> F3 = hirzebruch_surface(NormalToricVariety, 3)
-Normal toric variety
-
-julia> chern_class(F3, 0)
-Cohomology class on a normal toric variety given by 1
-
-julia> chern_class(F3, 1, check = false)
-Cohomology class on a normal toric variety given by t1 + x1 + t2 + x2
-
-julia> integrate(chern_class(F3, 2), check = false)
-4
source
chern_classesMethod
chern_classes(v::NormalToricVariety; check::Bool = true)

Computes all Chern classes of the tangent bundle of a normal toric variety, which is smooth and complete. Since those checks can be computationally very demanding, the optional argument check can be set to false to skip those tests.

Examples

julia> F3 = hirzebruch_surface(NormalToricVariety, 3)
-Normal toric variety
-
-julia> cs = chern_classes(F3)
-3-element Vector{CohomologyClass}:
- Cohomology class on a normal toric variety given by 1
- Cohomology class on a normal toric variety given by t1 + x1 + t2 + x2
- Cohomology class on a normal toric variety given by 4//3*x2^2
-
-julia> integrate(cs[3])
-4
source
diff --git a/previews/PR4245/AlgebraicGeometry/ToricVarieties/CyclicQuotientSingularities/index.html b/previews/PR4245/AlgebraicGeometry/ToricVarieties/CyclicQuotientSingularities/index.html deleted file mode 100644 index d15cdddc37bd..000000000000 --- a/previews/PR4245/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 [Chr91] and [Ste91].

Warning

Note that [Chr91] and [Ste91] 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/PR4245/AlgebraicGeometry/ToricVarieties/NormalToricVarieties/index.html b/previews/PR4245/AlgebraicGeometry/ToricVarieties/NormalToricVarieties/index.html deleted file mode 100644 index 0bebf03c753e..000000000000 --- a/previews/PR4245/AlgebraicGeometry/ToricVarieties/NormalToricVarieties/index.html +++ /dev/null @@ -1,422 +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:

  • AffineNormalToricVariety is the type for toric varieties associated to a cone $\sigma$, denoted by $U_{\sigma}$ in [CLS11]
  • NormalToricVariety is the type for toric varieties associated to a polyhedral fan $\Sigma$, denoted by $X_{\Sigma}$ in [CLS11]
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.

Equality of Normal Toric Varieties

Warning

Equality of normal toric varieties is computationally very demanding. We have therefore made special design decisions for the == method.

In OSCAR, the == operator is reserved to check if two normal toric varieties are identical, meaning their underlying polyhedral fans are the same. However, this check is computationally challenging due to several reasons:

  • The ray generators might be scaled.
  • The ray generators might be stored in different orders.
  • The maximal (polyhedral) cones of the polyhedral fan might be stored in different orders.
  • If we fall back on polyhedral fan equality, lineality of the cones must also be considered.

To avoid this computational bottleneck, we have specially designed the == method. It checks if the memory locations of the two objects in question are identical. If so, our == method returns true. Otherwise, it raise an error.

Note that triple equality === (i.e. the check of equal the memory locations) is always supported for normal toric varieties. We recommend using it.

However, if you truly need to check for two normal toric varieties to be mathematically identical, then you will need to add a custom method. This method could look as follows:

function slow_equal(tv1::NormalToricVariety, tv2::NormalToricVariety)
-  tv1 === tv2 && return true
-  ambient_dim(tv1) == ambient_dim(tv2) || return false
-  f_vector(tv1) == f_vector(tv2) || return false
-  return Set(maximal_cones(tv1)) == Set(maximal_cones(tv2))
-end

Please note that this method slow_equal is not performant, that we currently (summer 2024) have no intentions in adding this function to OSCAR nor to make improvements to its performance. Rather, expect this method to be slow, potentially painfully so.

Constructors

Affine Toric Varieties

affine_normal_toric_varietyMethod
affine_normal_toric_variety(C::Cone)

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 toric variety
source
normal_toric_varietyMethod
normal_toric_variety(C::Cone)

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 toric variety
source
affine_normal_toric_varietyMethod
affine_normal_toric_variety(v::NormalToricVariety)

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 toric variety
-
-julia> affineVariety = affine_normal_toric_variety(v)
-Normal toric variety
source

Normal Toric Varieties

normal_toric_varietyFunction
normal_toric_variety(C::Cone)

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 toric variety
source
normal_toric_variety(max_cones::IncidenceMatrix, rays::AbstractCollection[RayVector]; non_redundant::Bool = false)

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 = incidence_matrix([[1, 2], [2, 3], [3, 4], [4, 1]])
-4×4 IncidenceMatrix
-[1, 2]
-[2, 3]
-[3, 4]
-[1, 4]
-
-julia> normal_toric_variety(max_cones, ray_generators)
-Normal toric variety
-
-julia> normal_toric_variety(max_cones, ray_generators; non_redundant = true)
-Normal toric variety
source
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)
-Polytope 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_variety(P::Polyhedron)

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)
-Polytope in ambient dimension 2
-
-julia> ntv = normal_toric_variety(square)
-Normal toric variety
source

Famous Toric Vareties

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_spaceMethod
affine_space(::Type{NormalToricVariety}, d::Int)

Construct the (toric) affine space of dimension d.

Examples

julia> affine_space(NormalToricVariety, 2)
-Normal toric variety
source
del_pezzo_surfaceMethod
del_pezzo_surface(::Type{NormalToricVariety}, b::Int)

Constructs the del Pezzo surface with b blowups for b at most 3.

Examples

julia> del_pezzo_surface(NormalToricVariety, 3)
-Normal toric variety
source
hirzebruch_surfaceMethod
hirzebruch_surface(::Type{NormalToricVariety}, r::Int)

Construct the r-th Hirzebruch surface.

Examples

julia> hirzebruch_surface(NormalToricVariety, 5)
-Normal toric variety
source
projective_spaceMethod
projective_space(::Type{NormalToricVariety}, d::Int)

Construct the projective space of dimension d.

Examples

julia> projective_space(NormalToricVariety, 2)
-Normal toric variety
source
weighted_projective_spaceMethod
weighted_projective_space(::Type{NormalToricVariety}, w::Vector{T}) where {T <: IntegerUnion}

Construct the weighted projective space corresponding to the weights w.

Examples

julia> weighted_projective_space(NormalToricVariety, [2, 3, 1])
-Normal toric variety
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)

Return 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)

Return 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 generated by
-  x1*x4
-
-julia> stanley_reisner_ideal(v2)
-Ideal generated by
-  x2*x3
source

An application of this functionality exists in the physics. Witten's Generalized-Sigma models (GLSM) [Wit88] 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 [FJR17], which describes this as GIT construction [CLS11].

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
normal_toric_variety_from_glsm(charges::ZZMatrix)

Return 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:

  • normal_toric_variety_from_glsm(charges::Vector{Vector{Int}})
  • normal_toric_variety_from_glsm(charges::Vector{Vector{ZZRingElem}})
source
normal_toric_varieties_from_glsmMethod
normal_toric_varieties_from_glsm(charges::ZZMatrix)

Return 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:

  • normal_toric_varieties_from_glsm(charges::Vector{Vector{Int}})
  • normal_toric_varieties_from_glsm(charges::Vector{Vector{ZZRingElem}})
source

Further Constructions

*Method
Base.:*(v::NormalToricVarietyType, w::NormalToricVarietyType)

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::NormalToricVarietyType, 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::NormalToricVarietyType)).

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 toric variety
-
-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
projectivizationMethod
projectivization(E::ToricLineBundle...)

This function computes the projectivization of a direct sum of line bundles or divisors. Please see [OM78] for more background information.

Examples

Let us construct the projective bundles $X=\mathbb{P}(\mathcal{O}_{\mathbb{P}^1}\oplus\mathcal{O}_{\mathbb{P}^1}(1))$ and $Y=\mathbb{P}(\mathcal{O}_{\mathbb{P}^1}\oplus\mathcal{O}_{\mathbb{P}^1}(2))$.

julia> P1 = projective_space(NormalToricVariety, 1);
-
-julia> D0 = toric_divisor(P1, [0,0]);
-
-julia> D1 = toric_divisor(P1, [1,0]);
-
-julia> X = projectivization(D0, D1)
-Normal toric variety
-
-julia> L0 = toric_line_bundle(P1, [0]);
-
-julia> L1 = toric_line_bundle(P1, [2]);
-
-julia> Y = projectivization(L0, L1)
-Normal toric variety
source
total_spaceMethod
total_space(E::ToricLineBundle...)

This function computes the total space of a direct sum of line bundles or divisors. Please see [OM78] for more background information.

Examples

Let us construct the toric Calabi-Yau varieties given by the total space of $\mathcal{O}_{\mathbb{P}^1}(2)\oplus\mathcal{O}_{\mathbb{P}^1}(-4)$ and $\omega_{\mathbb{P}^2}$.

julia> P1 = projective_space(NormalToricVariety, 1);
-
-julia> L1 = toric_line_bundle(P1, [2]);
-
-julia> L2 = toric_line_bundle(P1, [-4]);
-
-julia> X = total_space(L1, L2)
-Normal toric variety
-
-julia> degree(canonical_bundle(X))
-0
-
-julia> P2 = projective_space(NormalToricVariety, 2);
-
-julia> D = canonical_divisor(P2);
-
-julia> Y = total_space(D)
-Normal toric variety
-
-julia> degree(canonical_bundle(Y))
-0
source

Properties of Toric Varieties

has_torusfactorMethod
has_torusfactor(v::NormalToricVarietyType)

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::NormalToricVarietyType)

Checks if the normal toric variety v is affine.

Examples

julia> is_affine(projective_space(NormalToricVariety, 2))
-false
source
is_completeMethod
is_complete(v::NormalToricVarietyType)

Checks if the normal toric variety v is complete.

Examples

julia> is_complete(projective_space(NormalToricVariety, 2))
-true
source
is_fanoMethod
is_fano(v::NormalToricVarietyType)

Checks if the normal toric variety v is fano.

Examples

julia> is_fano(projective_space(NormalToricVariety, 2))
-true
source
is_gorensteinMethod
is_gorenstein(v::NormalToricVarietyType)

Checks if the normal toric variety v is Gorenstein.

Examples

julia> is_gorenstein(projective_space(NormalToricVariety, 2))
-true
source
is_simplicialMethod
is_simplicial(v::NormalToricVarietyType)

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::NormalToricVarietyType)

Checks if the normal toric variety v is smooth.

Examples

julia> is_smooth(projective_space(NormalToricVariety, 2))
-true
source
is_normalMethod
is_normal(v::NormalToricVarietyType)

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::NormalToricVarietyType)

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::NormalToricVarietyType)

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::NormalToricVarietyType)

Decides if the normal toric varieties v is a projective space.

Examples

julia> F5 = hirzebruch_surface(NormalToricVariety, 5)
-Normal toric variety
-
-julia> is_projective_space(F5)
-false
-
-julia> is_projective_space(projective_space(NormalToricVariety, 2))
-true
source
is_q_gorensteinMethod
is_q_gorenstein(v::NormalToricVarietyType)

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::NormalToricVarietyType)

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 toric variety
-
-julia> affine_open_covering(p2)
-3-element Vector{AffineNormalToricVariety}:
- Normal toric variety
- Normal toric variety
- Normal toric variety
source

Characters, Weil Divisors, Cartier Divisors, Class Group and Picard Group

torusinvariant_cartier_divisor_groupMethod
torusinvariant_cartier_divisor_group(v::NormalToricVarietyType)

Return the Cartier divisor group of an abstract normal toric variety v.

Examples

julia> p2 = projective_space(NormalToricVariety, 2)
-Normal toric variety
-
-julia> torusinvariant_cartier_divisor_group(p2)
-Z^3
source
character_latticeMethod
character_lattice(v::NormalToricVarietyType)

Return the character lattice of a normal toric variety v.

Examples

julia> p2 = projective_space(NormalToricVariety, 2);
-
-julia> character_lattice(p2)
-Z^2
source
class_groupMethod
class_group(v::NormalToricVarietyType)

Return the class group of the normal toric variety v.

Examples

julia> p2 = projective_space(NormalToricVariety, 2);
-
-julia> class_group(p2)
-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::NormalToricVarietyType)

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 toric variety
-
-julia> map_from_torusinvariant_cartier_divisor_group_to_torusinvariant_weil_divisor_group(p2)
-Map
-  from Z^3
-  to Z^3
source
map_from_torusinvariant_cartier_divisor_group_to_picard_groupMethod
map_from_torusinvariant_cartier_divisor_group_to_picard_group(v::NormalToricVarietyType)

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 toric variety
-
-julia> map_from_torusinvariant_cartier_divisor_group_to_picard_group(p2)
-Map
-  from Z^3
-  to Z
source
map_from_character_lattice_to_torusinvariant_weil_divisor_groupMethod
map_from_character_lattice_to_torusinvariant_weil_divisor_group(v::NormalToricVarietyType)

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
-  from Z^2
-  to Z^3
source
map_from_torusinvariant_weil_divisor_group_to_class_groupMethod
map_from_torusinvariant_weil_divisor_group_to_class_group(v::NormalToricVarietyType)

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
-  from Z^3
-  to Z
source
picard_groupMethod
picard_group(v::NormalToricVarietyType)

Return the Picard group of an abstract normal toric variety v.

Examples

julia> p2 = projective_space(NormalToricVariety, 2)
-Normal toric variety
-
-julia> picard_group(p2)
-Z
source
torusinvariant_weil_divisor_groupMethod
torusinvariant_weil_divisor_group(v::NormalToricVarietyType)

Return the torusinvariant divisor group of a normal toric variety v.

Examples

julia> p2 = projective_space(NormalToricVariety, 2);
-
-julia> torusinvariant_weil_divisor_group(p2)
-Z^3
source
torusinvariant_prime_divisorsMethod
torusinvariant_prime_divisors(v::NormalToricVarietyType)

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

Gorenstein and Picard index

gorenstein_indexMethod
gorenstein_index(v::NormalToricVarietyType)

Return the Gorenstein index of a $\mathbb{Q}$-Gorenstein normal toric variety v. This is the smallest positive integer $l$ such that $-l K$ is Cartier, where $K$ is a canonical divisor on v. See exercise 8.3.10 and 8.3.11 in [CLS11] for more details.

Examples

julia> gorenstein_index(weighted_projective_space(NormalToricVariety, [2,3,5]))
-3
source
picard_indexMethod
picard_index(v::NormalToricVarietyType)

Return the index of the Picard group in the class group of a simplicial normal toric variety v. Here, the Picard group embeds as the group of Cartier divisor classes into the class group via map_from_picard_group_to_class_group. See [HHS11] for more details.

Examples

julia> picard_index(weighted_projective_space(NormalToricVariety, [2,3,5]))
-30
source

Cones and Fans

polyhedral_fanMethod
polyhedral_fan(v::NormalToricVarietyType)

Return the fan of an abstract normal toric variety v.

Examples

julia> p2 = projective_space(NormalToricVariety, 2)
-Normal toric variety
-
-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
weight_coneMethod
weight_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 toric variety
-
-julia> weight_cone(antv)
-Polyhedral cone in ambient dimension 2
-
-julia> polarize(cone(antv)) == weight_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 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 toric variety
-
-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 toric variety
-
-julia> nef = nef_cone(p2)
-Polyhedral cone in ambient dimension 1
-
-julia> dim(nef)
-1
source

Dimensions

dimMethod
dim(v::NormalToricVarietyType)

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::NormalToricVarietyType)

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::NormalToricVarietyType)

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::NormalToricVarietyType, 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 [CLS11]. Note that this theorem requires that the normal toric variety v is both complete and simplicial.

Examples

julia> P3 = projective_space(NormalToricVariety, 3)
-Normal toric variety
-
-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:

  • Cox ring (also termed the "total coordinate ring" in [CLS11]),
  • coordinate ring of torus,
  • cohomology_ring,
  • Chow ring,
  • irrelevant ideal,
  • Stanley-Reisner ideal,
  • ideal of linear relations,
  • toric ideal.

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::NormalToricVarietyType) always return the field of rational numbers. For the coordinate names, we provide the following setter functions:

set_coordinate_namesMethod
set_coordinate_names(v::NormalToricVarietyType, coordinate_names::AbstractVector{<:VarName})

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::NormalToricVarietyType)).

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"
-
-julia> set_coordinate_names(antv, ["v"])
-
-julia> coordinate_names(antv)
-1-element Vector{String}:
- "v"
-
-julia> set_coordinate_names(antv, ['w'])
-
-julia> coordinate_names(antv)
-1-element Vector{String}:
- "w"
source
set_coordinate_names_of_torusMethod
set_coordinate_names_of_torus(v::NormalToricVarietyType, coordinate_names::AbstractVector{<:VarName})

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::NormalToricVarietyType)

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::NormalToricVarietyType)

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::NormalToricVarietyType)

Computes the Cox ring of the normal toric variety v. Note that [CLS11] refers to this ring as the "total coordinate ring". For uniformity with schemes, we also support the function coordinate_ring to refer to the Cox 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]
-
-julia> cox_ring(p2) == coordinate_ring(p2)
-true
source
irrelevant_idealMethod
irrelevant_ideal(v::NormalToricVarietyType)

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::NormalToricVarietyType)

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::NormalToricVarietyType)

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 toric variety
-
-julia> toric_ideal(antv)
-Ideal generated by
-  -x1*x2 + x3*x4
source
coordinate_ring_of_torusMethod
coordinate_ring_of_torus(v::NormalToricVarietyType)

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 y1, y2, y1_, y2_
-    over rational field
-  by ideal (y1*y1_ - 1, y2*y2_ - 1)
source

One can check the status as follows:

is_finalizedMethod
is_finalized(v::NormalToricVarietyType)

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::NormalToricVarietyType)

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 [CLS11] 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::NormalToricVarietyType)

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::NormalToricVarietyType)

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::NormalToricVarietyType)

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 toric variety
-
-julia> R, _ = polynomial_ring(QQ, 4);
-
-julia> toric_ideal(R, antv)
-Ideal generated by
-  -x1*x2 + x3*x4
source
coordinate_ring_of_torusMethod
coordinate_ring_of_torus(R::MPolyRing, v::NormalToricVarietyType)

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::NormalToricVarietyType, 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::NormalToricVarietyType, 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 generated by
-  -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 generated by
-  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/PR4245/AlgebraicGeometry/ToricVarieties/Subvarieties/index.html b/previews/PR4245/AlgebraicGeometry/ToricVarieties/Subvarieties/index.html deleted file mode 100644 index cc9495414eb4..000000000000 --- a/previews/PR4245/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 [CLS11]). 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::NormalToricVarietyType, 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 [CLS11] 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::NormalToricVarietyType, 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 [CLS11] 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 [CLS11].

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/PR4245/AlgebraicGeometry/ToricVarieties/ToricDivisorClasses/index.html b/previews/PR4245/AlgebraicGeometry/ToricVarieties/ToricDivisorClasses/index.html deleted file mode 100644 index 0d2b60b95e80..000000000000 --- a/previews/PR4245/AlgebraicGeometry/ToricVarieties/ToricDivisorClasses/index.html +++ /dev/null @@ -1,63 +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::NormalToricVarietyType, class::FinGenAbGroupElem)

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 toric variety
-
-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::NormalToricVarietyType, 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 toric variety
-
-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 toric variety
-
-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::NormalToricVarietyType)

Construct the trivial divisor class of a normal toric variety.

Examples

julia> v = projective_space(NormalToricVariety, 2)
-Normal toric variety
-
-julia> trivial_divisor_class(v)
-Divisor class on a normal toric variety
source
anticanonical_divisor_classMethod
anticanonical_divisor_class(v::NormalToricVarietyType)

Construct the anticanonical divisor class of a normal toric variety.

Examples

julia> v = projective_space(NormalToricVariety, 2)
-Normal toric variety
-
-julia> anticanonical_divisor_class(v)
-Divisor class on a normal toric variety
source
canonical_divisor_classMethod
canonical_divisor_class(v::NormalToricVarietyType)

Construct the canonical divisor class of a normal toric variety.

Examples

julia> v = projective_space(NormalToricVariety, 2)
-Normal toric variety
-
-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 toric variety
-
-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 toric variety
-
-julia> tdc = toric_divisor_class(P2, class_group(P2)([1]))
-Divisor class on a normal toric variety
-
-julia> divisor_class(tdc)
-Abelian group element [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 toric variety
-
-julia> tdc = toric_divisor_class(P2, class_group(P2)([1]))
-Divisor class on a normal toric variety
-
-julia> toric_variety(tdc)
-Normal toric variety
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 toric variety
-
-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/PR4245/AlgebraicGeometry/ToricVarieties/ToricDivisors/index.html b/previews/PR4245/AlgebraicGeometry/ToricVarieties/ToricDivisors/index.html deleted file mode 100644 index 2f8ff50d6b17..000000000000 --- a/previews/PR4245/AlgebraicGeometry/ToricVarieties/ToricDivisors/index.html +++ /dev/null @@ -1,151 +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::NormalToricVarietyType, 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::NormalToricVarietyType, 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::NormalToricVarietyType)

Construct the trivial divisor of a normal toric variety.

Examples

julia> v = projective_space(NormalToricVariety, 2)
-Normal toric variety
-
-julia> trivial_divisor(v)
-Torus-invariant, non-prime divisor on a normal toric variety
source
anticanonical_divisorMethod
anticanonical_divisor(v::NormalToricVarietyType)

Construct the anticanonical divisor of a normal toric variety.

Examples

julia> v = projective_space(NormalToricVariety, 2)
-Normal toric variety
-
-julia> anticanonical_divisor(v)
-Torus-invariant, non-prime divisor on a normal toric variety
source
canonical_divisorMethod
canonical_divisor(v::NormalToricVarietyType)

Construct the canonical divisor of a normal toric variety.

Examples

julia> v = projective_space(NormalToricVariety, 2)
-Normal toric variety
-
-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 toric variety
-
-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 toric variety
-
-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 toric variety
-
-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 toric variety
-
-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 toric variety
-
-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 toric variety
-
-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 toric variety
-
-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 toric variety
-
-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 toric variety
-
-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 toric variety
-
-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 toric variety
-
-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 [CLS11]. 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 toric variety
-
-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 toric variety
source

The following attributes are supported by experimental code:

schemeMethod
scheme(td::ToricDivisor)

Every toric divisor has an underlying scheme-theoretic Weil divisor. This method returns the scheme, on which said scheme-theoretic divisor is defined. In the case at hand, this is by design the toric variety at hand, which knows its underlying scheme. The latter can be accessed with the function underlying_toric_structure.

Examples

julia> P3 = projective_space(NormalToricVariety, 3)
-Normal toric variety
-
-julia> td = toric_divisor(P3, [0, 1, 0, 0])
-Torus-invariant, prime divisor on a normal toric variety
-
-julia> scheme(td)
-Normal toric variety
-
-julia> forget_toric_structure(scheme(td))
-(Scheme over QQ covered with 4 patches, Hom: scheme over QQ covered with 4 patches -> normal toric variety)
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
forget_toric_structureMethod
forget_toric_structure(td::ToricDivisor)

Every toric divisor has an underlying scheme-theoretic Weil divisor. This method returns said divisor.

Examples

julia> P3 = projective_space(NormalToricVariety, 3)
-Normal toric variety
-
-julia> td = toric_divisor(P3, [0, 1, 0, 0])
-Torus-invariant, prime divisor on a normal toric variety
-
-julia> forget_toric_structure(td)
-Effective weil divisor
-  on normal, 3-dimensional toric variety
-with coefficients in integer ring
-given as the formal sum of
-  1 * sheaf of ideals
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
diff --git a/previews/PR4245/AlgebraicGeometry/ToricVarieties/ToricIdealSheaves/index.html b/previews/PR4245/AlgebraicGeometry/ToricVarieties/ToricIdealSheaves/index.html deleted file mode 100644 index 86ba46a31837..000000000000 --- a/previews/PR4245/AlgebraicGeometry/ToricVarieties/ToricIdealSheaves/index.html +++ /dev/null @@ -1,25 +0,0 @@ - -Toric Ideal Sheaves (Experimental) · Oscar.jl

Toric Ideal Sheaves (Experimental)

Ideal sheaves on toric varieties are currently in experimental state. Currently, we support the following functionality. Note that, as of October 2023, this is limited to smooth toric varieties.

ideal_sheafMethod
ideal_sheaf(td::ToricDivisor)

Return the ideal sheaf corresponding to a toric divisor.

Examples

julia> P3 = projective_space(NormalToricVariety, 3)
-Normal toric variety
-
-julia> td = toric_divisor(P3, [0, 1, 0, 0])
-Torus-invariant, prime divisor on a normal toric variety
-
-julia> ideal_sheaf(td)
-Sheaf of ideals
-  on normal, smooth toric variety
-with restrictions
-  1: Ideal (x_2_1)
-  2: Ideal (x_2_2)
-  3: Ideal (1)
-  4: Ideal (x_2_4)
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
ideal_sheafMethod
ideal_sheaf(X::NormalToricVariety, I::MPolyIdeal)

Create a sheaf of ideals on a toric variety $X$ from a homogeneous ideal I in its cox_ring.

Examples

julia> P3 = projective_space(NormalToricVariety, 3)
-Normal toric variety
-
-julia> (x1,x2,x3,x4) = gens(cox_ring(P3));
-
-julia> I = ideal([x2,x3])
-Ideal generated by
-  x2
-  x3
-
-julia> IdealSheaf(P3, I);
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
diff --git a/previews/PR4245/AlgebraicGeometry/ToricVarieties/ToricLineBundles/index.html b/previews/PR4245/AlgebraicGeometry/ToricVarieties/ToricLineBundles/index.html deleted file mode 100644 index f63cb0335dfb..000000000000 --- a/previews/PR4245/AlgebraicGeometry/ToricVarieties/ToricLineBundles/index.html +++ /dev/null @@ -1,169 +0,0 @@ - -Toric Line Bundles · Oscar.jl

Toric Line Bundles

Constructors

Generic constructors

toric_line_bundleMethod
toric_line_bundle(v::NormalToricVarietyType, picard_class::FinGenAbGroupElem)

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 toric variety
-
-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::NormalToricVarietyType, 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 toric variety
-
-julia> l = toric_line_bundle(v, [ZZRingElem(2)])
-Toric line bundle on a normal toric variety
source
toric_line_bundleMethod
toric_line_bundle(v::NormalToricVarietyType, 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 toric variety
-
-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 toric variety
-
-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::NormalToricVarietyType, 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 toric variety
-
-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 toric variety
-
-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::NormalToricVarietyType)

Construct the anticanonical bundle of a normal toric variety.

Examples

julia> v = projective_space(NormalToricVariety, 2)
-Normal toric variety
-
-julia> anticanonical_bundle(v)
-Toric line bundle on a normal toric variety
source
canonical_bundleMethod
canonical_bundle(v::NormalToricVarietyType)

Construct the canonical bundle of a normal toric variety.

Examples

julia> v = projective_space(NormalToricVariety, 2)
-Normal toric variety
-
-julia> canonical_bundle(v)
-Toric line bundle on a normal toric variety
source
structure_sheafMethod
structure_sheaf(v::NormalToricVarietyType)

Construct the structure sheaf of a normal toric variety.

Examples

julia> v = projective_space(NormalToricVariety, 2)
-Normal toric variety
-
-julia> structure_sheaf(v)
-Toric line bundle on a normal toric variety
source
trivial_line_bundleMethod
trivial_line_bundle(v::NormalToricVarietyType)

Construct the trivial line bundle on a normal toric variety.

Examples

julia> v = projective_space(NormalToricVariety, 2)
-Normal toric variety
-
-julia> l = trivial_line_bundle(v)
-Toric line bundle on a normal toric variety
-
-julia> is_trivial(l)
-true
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_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 toric variety
-
-julia> is_ample(toric_line_bundle(F4, [1,0]))
-false
source
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 toric variety
-
-julia> is_basepoint_free(toric_line_bundle(F4, [1, 0]))
-true
source
is_immaculateMethod
is_immaculate(l::ToricLineBundle)

Return true if all sheaf cohomologies of l are trivial and false otherwise.

Examples

julia> F4 = hirzebruch_surface(NormalToricVariety, 4)
-Normal toric variety
-
-julia> l = toric_line_bundle(F4, [1,0])
-Toric line bundle on a normal toric variety
-
-julia> is_immaculate(toric_line_bundle(F4, [1,0]))
-false
-
-julia> all_cohomologies(l)
-3-element Vector{ZZRingElem}:
- 2
- 0
- 0
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 toric variety
-
-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 toric variety
-
-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 toric variety
-
-julia> l = toric_line_bundle(v, [ZZRingElem(2)])
-Toric line bundle on a normal toric variety
-
-julia> picard_class(l)
-Abelian group element [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 toric variety
-
-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 toric variety
-
-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 toric variety
-
-julia> l = toric_line_bundle(v, [ZZRingElem(2)])
-Toric line bundle on a normal toric variety
-
-julia> toric_variety(l)
-Normal 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 toric variety
-
-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 toric variety
-
-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
generic_sectionMethod
generic_section(l::ToricLineBundle)

Return a generic section of the toric line bundle l, that is return the sum of all elements basis_of_global_sections(l), each multiplied by a random integer.

The optional keyword argument range can be used to set the range of the random integers, e.g., generic_section(l, range = -100:100)

Examples

julia> v = projective_space(NormalToricVariety, 2)
-Normal toric variety
-
-julia> l = toric_line_bundle(v, [ZZRingElem(2)])
-Toric line bundle on a normal toric variety
-
-julia> s = generic_section(l);
-
-julia> parent(s) == cox_ring(toric_variety(l))
-true
source
diff --git a/previews/PR4245/AlgebraicGeometry/ToricVarieties/ToricMorphisms/index.html b/previews/PR4245/AlgebraicGeometry/ToricVarieties/ToricMorphisms/index.html deleted file mode 100644 index db521c72d7cb..000000000000 --- a/previews/PR4245/AlgebraicGeometry/ToricVarieties/ToricMorphisms/index.html +++ /dev/null @@ -1,140 +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 [CLS11], 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 with specified codomain

toric_morphismMethod
toric_morphism(domain::NormalToricVarietyType, mapping_matrix::ZZMatrix, codomain::NormalToricVarietyType; check=true)

Construct the toric morphism with given domain and associated to the lattice morphism given by the mapping_matrix.

If the codomain is left out, it will be determined whether the image of the domain fan is itself a polyhedral fan. In that case the codomain is assumed to be the associated toric variety.

All checks can be disabled with check=false.

Examples

julia> domain = projective_space(NormalToricVariety, 1)
-Normal toric variety
-
-julia> codomain = hirzebruch_surface(NormalToricVariety, 2)
-Normal toric variety
-
-julia> mapping_matrix = matrix(ZZ, [0 1])
-[0   1]
-
-julia> toric_morphism(domain, mapping_matrix, codomain)
-Toric morphism
source
toric_morphismMethod
toric_morphism(domain::NormalToricVarietyType, grid_morphism::FinGenAbGroupHom, codomain::NormalToricVarietyType; check=true)

Construct the toric morphism from the domain to the codomain with map given by the grid_morphism.

If the codomain is left out, it will be determined whether the image of the domain fan is itself a polyhedral fan. In that case the codomain is assumed to be the associated toric variety.

All checks can be disabled with check=false.

Examples

julia> domain = projective_space(NormalToricVariety, 1)
-Normal toric variety
-
-julia> codomain = hirzebruch_surface(NormalToricVariety, 2)
-Normal toric variety
-
-julia> mapping_matrix = matrix(ZZ, [[0, 1]])
-[0   1]
-
-julia> grid_morphism = hom(character_lattice(domain), character_lattice(codomain), mapping_matrix)
-Map
-  from Z
-  to Z^2
-
-julia> toric_morphism(domain, grid_morphism, codomain)
-Toric morphism
source

Special constructors

toric_identity_morphismMethod
toric_identity_morphism(variety::NormalToricVarietyType)

Construct the toric identity morphism from variety to variety.

Examples

julia> toric_identity_morphism(hirzebruch_surface(NormalToricVariety, 2))
-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 toric variety
-
-julia> domain(toric_identity_morphism(F4))
-Normal toric variety
source
imageMethod
image(F::FreeMod{R}, A::MatElem{R}) where R

Return the image of A as an object of type SubquoModule with ambient free module F.

Examples

julia> R, (x,y,z) = polynomial_ring(QQ, [:x, :y, :z]);
-
-julia> F = free_module(R, 2)
-Free module of rank 2 over R
-
-julia> A = R[x y; 2*x^2 3*y^2]
-[    x       y]
-[2*x^2   3*y^2]
- 
-julia> M = image(F, A)
-Submodule with 2 generators
-1 -> x*e[1] + y*e[2]
-2 -> 2*x^2*e[1] + 3*y^2*e[2]
-represented as subquotient with no relations.
-
-julia> ambient_free_module(M) === F
-true
julia> Rg, (x, y, z) = graded_polynomial_ring(QQ, [:x, :y, :z]);
-
-julia> F = graded_free_module(Rg, [8,8])
-Graded free module Rg^2([-8]) of rank 2 over Rg
-
-julia> A = Rg[x y; 2*x^2 3*y^2]
-[    x       y]
-[2*x^2   3*y^2]
- 
-julia> M = image(F, A)
-Graded submodule of F
-1 -> x*e[1] + y*e[2]
-2 -> 2*x^2*e[1] + 3*y^2*e[2]
-represented as subquotient with no relations
-
-julia> ambient_free_module(M) === F
-true
-
-julia> degrees_of_generators(M)
-2-element Vector{FinGenAbGroupElem}:
- [9]
- [10]
source
codomainMethod
codomain(tm::ToricMorphism)

Return the codomain of the toric morphism tm.

Examples

julia> F4 = hirzebruch_surface(NormalToricVariety, 4)
-Normal toric variety
-
-julia> codomain(toric_identity_morphism(F4))
-Normal toric variety
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 toric variety
-
-julia> grid_morphism(toric_identity_morphism(F4))
-Map
-  from Z^2
-  to 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 toric variety
-
-julia> morphism_on_torusinvariant_weil_divisor_group(toric_identity_morphism(F4))
-Map
-  from Z^4
-  to 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 toric variety
-
-julia> morphism_on_torusinvariant_cartier_divisor_group(toric_identity_morphism(F4))
-Map
-  from Z^4
-  to 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 toric variety
-
-julia> morphism_on_class_group(toric_identity_morphism(F4))
-Map
-  from Z^2
-  to 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 toric variety
-
-julia> morphism_on_picard_group(toric_identity_morphism(F4))
-Map
-  from Z^2
-  to Z^2
source
covering_morphismMethod
covering_morphism(f::ToricMorphism)

For a given toric morphism tm, we can compute the corresponding morphism of covered schemes. The following demonstrates this for the blow-up morphism of a blow-up of the projective space.

Examples

julia> IP2 = projective_space(NormalToricVariety, 2)
-Normal toric variety
-
-julia> bl = blow_up(IP2, [1, 1]);
-
-julia> cov_bl = covering_morphism(bl);
-
-julia> domain(cov_bl)
-Covering
-  described by patches
-    1: normal toric variety
-    2: normal toric variety
-    3: normal toric variety
-    4: normal toric variety
-  in the coordinate(s)
-    1: [x_1_1, x_2_1]
-    2: [x_1_2, x_2_2]
-    3: [x_1_3, x_2_3]
-    4: [x_1_4, x_2_4]
-
-julia> codomain(cov_bl)
-Covering
-  described by patches
-    1: normal toric variety
-    2: normal toric variety
-    3: normal toric variety
-  in the coordinate(s)
-    1: [x_1_1, x_2_1]
-    2: [x_1_2, x_2_2]
-    3: [x_1_3, x_2_3]
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::NormalToricVarietyType)

Return the quotient morphism from the Cox variety to the toric variety in question.

Examples

julia> F4 = hirzebruch_surface(NormalToricVariety, 4)
-Normal toric variety
-
-julia> morphism_from_cox_variety(F4)
-Toric morphism
source
cox_varietyMethod
cox_variety(variety::NormalToricVarietyType)

Return the Cox variety of the toric variety in question.

Examples

julia> F4 = hirzebruch_surface(NormalToricVariety, 4)
-Normal toric variety
-
-julia> cox_variety(F4)
-Normal toric variety
source
diff --git a/previews/PR4245/AlgebraicGeometry/ToricVarieties/ToricSchemes/index.html b/previews/PR4245/AlgebraicGeometry/ToricVarieties/ToricSchemes/index.html deleted file mode 100644 index f5a7b2727eee..000000000000 --- a/previews/PR4245/AlgebraicGeometry/ToricVarieties/ToricSchemes/index.html +++ /dev/null @@ -1,38 +0,0 @@ - -Toric Schemes · Oscar.jl

Toric Schemes

Toric varieties are special instances of schemes. As such, all scheme functionality is available to toric varieties.

Content

We aim for a seamless transition among toric varieties and covered schemes.

One advantage is that we can hope for improved performance of scheme functionality by using toric backends when applicable. In addition, one can apply powerful scheme computations to toric settings, thus extending the available toolkit significantly.

The user can extract the scheme corresponding to a toric variety as follows:

underlying_schemeMethod
underlying_scheme(X::AffineNormalToricVariety)

For an affine toric 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> C = positive_hull([1 0; 0 1])
-Polyhedral cone in ambient dimension 2
-
-julia> antv = affine_normal_toric_variety(C)
-Normal toric variety
-
-julia> Oscar.underlying_scheme(antv)
-Spectrum
-  of quotient
-    of multivariate polynomial ring in 2 variables x1, x2
-      over rational field
-    by ideal (0)
source
underlying_schemeMethod
underlying_scheme(X::NormalToricVariety)

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 toric variety
-
-julia> Oscar.underlying_scheme(P2)
-Scheme
-  over rational field
-with default covering
-  described by patches
-    1: normal toric variety
-    2: normal toric variety
-    3: normal toric variety
-  in the coordinate(s)
-    1: [x_1_1, x_2_1]
-    2: [x_1_2, x_2_2]
-    3: [x_1_3, x_2_3]
source

We also provide functionality to forget the toric structure completely. In this sense, the following methods return the underlying covered scheme, but this scheme does not remember being a toric variety.

forget_toric_structureMethod
forget_toric_structure(X::AffineNormalToricVariety)

Return a pair (Y, iso) where Y is a scheme without toric structure, together with an isomorphism iso : Y → X.

Examples

julia> C = positive_hull([1 0; 0 1])
-Polyhedral cone in ambient dimension 2
-
-julia> antv = affine_normal_toric_variety(C)
-Normal toric variety
-
-julia> forget_toric_structure(antv)
-(scheme(0), Hom: scheme(0) -> normal toric variety)
source
forget_toric_structureMethod
forget_toric_structure(X::NormalToricVariety)

Return a pair (Y, iso) where Y is a scheme without toric structure, together with an isomorphism iso : Y → X.

Examples

julia> P2 = projective_space(NormalToricVariety, 2)
-Normal toric variety
-
-julia> forget_toric_structure(P2)
-(Scheme over QQ covered with 3 patches, Hom: scheme over QQ covered with 3 patches -> normal toric variety)
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/PR4245/AlgebraicGeometry/ToricVarieties/cohomCalg/index.html b/previews/PR4245/AlgebraicGeometry/ToricVarieties/cohomCalg/index.html deleted file mode 100644 index 2c5cd794b1c1..000000000000 --- a/previews/PR4245/AlgebraicGeometry/ToricVarieties/cohomCalg/index.html +++ /dev/null @@ -1,97 +0,0 @@ - -Line bundle cohomology with cohomCalg · Oscar.jl

Line bundle cohomology with cohomCalg

We employ the cohomCalg algorithm [BJRR10*1] 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 [BJRR10], [BJRR10*1] (see also [RR10], [Jow11] and [BJRR12]).

Examples

julia> dP3 = del_pezzo_surface(NormalToricVariety, 3)
-Normal toric variety
-
-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 [BJRR10], [BJRR10*1] (see also [RR10], [Jow11] and [BJRR12]).

Examples

julia> dP3 = del_pezzo_surface(NormalToricVariety, 3)
-Normal toric variety
-
-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 [BJRR10*1], 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 [Bie18]. 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::NormalToricVarietyType)

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 toric variety
-
-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 indices [0]
- Toric vanishing set for cohomology indices [1]
- Toric vanishing set for cohomology indices [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 toric variety
-
-julia> vs = vanishing_sets(dP1)
-3-element Vector{ToricVanishingSet}:
- Toric vanishing set for cohomology indices [0]
- Toric vanishing set for cohomology indices [1]
- Toric vanishing set for cohomology indices [2]
-
-julia> toric_variety(vs[3])
-Normal, 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 toric variety
-
-julia> vs = vanishing_sets(dP1)
-3-element Vector{ToricVanishingSet}:
- Toric vanishing set for cohomology indices [0]
- Toric vanishing set for cohomology indices [1]
- Toric vanishing set for cohomology indices [2]
-
-julia> polyhedra(vs[3])
-1-element Vector{Polyhedron{QQFieldElem}}:
- Polyhedron in ambient dimension 2
source
cohomology_indicesMethod
cohomology_indices(tvs::ToricVanishingSet)

Return the cohomology indices of the toric vanishing set tvs.

Examples

julia> dP1 = del_pezzo_surface(NormalToricVariety, 1)
-Normal toric variety
-
-julia> vs = vanishing_sets(dP1)
-3-element Vector{ToricVanishingSet}:
- Toric vanishing set for cohomology indices [0]
- Toric vanishing set for cohomology indices [1]
- Toric vanishing set for cohomology indices [2]
-
-julia> cohomology_indices(vs[3])
-1-element Vector{Int64}:
- 2
source

Certainly, this also allows to compute the immaculate line bundles:

immaculate_line_bundlesMethod
immaculate_line_bundles(variety::NormalToricVarietyType)

Computes all immaculate line bundles as a toric vanishing set by intersecting the vanishing sets for all cohomology indices.

Examples

julia> dP1 = del_pezzo_surface(NormalToricVariety, 1)
-Normal toric variety
-
-julia> ilb = immaculate_line_bundles(dP1)
-Toric vanishing set for cohomology indices [0, 1, 2]
-
-julia> polyhedra(ilb)
-4-element Vector{Polyhedron{QQFieldElem}}:
- Polyhedron in ambient dimension 2
- Polyhedron in ambient dimension 2
- Polyhedron in ambient dimension 2
- Polyhedron in ambient dimension 2
-
-julia> print_constraints(polyhedra(ilb)[1])
--x_1 <= 0
--x_1 + x_2 <= 0
-
-julia> print_constraints(polyhedra(ilb)[2])
--x_1 + x_2 <= 0
-x_2 <= -2
-
-julia> print_constraints(polyhedra(ilb)[3])
--x_2 <= -1
-x_1 - x_2 <= -2
-
-julia> print_constraints(polyhedra(ilb)[4])
-x_1 - x_2 <= -2
-x_1 <= -3
source
diff --git a/previews/PR4245/AlgebraicGeometry/ToricVarieties/intro/index.html b/previews/PR4245/AlgebraicGeometry/ToricVarieties/intro/index.html deleted file mode 100644 index ef83dd7985b4..000000000000 --- a/previews/PR4245/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:

  • torus-invariant divisor (classes),
  • line bundles,
  • line bundle cohomology via cohomCalg (cf. [BJRR10*1]),
  • vanishing sets of line bundle cohomology (cf. Appendix B of [Bie18]),
  • cohomology ring and cohomology classes,
  • Chow ring, algebraic cycles and intersection theory,
  • elementary support for closed subvarieties.

Status

This project is work-in-progress.

Tutorial

We provide a tutorial for toric geometry in OSCAR.

Long term goals

We follow [CLS11]. Our long term goals include the following:

  • Ensure that one can perform all computations of Appendix B in [CLS11].
  • Provide support for coherent sheaves and their sheaf cohomologies. In particular, the existing algorithms in ToricVarieties_project (based on [Bie18]) should eventually be available in OSCAR.

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/PR4245/AlgebraicGeometry/intro/index.html b/previews/PR4245/AlgebraicGeometry/intro/index.html deleted file mode 100644 index e02a80ea66e1..000000000000 --- a/previews/PR4245/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,

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/PR4245/Combinatorics/EnumerativeCombinatorics/compositions/index.html b/previews/PR4245/Combinatorics/EnumerativeCombinatorics/compositions/index.html deleted file mode 100644 index c866475cecbf..000000000000 --- a/previews/PR4245/Combinatorics/EnumerativeCombinatorics/compositions/index.html +++ /dev/null @@ -1,49 +0,0 @@ - -Compositions · Oscar.jl

Compositions

A weak composition of a non-negative integer $n$ is a sequence $\lambda_1,\dots,\lambda_k$ of non-negative integers $\lambda_i$ such that $n = \lambda_1 + \dots + \lambda_k$. A composition of $n$ is a weak composition consisting of positive integers. The $\lambda_i$ are called the parts of the (weak) composition.

weak_compositionFunction
weak_composition(parts::Vector{T}; check::Bool = true) where T <: IntegerUnion

Return the weak composition given by the integer sequence parts as an object of type WeakComposition{T}.

If check is true (default), it is checked whether the given sequence defines a weak composition, that is, whether all elements of parts are non-negative.

Examples

julia> W = weak_composition([6, 0, 2, 3]) # the weak composition 6, 0, 2, 3 of 11
-[6, 0, 2, 3]
-
-julia> W = weak_composition(Int8[6, 0, 2, 3]) # save the elements in 8-bit integers
-Int8[6, 0, 2, 3]
source
compositionFunction
composition(parts::Vector{T}; check::Bool = true) where T <: IntegerUnion

Return the composition given by the integer sequence parts as an object of type Composition{T}.

If check is true (default), it is checked whether the given sequence defines a composition, that is, whether all elements of parts are positive.

Examples

julia> C = composition([6, 1, 2, 3]) # the composition 6, 1, 2, 3 of 12
-[6, 1, 2, 3]
-
-julia> C = composition(Int8[6, 1, 2, 3]) # save the elements in 8-bit integers
-Int8[6, 1, 2, 3]
source

Generating and counting

Unrestricted compositions

compositionsMethod
compositions(n::IntegerUnion)

Return an iterator over all compositions of a non-negative integer n.

By a composition of n we mean a sequence of positive integers whose sum is n.

Examples

julia> C = compositions(4)
-Iterator over the compositions of 4
-
-julia> collect(C)
-8-element Vector{Composition{Int64}}:
- [4]
- [3, 1]
- [2, 2]
- [1, 3]
- [2, 1, 1]
- [1, 2, 1]
- [1, 1, 2]
- [1, 1, 1, 1]
source
number_of_compositionsMethod
number_of_compositions(n::IntegerUnion)

Return the number of compositions of the non-negative integer n. For n < 0, return 0.

source

Note that an integer $n$ has infinitely many weak compositions as one may always append zeros to the end of a given weak composition. Without restrictions on the number of parts, we can hence only generate compositions, but not weak compositions.

Restricted compositions

compositionsMethod
compositions(n::IntegerUnion, k::IntegerUnion)

Return an iterator over all compositions of a non-negative integer n into k parts, produced in lexicographically descending order.

By a composition of n into k parts we mean a sequence of k positive integers whose sum is n.

Examples

julia> C = compositions(4, 2)
-Iterator over the compositions of 4 into 2 parts
-
-julia> collect(C)
-3-element Vector{Composition{Int64}}:
- [3, 1]
- [2, 2]
- [1, 3]
source
number_of_compositionsMethod
number_of_compositions(n::IntegerUnion, k::IntegerUnion)

Return the number of compositions of the non-negative integer n into k >= 0 parts. If n < 0 or k < 0, return 0.

source

Restricted weak compositions

weak_compositionsFunction
weak_compositions(n::IntegerUnion, k::IntegerUnion)

Return an iterator over all weak compositions of a non-negative integer n into k parts, produced in lexicographically descending order. Using a smaller integer type for n (e.g. Int8) may increase performance.

By a weak composition of n into k parts we mean a sequence of k non-negative integers whose sum is n.

Examples

julia> W = weak_compositions(3, 2)
-Iterator over the weak compositions of 3 into 2 parts
-
-julia> length(W)
-4
-
-julia> collect(W)
-4-element Vector{WeakComposition{Int64}}:
- [3, 0]
- [2, 1]
- [1, 2]
- [0, 3]
source
number_of_weak_compositionsMethod
number_of_weak_compositions(n::IntegerUnion, k::IntegerUnion)

Return the number of weak compositions of the non-negative integer n into k >= 0 parts. If n < 0 or k < 0, return 0.

source

Ascending compositions

ascending_compositionsFunction
ascending_compositions(n::IntegerUnion)

Return an iterator over all ascending compositions of a non-negative integer n.

By a ascending composition of n we mean a non-decreasing sequence of positive integers whose sum is n.

The implemented algorithm is "AccelAsc" (Algorithm 4.1) in [KO14].

Examples

julia> C = ascending_compositions(4)
-Iterator over the ascending compositions of 4
-
-julia> collect(C)
-5-element Vector{Composition{Int64}}:
- [1, 1, 1, 1]
- [1, 1, 2]
- [1, 3]
- [2, 2]
- [4]
source

The number of ascending compositions of $n$ coincides with the number of partitions of $n$.

diff --git a/previews/PR4245/Combinatorics/EnumerativeCombinatorics/partitions/index.html b/previews/PR4245/Combinatorics/EnumerativeCombinatorics/partitions/index.html deleted file mode 100644 index 3ce121f808fe..000000000000 --- a/previews/PR4245/Combinatorics/EnumerativeCombinatorics/partitions/index.html +++ /dev/null @@ -1,86 +0,0 @@ - -Partitions · Oscar.jl

Partitions

A partition of a non-negative integer $n$ is a decreasing sequence $\lambda_1 \geq \lambda_2\geq \dots \geq \lambda_r$ of positive integers $\lambda_i$ such that $n = \lambda_1 + \dots + \lambda_r$. The $\lambda_i$ are called the parts of the partition and $r$ is called the length. General references on partitions are [Ful97] and [Knu11], Section 7.2.1.4.

A partition can be encoded as an array with elements $\lambda_i$. In OSCAR, the parametric type Partition{T} is provided which is a subtype of AbstractVector{T}. Here, T can be any subtype of IntegerUnion. 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.

partitionFunction
partition([T::Type{<:IntegerUnion}], parts::IntegerUnion...; check::Bool = true)
-partition(parts::Vector{T}; check::Bool = true) where T <: IntegerUnion

Return the partition given by the integer sequence parts as an object of type Partition{T}.

The element type T may be optionally specified, see also the examples below.

If check is true (default), it is checked whether the given sequence defines a partition.

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) # the same partition
-[6, 4, 4, 2]
-
-julia> P = partition(Int8, 6, 4, 4, 2) # save the elements in 8-bit integers
-Int8[6, 4, 4, 2]
source

Because Partition is a subtype of AbstractVector, all functions that can be used for vectors (1-dimensional arrays) can be used for partitions as well.

julia> P = partition(6, 4, 4, 2)
-[6, 4, 4, 2]
-
-julia> length(P)
-4
-
-julia> P[1]
-6

However, usually, $|\lambda| := n$ is called the size of $\lambda$. In Julia, the function size for arrays already exists and returns the dimension of an array. Instead, one 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

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. For this, OSCAR provides the function getindex_safe:

getindex_safeFunction
getindex_safe(P::Partition, i::IntegerUnion)

Return P[i] if i < length(P) and 0 otherwise. It is assumed that i is positive.

Examples

julia> P = partition([3, 2, 1])
-[3, 2, 1]
-
-julia> getindex_safe(P, 3)
-1
-
-julia> getindex_safe(P, 4)
-0
source

If you are sure that P[i] exists, use getindex because this will be faster.

Generating and counting

partitionsMethod
partitions(n::IntegerUnion)

Return an iterator over all partitions of a non-negative integer n, produced in lexicographically descending order. Using a smaller integer type for n (e.g. Int8) may increase performance.

The algorithm used is "Algorithm ZS1" by [ZS98]. This algorithm is also discussed in [Knu11], Algorithm P (page 392).

Examples

julia> p = partitions(4);
-
-julia> first(p)
-[4]
-
-julia> collect(p)
-5-element Vector{Partition{Int64}}:
- [4]
- [3, 1]
- [2, 2]
- [2, 1, 1]
- [1, 1, 1, 1]
-
-julia> collect(partitions(Int8(4))) # using less memory
-5-element Vector{Partition{Int8}}:
- Int8[4]
- Int8[3, 1]
- Int8[2, 2]
- Int8[2, 1, 1]
- Int8[1, 1, 1, 1]
source
number_of_partitionsMethod
number_of_partitions(n::IntegerUnion)

Return the number of integer partitions of n. For n < 0, return 0.

Examples

julia> number_of_partitions(1000)
-24061467864032622473692149727991
source

For counting partitions, the Hardy-Ramanujan-Rademachen formula is used, see [Joh12] for details. See also [Knu11], Section 7.2.1.4 and [OEIS], A000041.

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. 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> collect(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(collect(partitions(100, [1, 2, 5, 10, 20, 50])))
-4562

The original "Ways to change one dollar" problem has 292 solutions:

julia> length(collect(partitions(100, [1, 5, 10, 25, 50])))
-292
number_of_partitionsMethod
number_of_partitions(n::IntegerUnion, k::IntegerUnion)

Return the number of integer partitions of the non-negative integer n into k >= 0 parts. If n < 0 or k < 0, return 0.

source

For counting the partitions the recurrence relation $p_k(n) = p_{k - 1}(n - 1) + p_k(n - k)$ is used, where $p_k(n)$ denotes the number of partitions of $n$ into $k$ parts; see [Knu11], Section 7.2.1.4, Equation (39), and also [OEIS], A008284.

partitionsMethod
partitions(n::IntegerUnion, k::IntegerUnion; only_distinct_parts::Bool = false)
-partitions(n::IntegerUnion, k::IntegerUnion, lb::IntegerUnion, ub::IntegerUnion; only_distinct_parts::Bool = false)

Return an iterator over all partitions of a non-negative integer n into k >= 0 parts. Optionally, a lower bound lb >= 0 and an upper bound ub for the parts can be supplied. In this case, the partitions are produced in decreasing order.

There are two choices for the parameter only_distinct_parts:

  • false: no further restriction (default);
  • true: only distinct parts.

The implemented algorithm is "parta" in [RJ76].

Examples

All partitions of 7 into 3 parts:

julia> collect(partitions(7, 3))
-4-element Vector{Partition{Int64}}:
- [5, 1, 1]
- [4, 2, 1]
- [3, 3, 1]
- [3, 2, 2]

All partitions of 7 into 3 parts where all parts are between 1 and 4:

julia> collect(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> collect(partitions(7, 3, 1, 4; only_distinct_parts = true))
-1-element Vector{Partition{Int64}}:
- [4, 2, 1]
source
partitionsMethod
partitions(n::T, v::Vector{T}) where T <: IntegerUnion
-partitions(n::T, v::Vector{T}, mu::Vector{<:IntegerUnion}) where T <: IntegerUnion
-partitions(n::T, k::IntegerUnion, v::Vector{T}, mu::Vector{<:IntegerUnion}) where T <: IntegerUnion

Return an iterator over all partitions of a non-negative integer n where each part is an element in the vector v of positive integers. It is assumed that the entries in v are strictly increasing.

If the optional vector mu is supplied, then each v[i] occurs a maximum of mu[i] > 0 times per partition.

If the optional integer k >= 0 is supplied, the partitions will be into k parts. In this case, the partitions are produced in lexicographically decreasing order.

The implemented algorithm is "partb" in [RJ76].

Example

The number of partitions of 100 where the parts are from {1, 2, 5, 10, 20, 50}:

julia> length(collect(partitions(100, [1, 2, 5, 10, 20, 50])))
-4562

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> collect(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]

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> collect(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]
source

Operations

The conjugate of a partition $\lambda$ is obtained by considering its Young diagram (see Tableaux) and then flipping it along its main diagonal, see [Ful97], page 2, and [Knu11], Section 7.2.1.4.

conjugateFunction
conjugate(lambda::Partition)

Return the conjugate of the partition lambda.

Examples

julia> conjugate(partition(8, 8, 8, 7, 2, 1, 1))
-[7, 5, 4, 4, 4, 4, 4, 3]
source

Relations

The dominance order on partitions is the partial order $\trianglerighteq$ defined by $\lambda \trianglerighteq\mu$ if and only if $\lambda_1 + \dots + \lambda_i \geq \mu_1 + \dots + \mu_i$ for all $i$. If $\lambda\trianglerighteq\mu$ one says that $\lambda$ dominates $\mu$. See [Ful97], page 26, and [Knu11], Section 7.2.1.4, Exercise 54.

Note that whereas the lexicographic ordering is a total ordering, the dominance ordering is not. Further, [Knu11] says majorizes instead of dominates and uses the symbol $\succeq$ instead of $\trianglerighteq$.

dominatesFunction
dominates(lambda::Partition, mu::Partition)

Return true if lambda dominates mu, false otherwise.

Examples

julia> dominates(partition(3, 1), partition(2, 2))
-true
-
-julia> dominates(partition(4, 1), partition(3, 3))
-false
source
diff --git a/previews/PR4245/Combinatorics/EnumerativeCombinatorics/schur_polynomials/index.html b/previews/PR4245/Combinatorics/EnumerativeCombinatorics/schur_polynomials/index.html deleted file mode 100644 index d17968032296..000000000000 --- a/previews/PR4245/Combinatorics/EnumerativeCombinatorics/schur_polynomials/index.html +++ /dev/null @@ -1,17 +0,0 @@ - -Schur polynomials · Oscar.jl

Schur polynomials

Given a partition $\lambda$ with $n$ parts, the Schur polynomial is defined to be the polynomial

\[s_\lambda := \sum x_1^{m_1}\dots x_n^{m_n}\]

where the sum is taken over all semistandard tableaux $T$ of shape $\lambda$ and $m_i$ is the weight of $i$ in $T$.

There are two different algorithms for the computation of a Schur polynomial implemented which are automatically selected depending on the size of the input.

For small integers or if $n\geq 10$, the combinatorial algorithm is used. This algorithm directly applies the above definition.

In the other cases, 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^{\lambda_1 + n - 1} & x_2^{\lambda_1 + n - 1} & \dots & x_n^{\lambda_1 + n - 1} \\ -x_1^{\lambda_2 + n - 2} & x_2^{\lambda_2 + n - 2} & \dots & x_n^{\lambda_2 + n - 2} \\ -\vdots & \vdots & \ddots & \vdots \\ -x_1^{\lambda_n} & x_2^{\lambda_n} & \dots & x_n^{\lambda_n} -\end{vmatrix}\]

is used.

schur_polynomialFunction
schur_polynomial([R::ZZMPolyRing], lambda::Partition, n::Int = length(lambda))

Return the Schur polynomial s of the partition lambda in n variables.

The ambient ring of s may optionally be supplied as a first argument.

Examples

julia> R, _ = 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
source
diff --git a/previews/PR4245/Combinatorics/EnumerativeCombinatorics/tableaux/index.html b/previews/PR4245/Combinatorics/EnumerativeCombinatorics/tableaux/index.html deleted file mode 100644 index 89e59ed8e76a..000000000000 --- a/previews/PR4245/Combinatorics/EnumerativeCombinatorics/tableaux/index.html +++ /dev/null @@ -1,49 +0,0 @@ - -Tableaux · Oscar.jl

Tableaux

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 $\lambda$ of a non-negative integer $n$ (the total number of boxes of the diagram). The diagram is then said to be of shape $\lambda$. Conversely, one can associate to any partition $\lambda$ a Young diagram in the obvious way, so Young diagrams are just another way to look at partitions.

A Young tableau of shape $\lambda$ is a filling of the boxes of the Young diagram of $\lambda$ 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$.

In OSCAR, a tableau is internally stored as an array of arrays and is represented by the type YoungTableau{T} which is a subtype of AbstractVector{AbstractVector{T}}, where T is the integer type of the filling. As for partitions, one may increase performance by casting into smaller integer types, e.g. Int8.

young_tableauFunction
young_tableau([::Type{T}], v::Vector{Vector{<:IntegerUnion}}; check::Bool = true) where T <: IntegerUnion

Return the Young tableau given by v as an object of type YoungTableau{T}.

The element type T may be optionally specified, see also the examples below.

If check is true (default), it is checked whether v defines a tableau, that is, whether the structure of v defines a partition.

Examples

julia> young_tableau([[1, 2, 3], [4, 5], [6]])
-+---+---+---+
-| 1 | 2 | 3 |
-+---+---+---+
-| 4 | 5 |
-+---+---+
-| 6 |
-+---+
-
-julia> young_tableau(Int8, [[1, 2, 3], [4, 5], [6]]) # save the elements in 8-bit integers
-+---+---+---+
-| 1 | 2 | 3 |
-+---+---+---+
-| 4 | 5 |
-+---+---+
-| 6 |
-+---+
source

Operations

hook_lengthFunction
hook_length(tab::YoungTableau, i::Integer, j::Integer)
-hook_length(lambda::Partition, i::Integer, j::Integer)

Return the hook length of the box with coordinates (i, j) in the Young tableau tab respectively the Young diagram of shape lambda.

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.

See also hook_lengths.

source
hook_lengthsFunction
hook_lengths(lambda::Partition)

Return the Young tableau of shape lambda in which the entry at position (i, j) is equal to the hook length of the corresponding box.

See also hook_length.

source
shapeFunction
shape(tab::YoungTableau)

Return the shape of the tableau tab, i.e. the partition given by the lengths of the rows of the tableau.

source
weightFunction
weight(tab::YoungTableau)

Return the weight of the tableau tab as an array whose i-th element gives the number of times the integer i appears in the tableau.

source
reading_wordFunction
reading_word(tab::YoungTableau)

Return the reading word of the tableau tab as an array, i.e. the word obtained by concatenating the fillings of the rows, starting from the bottom row.

Examples

julia> reading_word(young_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::YoungTableau)

Return true if the tableau tab is semistandard and false otherwise.

A tableau is called semistandard if the entries weakly increase along each row and strictly increase down each column.

See also is_standard.

source
semistandard_tableauxFunction
semistandard_tableaux(shape::Partition{T}, max_val::T = sum(shape)) where T <: IntegerUnion
-semistandard_tableaux(shape::Vector{T}, max_val::T = sum(shape)) where T <: IntegerUnion

Return an iterator over all semistandard Young tableaux of given shape 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(box_num::T, max_val::T = box_num) where T <: Integer

Return an iterator over all semistandard Young tableaux consisting of box_num boxes and filling elements bounded by max_val.

source
semistandard_tableaux(s::Partition{T}, weight::Vector{T}) where T <: Integer
-semistandard_tableaux(s::Vector{T}, weight::Vector{T}) where T <: Integer

Return an iterator over all semistandard Young tableaux with shape s and given weight. This requires that sum(s) = sum(weight).

source

Standard tableaux

is_standardFunction
is_standard(tab::YoungTableau)

Return true if the tableau tab is standard and false otherwise.

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.

See also is_semistandard.

source
standard_tableauxFunction
standard_tableaux(s::Partition)
-standard_tableaux(s::Vector{Integer})

Return an iterator over all standard Young tableaux of a given shape s.

source
standard_tableaux(n::IntegerUnion)

Return an iterator over all standard Young tableaux with n boxes.

source

The number $f^\lambda$ of standard Young tableaux of shape $\lambda$ is computed using the hook length formula

\[f^\lambda = \frac{n!}{\prod_{i, j} h_\lambda(i, j)},\]

where the product is taken over all boxes in the Young diagram of $\lambda$ and $h_\lambda$ denotes the hook length of the box $(i, j)$.

schenstedFunction
schensted(sigma::Vector{<:IntegerUnion})
-schensted(sigma::PermGroupElem)

Return the pair of standard Young tableaux (the insertion and the recording tableau) corresponding to the permutation sigma under the Robinson-Schensted correspondence.

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 |
-+---+
-
source
bump!Function
bump!(tab::YoungTableau, x::Int)

Insert the integer x into the tableau tab according to the bumping algorithm by applying the Schensted insertion.

source
bump!(tab::YoungTableau, x::Integer, Q::YoungTableau, y::Integer)

Insert the integer x into tab according to the bumping algorithm by applying the Schensted insertion and insert the integer y into Q at the same position as x in tab.

source
diff --git a/previews/PR4245/Combinatorics/graphs/index.html b/previews/PR4245/Combinatorics/graphs/index.html deleted file mode 100644 index d7ba8c123453..000000000000 --- a/previews/PR4245/Combinatorics/graphs/index.html +++ /dev/null @@ -1,296 +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> n_vertices(g)
-5
-
-julia> n_edges(g)
-0
source
dual_graphMethod
dual_graph(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 = dual_graph(c);
-
-julia> n_vertices(g)
-6
-
-julia> n_edges(g)
-12
source
vertex_edge_graphMethod
vertex_edge_graph(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. If the polyhedron has lineality, then it has no vertices or bounded edges, so the vertex_edge_graph will be the empty graph. In this case, the keyword argument can be used to consider the polyhedron modulo its lineality space.

Examples

Construct the edge graph of the cube. Like the cube it has 8 vertices and 12 edges.

julia> c = cube(3);
-
-julia> g = vertex_edge_graph(c);
-
-julia> n_vertices(g)
-8
-
-julia> n_edges(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)
-Directed graph with 2 nodes and the following edges:
-(2, 1)
-
-julia> graph_from_adjacency_matrix(Undirected, G)
-Undirected graph with 2 nodes and the following edges:
-(2, 1)
-
source
graph_from_edgesFunction
graph_from_edges(edges::Vector{Vector{Int}})
-graph_from_edges(::Type{T}, edges::Vector{Vector{Int}}, n_vertices::Int=-1) where {T <:Union{Directed, Undirected}}

Creates a graph from a vector of edges. There is an optional input for number of vertices, graph_from_edges will ignore any negative integers and throw an error when the input is less than the maximum vertex index in edges.

Examples

julia> G = graph_from_edges([[1,3],[3,5],[4,5],[2,4],[2,3]])
-Undirected graph with 5 nodes and the following edges:
-(3, 1)(3, 2)(4, 2)(5, 3)(5, 4)
-
-julia> G = graph_from_edges(Directed, [[1,3]], 4)
-Directed graph with 4 nodes and the following edges:
-(1, 3)
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. Return true if a new edge (s,t) was added, false otherwise.

Examples

julia> g = Graph{Directed}(2);
-
-julia> add_edge!(g, 1, 2)
-true
-
-julia> add_edge!(g, 1, 2)
-false
-
-julia> n_edges(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. Return the number of vertices that were actually added to the graph g.

Examples

julia> g = Graph{Directed}(2);
-
-julia> n_vertices(g)
-2
-
-julia> add_vertices!(g, 5);
-
-julia> n_vertices(g)
-7
source
add_vertex!Method
add_vertex!(g::Graph{T}) where {T <: Union{Directed, Undirected}}

Add a vertex to the graph g. Return true if there a new vertex was actually added.

Examples

julia> g = Graph{Directed}(2);
-
-julia> n_vertices(g)
-2
-
-julia> add_vertex!(g)
-true
-
-julia> n_vertices(g)
-3
source
rem_edge!Method
rem_edge!(g::Graph{T}, s::Int64, t::Int64) where {T <: Union{Directed, Undirected}}
-rem_edge!(g::Graph{T}, e::Edge) where {T <: Union{Directed, Undirected}}

Remove edge (s,t) from the graph g. Return true if there was an edge from s to t and it got removed, false otherwise.

Examples

julia> g = Graph{Directed}(2);
-
-julia> add_edge!(g, 1, 2)
-true
-
-julia> n_edges(g)
-1
-
-julia> rem_edge!(g, 1, 2)
-true
-
-julia> n_edges(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. Return true if node v existed and was actually removed, false otherwise. Please note that this will shift the indices of the vertices with index larger than v, but it will preserve the vertex ordering.

Examples

julia> g = Graph{Directed}(2);
-
-julia> n_vertices(g)
-2
-
-julia> rem_vertex!(g, 1)
-true
-
-julia> n_vertices(g)
-1
source
rem_vertices!Method
rem_vertices!(g::Graph{T}, a::AbstractArray{Int64}) where {T <: Union{Directed, Undirected}}

Remove the vertices in a from the graph g. Return true if at least one vertex was removed. Please note that this will shift the indices of some of the remaining vertices, but it will preserve the vertex ordering.

Examples

julia> g = Graph{Directed}(2);
-
-julia> n_vertices(g)
-2
-
-julia> rem_vertices!(g, [1, 2])
-true
-
-julia> n_vertices(g)
-0
source

Auxiliary functions

adjacency_matrixMethod
adjacency_matrix(g::Graph{T}) where {T <: Union{Directed, Undirected}}

Return an unsigned (boolean) adjacency matrix representing a graph g. If g is undirected, the adjacency matrix will be symmetric. For g being directed, the adjacency matrix has a 1 at (u,v) if there is an edge u->v.

Examples

Adjacency matrix for a directed graph:

julia> G = Graph{Directed}(3)
-Directed graph with 3 nodes and no edges
-
-julia> add_edge!(G,1,3)
-true
-
-julia> add_edge!(G,1,2)
-true
-
-julia> adjacency_matrix(G)
-3×3 IncidenceMatrix
-[2, 3]
-[]
-[]
-
-
-julia> matrix(ZZ, adjacency_matrix(G))
-[0   1   1]
-[0   0   0]
-[0   0   0]

Adjacency matrix for an undirected graph:

julia> G = vertex_edge_graph(cube(2))
-Undirected graph with 4 nodes and the following edges:
-(2, 1)(3, 1)(4, 2)(4, 3)
-
-julia> adjacency_matrix(G)
-4×4 IncidenceMatrix
-[2, 3]
-[1, 4]
-[1, 4]
-[2, 3]
-
-
-julia> matrix(ZZ, adjacency_matrix(G))
-[0   1   1   0]
-[1   0   0   1]
-[1   0   0   1]
-[0   1   1   0]
source
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
degreeMethod
degree(g::Graph{T} [, v::Int64]) where {T <: Union{Directed, Undirected}}

Return the degree of the vertex v in the graph g. If v is missing, return the list of degrees of all vertices.

Examples

julia> g = vertex_edge_graph(icosahedron());
-
-julia> degree(g, 1)
-5
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 = vertex_edge_graph(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 = vertex_edge_graph(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 = vertex_edge_graph(triangle);
-
-julia> has_vertex(g, 1)
-true
-
-julia> has_vertex(g, 4)
-false
source
laplacian_matrixMethod
laplacian_matrix(g::Graph{T}) where {T <: Union{Directed, Undirected}}

Return the Laplacian matrix of the graph g. The Laplacian matrix of a graph can be written as the difference of D, where D is a quadratic matrix with the degrees of g on the diagonal, and the adjacency matrix of g. For an undirected graph, the Laplacian matrix is symmetric.

Examples

julia> G = vertex_edge_graph(cube(2))
-Undirected graph with 4 nodes and the following edges:
-(2, 1)(3, 1)(4, 2)(4, 3)
-
-julia> laplacian_matrix(G)
-[ 2   -1   -1    0]
-[-1    2    0   -1]
-[-1    0    2   -1]
-[ 0   -1   -1    2]
source
n_edgesMethod
n_edges(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 = vertex_edge_graph(c);
-
-julia> n_edges(g)
-12
source
n_verticesMethod
n_vertices(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 = vertex_edge_graph(c);
-
-julia> n_vertices(g)
-8
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
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
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(vertex_edge_graph(simplex(3)), dual_graph(simplex(3)))
-true
-
-julia> is_isomorphic(vertex_edge_graph(cube(3)), dual_graph(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(vertex_edge_graph(simplex(3)), dual_graph(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.

Quantum Automorphisms

quantum_automorphism_groupMethod
quantum_automorphism_group(G::Graph{Undirected})

Return the ideal that defines the quantum automorphism group of the undirected graph G.

Examples

julia> G = graph_from_edges([[1, 2], [2, 4]]);
-
-julia> qAut = quantum_automorphism_group(G);
-
-julia> length(gens(qAut))
-184
source
diff --git a/previews/PR4245/Combinatorics/intro/index.html b/previews/PR4245/Combinatorics/intro/index.html deleted file mode 100644 index 6b085c327f2d..000000000000 --- a/previews/PR4245/Combinatorics/intro/index.html +++ /dev/null @@ -1,2 +0,0 @@ - -Introduction · Oscar.jl
diff --git a/previews/PR4245/Combinatorics/matroids/index.html b/previews/PR4245/Combinatorics/matroids/index.html deleted file mode 100644 index 8834a455e526..000000000000 --- a/previews/PR4245/Combinatorics/matroids/index.html +++ /dev/null @@ -1,418 +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 [Oxl11].

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 [Oxl11].

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 [Oxl11].

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 [Oxl11].

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 [Oxl11].

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 [Oxl11].

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 [Oxl11].

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_matroidFunction
cycle_matroid(g::Graph{Undirected})

The cycle matroid of a graph g.

See Section 1.1 of [Oxl11].

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 [Oxl11].

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
matroid_from_matroid_hexMethod
matroid_from_matroid_hex(str::AbstractString)

Returns a matroid from a string of hex characters.

Examples

To retrieve the fano matroid from its hex encoding write:

julia> matroid_from_matroid_hex("r3n7_3f7eefd6f")
-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 [Oxl11].

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 [Oxl11]. 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 [Oxl11]. 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 [Oxl11].

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 [Oxl11].

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 [Oxl11].

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 [Oxl11].

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 [Oxl11].

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 [Oxl11].

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 [Oxl11].

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 [Oxl11].

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 [Oxl11].

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 [Oxl11].

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([::Type{Int},] M::Matroid)

Return the list of bases of the matroid M. If Int is passed as a first argument then the bases will be returned as indices instead of ground set elements.

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{Int64}}:
- []
- [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{Int64}}:
- [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 [Oxl11].

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{Int64}}:
- []
- [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{Int64}}:
- [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 [Oxl11]. 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 [Oxl11]. 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{Int64}}:
- []
- [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{Int64}}:
- [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 [Oxl11].

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 [Oxl11].

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 [Oxl11].

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 [Oxl11].

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 [Oxl11].

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 [Oxl11].

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 [Oxl11].

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 [Oxl11].

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 [Oxl11].

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 [Oxl11].

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())
-Int64[]
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())
-Int64[]
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 [Oxl11].

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 [Oxl11].

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 [Oxl11].

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 [Oxl11].

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 [Oxl11].

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 [Oxl11].

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 [Oxl11].

Examples

julia> tutte_connectivity(fano_matroid())
-3
-
-julia> tutte_connectivity(uniform_matroid(2,4))
-infinity
-
source
tutte_polynomialMethod
tutte_polynomial(M::Matroid)
-tutte_polynomial(M::Matroid; parent::ZZMPolyRing)
-tutte_polynomial(parent::ZZMPolyRing, 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 [Oxl11].

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)
-characteristic_polynomial(M::Matroid; parent::ZZPolyRing)
-characteristic_polynomial(parent::ZZPolyRing, 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 [Oxl11].

Examples

julia> characteristic_polynomial(fano_matroid())
-q^3 - 7*q^2 + 14*q - 8
-
source
reduced_characteristic_polynomialMethod
reduced_characteristic_polynomial(M::Matroid)
-reduced_characteristic_polynomial(M::Matroid; parent::ZZPolyRing)
-reduced_characteristic_polynomial(parent::ZZPolyRing, 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 [Oxl11].

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 of the matroid M.

Examples

To get the revlex basis encoding of the fano matroid and to produce a matrod form the encoding write:

julia> str = revlex_basis_encoding(fano_matroid())
-"0******0******0***0******0*0**0****"
-
-julia> matroid_from_revlex_basis_encoding(str, 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
matroid_hexMethod
matroid_hex(M::Matroid)

Stores a matroid as a string of hex characters. The first part of the string is "r" followed by the rank of the matroid. This is followed by "n" and the number of elements. The rest of the string is the revlex basis encoding. The encoding is done by converting the basis encoding to a vector of bits and then to a string of characters. The bits are padded to a multiple of 4 and then converted to hex characters.

Examples

To get the hex encoding of the fano matroid write:

julia> matroid_hex(fano_matroid())
-"r3n7_3f7eefd6f"
-
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)
-Permutation group of degree 4
source
matroid_base_polytopeMethod
matroid_base_polytope(M::Matroid)

The base polytope of the matroid M.

Examples

julia> D = matroid_base_polytope(uniform_matroid(2,4));
-
-julia> vertices(D)
-6-element SubObjectIterator{PointVector{QQFieldElem}}:
- [1, 1, 0, 0]
- [1, 0, 1, 0]
- [1, 0, 0, 1]
- [0, 1, 1, 0]
- [0, 1, 0, 1]
- [0, 0, 1, 1]
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 [AHK18] and [BES19].

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
augmented_chow_ringMethod
augmented_chow_ring(M::Matroid)

Return an augmented Chow ring of a matroid. As described in [BHMPW20].

Examples

julia> M = fano_matroid();
-
-julia> R = augmented_chow_ring(M);
source

Quantum Automorphisms

quantum_symmetric_groupMethod
quantum_symmetric_group(n::Int)

Return the ideal that defines the quantum symmetric group on n elements. It is comprised of 2*n + n^2 + 2*n*n*(n-1) many generators.

The relations are:

  • row and column sum relations: 2*n relations
  • idempotent relations: n^2 relations
  • relations of type u[i,j]*u[i,k] and u[j,i]*u[k,i] for k != j: 2*n*n*(n-1) relations

Example

julia> S4 = quantum_symmetric_group(4);
-
-julia> length(gens(S4))
-120
source
quantum_automorphism_groupMethod
quantum_automorphism_group(M::Matroid, structure::Symbol=:bases)

Return the ideal that defines the quantum automorphism group of a matroid for a given structure.

Examples

julia> G = complete_graph(4)
-Undirected graph with 4 nodes and the following edges:
-(2, 1)(3, 1)(3, 2)(4, 1)(4, 2)(4, 3)
-
-julia> M = cycle_matroid(G);
-
-julia> qAut = quantum_automorphism_group(M,:bases);
-
-julia> length(gens(qAut))
-23448
source
diff --git a/previews/PR4245/Combinatorics/phylogenetic_trees/index.html b/previews/PR4245/Combinatorics/phylogenetic_trees/index.html deleted file mode 100644 index b994dcaeea58..000000000000 --- a/previews/PR4245/Combinatorics/phylogenetic_trees/index.html +++ /dev/null @@ -1,91 +0,0 @@ - -Phylogenetic Trees · Oscar.jl

Phylogenetic Trees

Introduction

Phylogenetic trees represent the evolutionary history of some species of consideration. Here we consider phylogenetic trees with branch lengths as defined in [SS03].

Construction

phylogenetic_treeFunction
phylogenetic_tree(T::Type{<:Union{Float64, QQFieldElem}}, newick::String)

Constructs a rooted phylogenetic tree with Newick representation newick. T indicates the numerical type of the edge lengths.

Examples

Make a phylogenetic tree with 4 leaves from its Newick representation and print its taxa and cophenetic matrix.

julia> phylo_t = phylogenetic_tree(Float64, "((H:3,(C:1,B:1):2):1,G:4);");
-
-julia> taxa(phylo_t)
-4-element Vector{String}:
- "B"
- "C"
- "G"
- "H"
-
-julia> cophenetic_matrix(phylo_t)
-4×4 Matrix{Float64}:
- 0.0  2.0  8.0  6.0
- 2.0  0.0  8.0  6.0
- 8.0  8.0  0.0  8.0
- 6.0  6.0  8.0  0.0
source
phylogenetic_tree(M::Matrix{T}, taxa::Vector{String}) where T <: Union{Float64, QQFieldElem}

Constructs a phylogenetic tree with cophenetic matrix M and taxa taxa. The matrix M must be ultrametric, otherwise an error will be thrown.

Examples

Make a phylogenetic tree on 4 taxa with given cophenetic matrix and print one Newick representation.

julia> mat = [0. 2 8 6; 2 0 8 6; 8 8 0 8; 6 6 8 0]
-4×4 Matrix{Float64}:
- 0.0  2.0  8.0  6.0
- 2.0  0.0  8.0  6.0
- 8.0  8.0  0.0  8.0
- 6.0  6.0  8.0  0.0
-
-julia> tax = ["Bonobo", "Chimpanzee", "Gorilla", "Human"]
-4-element Vector{String}:
- "Bonobo"
- "Chimpanzee"
- "Gorilla"
- "Human"
-
-julia> tree_mat = phylogenetic_tree(mat, tax);
-
-julia> newick(tree_mat)
-"Gorilla:4,(Human:3,(Bonobo:1,Chimpanzee:1):2):1;"
source

Some Helpful Functions

adjacency_treeFunction
adjacency_tree(ptree::PhylogeneticTree)

Returns the underlying graph of the phylogenetic tree ptree.

Examples

Make a phylogenetic tree with given Newick format and print its underlying graph.

julia> ptree = phylogenetic_tree(Float64, "((H:3,(C:1,B:1):2):1,G:4);");
-
-julia> adjacency_tree(ptree)
-Directed graph with 7 nodes and the following edges:
-(1, 2)(1, 7)(2, 3)(2, 4)(4, 5)(4, 6)
source
is_equidistantFunction
is_equidistant(ptree::PhylogeneticTree)

Checks if the phylogenetic tree ptree is equidistant.

Examples

Make a phylogenetic tree with given Newick format and check if it is equidistant.

julia> ptree = phylogenetic_tree(Float64, "((H:3,(C:1,B:1):2):1,G:4);");
-
-julia> is_equidistant(ptree)
-true
source
cophenetic_matrixFunction
cophenetic_matrix(ptree::PhylogeneticTree)

Returns the cophenetic matrix of the phylogenetic tree ptree.

Examples

Make a phylogenetic tree with given Newick format and print its cophenetic matrix.

julia> ptree = phylogenetic_tree(Float64, "((H:3,(C:1,B:1):2):1,G:4);");
-
-julia> cophenetic_matrix(ptree)
-4×4 Matrix{Float64}:
- 0.0  2.0  8.0  6.0
- 2.0  0.0  8.0  6.0
- 8.0  8.0  0.0  8.0
- 6.0  6.0  8.0  0.0
source
taxaFunction
taxa(ptree::PhylogeneticTree)

Returns the taxa of the phylogenetic tree ptree.

Examples

Make a phylogenetic tree with given Newick format and print its taxa.

julia> ptree = phylogenetic_tree(Float64, "((H:3,(C:1,B:1):2):1,G:4);");
-
-julia> taxa(ptree)
-4-element Vector{String}:
- "B"
- "C"
- "G"
- "H"
source
newickFunction
newick(ptree::PhylogeneticTree)

Returns a Newick representation of the phylogenetic tree ptree.

Examples

Make a phylogenetic tree from a matrix and print a Newick representation of it.

julia> mat = [0. 2 8 6; 2 0 8 6; 8 8 0 8; 6 6 8 0]
-4×4 Matrix{Float64}:
- 0.0  2.0  8.0  6.0
- 2.0  0.0  8.0  6.0
- 8.0  8.0  0.0  8.0
- 6.0  6.0  8.0  0.0
-
-julia> tax = ["Bonobo", "Chimpanzee", "Gorilla", "Human"]
-4-element Vector{String}:
- "Bonobo"
- "Chimpanzee"
- "Gorilla"
- "Human"
-
-julia> tree_mat = phylogenetic_tree(mat, tax);
-
-julia> newick(tree_mat)
-"Gorilla:4,(Human:3,(Bonobo:1,Chimpanzee:1):2):1;"
source
tropical_median_consensusFunction
tropical_median_consensus(arr::Vector{PhylogeneticTree{T}})

Computes the tropical median consensus tree of the phylogenetic trees from the vector arr.

Examples

Compute the tropical median consensus of three trees and print one of its Newick representations.

julia> t1 = phylogenetic_tree(Float64, "((H:30,(C:10,B:10):20):10,G:40);");
-
-julia> t2 = phylogenetic_tree(Float64, "(((H:10,C:10):20,B:30):10,G:40);");
-
-julia> t3 = phylogenetic_tree(Float64, "((H:25,C:25):15,(B:15,G:15):25);");
-
-julia> arr = [t1, t2, t3];
-
-julia> tc = tropical_median_consensus(arr);
-
-julia> newick(tc)
-"G:40,(B:35,(C:30,H:30):5):5;"
source
tropical_median_consensus(trees::Vararg{PhylogeneticTree, N}) where {N}

Computes the tropical median consensus tree of any number of phylogenetic trees given as parameters.

Examples

Compute the tropical median consensus of three trees and print one of its Newick representations.

julia> t1 = phylogenetic_tree(Float64, "((H:30,(C:10,B:10):20):10,G:40);");
-
-julia> t2 = phylogenetic_tree(Float64, "(((H:10,C:10):20,B:30):10,G:40);");
-
-julia> t3 = phylogenetic_tree(Float64, "((H:25,C:25):15,(B:15,G:15):25);");
-
-julia> tc = tropical_median_consensus(t1, t2, t3);
-
-julia> newick(tc)
-"G:40,(B:35,(C:30,H:30):5):5;"
source
diff --git a/previews/PR4245/Combinatorics/simplicialcomplexes/index.html b/previews/PR4245/Combinatorics/simplicialcomplexes/index.html deleted file mode 100644 index a60e53aae10b..000000000000 --- a/previews/PR4245/Combinatorics/simplicialcomplexes/index.html +++ /dev/null @@ -1,141 +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

simplicial_complexMethod
simplical_complex(generators::Union{Vector{Vector{Int}}, Vector{Set{Int}}})

Construct an abstract simplicial complex from a set of faces. While arbitrary non-negative integers are allowed as vertices, they will be relabeled to consecutive integers starting at 1.

Examples

julia> K = simplicial_complex([[1,2,3],[2,3,4]])
-Abstract simplicial complex of dimension 2 on 4 vertices
-
-julia> G = complete_bipartite_graph(2,3)
-Undirected graph with 5 nodes and the following edges:
-(3, 1)(3, 2)(4, 1)(4, 2)(5, 1)(5, 2)
-
-julia> K = simplicial_complex(G)
-Abstract simplicial complex of dimension 1 on 5 vertices

Simplicial complex comprising the empty set only:

julia> empty = simplicial_complex(Vector{Set{Int}}([]))
-Abstract simplicial complex of dimension -1 on 0 vertices

The original vertices can be recovered:

julia> L = simplicial_complex([[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 = simplicial_complex([[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 = simplicial_complex([[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

n_verticesMethod
n_vertices(K::SimplicialComplex)

Return the number of vertices of the abstract simplicial complex K.

Examples

julia> n_vertices(torus())
-7
source
n_facetsMethod
n_facets(K::SimplicialComplex)

Return the number of facets of the abstract simplicial complex K.

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 integral homology group of K.

Examples

julia> [ homology(real_projective_plane(), i) for i in [0,1,2] ]
-3-element Vector{FinGenAbGroup}:
- Z
- Z/2
- 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 integral cohomology group of K.

Examples

julia> K = simplicial_complex([[0,1],[1,2],[0,2]]);
-
-julia> cohomology(K,1)
-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

Recognizing topological spaces

is_sphereMethod
is_sphere(K::SimplicialComplex)

Heuristically check if the abstract simplicial complex K is a combinatorial sphere; see [JLLT22]. Note that this is undecidable in general. Returns true if recognized as a sphere. Returns false if not a sphere. Returns nothing if heuristics unsuccessful.

Examples

julia> K = simplicial_complex([[1,2,3],[2,3,4]]);
-
-julia> is_sphere(K)
-false
source
is_ballMethod
is_ball(K::SimplicialComplex)

Heuristically check if the abstract simplicial complex K is a combinatorial ball; see [JLLT22]. Note that this is undecidable in general. Returns true if recognized as a ball. Returns false if not a ball. Returns nothing if heuristics unsuccessful.

Examples

julia> K = simplicial_complex([[1,2,3],[2,3,4]]);
-
-julia> is_ball(K)
-true
source
is_manifoldMethod
is_manifold(K::SimplicialComplex)

Check if the abstract simplicial complex K is a combinatorial manifold, possibly with boundary. Note that this is undecidable in general. Returns true if recognized as a manifold. Returns false if not a manifold. Returns nothing if heuristics unsuccessful.

Examples

julia> is_manifold(torus())
-true
-
-julia> is_manifold(simplicial_complex([[1,2],[2,3]]))
-true
-
-julia> is_manifold(simplicial_complex([[1,2],[2,3],[2,4]]))
-false
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 = simplicial_complex([[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 = simplicial_complex([[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 [BH09].

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 generated by
-  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 generated by
-  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 = simplicial_complex([[1,2,3],[2,3,4]]);
-
-julia> stanley_reisner_ring(K)
-(Quotient of multivariate polynomial ring by ideal (x1*x4), Map: multivariate polynomial ring -> quotient of multivariate polynomial ring)
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 (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), Map: R -> quotient of multivariate polynomial ring)
source

Helpful functions

is_isomorphicMethod
is_isomorphic(K1::SimplicialComplex, K2::SimplicialComplex)

Checks if the given simplicial complexes are isomorphic.

Examples

julia> K1 = simplicial_complex([[1,2,3],[2,3,4]]);
-
-julia> K2 = simplicial_complex([[1,2,3],[2,3,4]]);
-
-julia> is_isomorphic(K1, K2)
-true
source
connected_sumFunction
connected_sum(K1::SimplicialComplex, K2::SimplicialComplex, f1::Int=0, f2::Int=0)

Compute the connected sum of two abstract simplicial complexes. Parameters f1 and f2 specify which facet of the first and second complex correspondingly are glued together. Default is the 0-th facet of both. The vertices in the selected facets are identified with each other according to their order in the facet (that is, in increasing index order).

Examples

julia> K = torus();
-
-julia> surface_genus_2 = connected_sum(K, K)
-Abstract simplicial complex of dimension 2 on 11 vertices
-
-julia> homology(surface_genus_2, 1)
-Z^4
-
-julia> is_manifold(surface_genus_2)
-true
source
deletionMethod
deletion(K::SimplicialComplex, face::Union{<:AbstractSet{Int},<:AbstractVector{Int}})

Remove the given face and all the faces containing it from an abstract simplicial complex K.

Examples

julia> K = simplicial_complex([[1, 2, 3], [2, 3, 4]]);
-
-julia> K_with_deletion = deletion(K, Set([1, 2]));
-
-julia> facets(K_with_deletion)
-2-element Vector{Set{Int64}}:
- Set([3, 1])
- Set([4, 2, 3])
source
automorphism_groupMethod
automorphism_group(K::SimplicialComplex; action=:on_vertices)

Given a simplicial complex K return its automorphism group as a PermGroup. The group can be returned as a subgroup of the permutation group of the vertices by passing :on_vertices to the action keyword argument or on the facets by passing :on_facets.

Examples

julia> K = simplicial_complex([[1, 2, 3], [2, 3, 4]])
-Abstract simplicial complex of dimension 2 on 4 vertices
-
-julia> automorphism_group(K)
-Permutation group of degree 4
source
on_simplicial_complexMethod
on_simplicial_complex(K::SimplicialComplex, g::PermGroupElem)

Given a simplicial complex K return the simplicial complex corresponding to a permutation on it's vertices given by g.

Examples

julia> K = simplicial_complex([[1, 2, 3], [2, 3, 4]])
-Abstract simplicial complex of dimension 2 on 4 vertices
-
-julia> G = automorphism_group(K)
-Permutation group of degree 4
-
-julia> g = collect(G)[2]
-(1,4)
-
-julia> facets(on_simplicial_complex(K, g))
-2-element Vector{Set{Int64}}:
- Set([2, 3, 1])
- Set([4, 2, 3])
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/PR4245/CommutativeAlgebra/FrameWorks/module_localizations/index.html b/previews/PR4245/CommutativeAlgebra/FrameWorks/module_localizations/index.html deleted file mode 100644 index 4130596c383a..000000000000 --- a/previews/PR4245/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 [Pos18].

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 [Pos18], 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, [Pos18] 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/PR4245/CommutativeAlgebra/FrameWorks/ring_localizations/index.html b/previews/PR4245/CommutativeAlgebra/FrameWorks/ring_localizations/index.html deleted file mode 100644 index 007559c46519..000000000000 --- a/previews/PR4245/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 behavior 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 cancelation 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, number_of_generators, and gen must be realized.

Moreover, a method for ideal membership via the in function is required.

diff --git a/previews/PR4245/CommutativeAlgebra/GroebnerBases/groebner_bases/index.html b/previews/PR4245/CommutativeAlgebra/GroebnerBases/groebner_bases/index.html deleted file mode 100644 index 3ad8074f54eb..000000000000 --- a/previews/PR4245/CommutativeAlgebra/GroebnerBases/groebner_bases/index.html +++ /dev/null @@ -1,445 +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)).

default_orderingMethod
default_ordering(R::MPolyRing)

Return the monomial ordering that is used for computations with ideals in R if no other ordering is specified – either directly by the user or by requirements of a specific algorithm.

source

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 R
-
-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])

Expert users may temporarily choose a different default ordering for a given ring.

with_orderingFunction
with_ordering(f, R::MPolyRing, o::MonomialOrdering)

Use the monomial ordering o for computations in R during the execution of f. This may be used with do block syntax, see the example.

This functionality is meant for advanced users. In general it should not be necessary to explicitly set a monomial ordering. Further, there is no guarantee that o is actually used. For example, if an algorithm requires an elimination ordering, o might be ignored.

Example

julia> R, (x, y, z) = QQ[:x, :y, :z];
-
-julia> f = x + y^2;
-
-julia> I = ideal(R, [y^2 - z, x - z^2]);
-
-julia> normal_form(f, I) # this uses degrevlex
-x + z
-
-julia> with_ordering(R, lex(R)) do
-           # this uses lex
-           normal_form(f, I)
-       end
-z^2 + z

Notice that in this small example we could have achieved the same by using the keyword argument ordering:

julia> normal_form(f, I, ordering = lex(R))
-z^2 + z
source

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 R
-
-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.

reduceMethod
reduce(g::T, F::Union{Vector{T}, IdealGens{T}};
-       ordering::MonomialOrdering = default_ordering(g)), complete_reduction::Bool = false) 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::Union{Vector{T}, IdealGens{T}};
-       ordering::MonomialOrdering = default_ordering(parent(G[1])), complete_reduction::Bool = false) where T <: MPolyRingElem

Return a Vector which contains, for each element g of G, a remainder as above.

Note

The returned remainders are fully reduced if complete_reduction is set to true and ordering is global.

Note

The reduction strategy behind the reduce function and the reduction strategy behind the functions reduce_with_quotients and reduce_with_quotients_and_unit differ. As a consequence, the computed remainders may differ.

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> reduce(g, [f1, f2], ordering = lex(R))
--3*x^10 + x^6 + x^5
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> reduce(g, [f1, f2, f3], ordering = lex(R))
-x^5 + x^3*y + x^2*y^2*z^2 + z^6
-
-julia> reduce(g, [f1,f2, f3], ordering = lex(R), complete_reduction = true)
-x^5 - x^3 + y^6 + z^6
source
reduce_with_quotientsMethod
reduce_with_quotients(g::T, F::Union{Vector{T}, IdealGens{T}};
-       ordering::MonomialOrdering = default_ordering(parent(g)), complete_reduction::Bool = false) 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::Union{Vector{T}, IdealGens{T}};
-       ordering::MonomialOrdering = default_ordering(parent(G[1])), complete_reduction::Bool = false) where T <: MPolyRingElem

Return a Vector which contains, for each element g of G, quotients and a remainder as above.

Note

The returned remainders are fully reduced if complete_reduction is set to true and ordering is global.

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> Q, h = reduce_with_quotients(g, [f1,f2, f3], ordering = lex(R));
-
-julia> h
-x^5 - x^3 + y^6 + z^6
-
-julia> g == Q[1]*f1+Q[2]*f2+Q[3]*f3+h
-true
source
reduce_with_quotients_and_unitMethod
reduce_with_quotients_and_unit(g::T, F::Union{Vector{T}, IdealGens{T}};
-       ordering::MonomialOrdering = default_ordering(parent(g)), complete_reduction::Bool = false) 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::Union{Vector{T}, IdealGens{T}};
-       ordering::MonomialOrdering = default_ordering(parent(G[1])), complete_reduction::Bool = false) where T <: MPolyRingElem

Return a Vector which contains, for each element g of G, a unit, quotients, and a remainder as above.

Note

The returned remainders are fully reduced if complete_reduction is set to true and ordering is global.

Note

The reduction strategy behind the reduce function and the reduction strategy behind the functions reduce_with_quotients and reduce_with_quotients_and_unit differ. As a consequence, the computed remainders may differ.

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 = lex(R));
-
-julia> u
-[1]
-
-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 = negdegrevlex(R));
-
-julia> U
-[y + 1       0]
-[    0   y + 1]
-
-julia> Q
-[  x^3 - x*y^2*z^2 + x*y + y^2*z^2                            0   y*z^2 + z^2]
-[x*y*z^2 + y^3*z - 3*y^2*z^2 - y*z   -x^2*y*z - x^2*z + x*y + x             0]
-
-julia> H
-2-element Vector{QQMPolyRingElem}:
- 0
- 0
-
-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),
  • :modular (implementation of multi-modular approach, if applicable),
  • :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),
  • :modular (implementation of multi-modular approach, if applicable),
  • :f4 (implementation of Faugère's F4 algorithm in the msolve package),
  • :fglm (implementation of the FGLM algorithm in Singular),
  • :hc (implementation of Buchberger's algorithm in Singular trying to first compute the highest corner modulo some prime), and
  • :hilbert (implementation of a Hilbert driven Gröbner basis computation in Singular).
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 3 elements w.r.t. 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 1 element w.r.t. 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 [FGLM93] 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 [Fau99] for more information.

Note

At current state only prime fields of characteristic 0 < p < 2^{31} and the rationals 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
  • normalize::Bool=true: normalizes elements in computed Gröbner basis for I
  • truncate_lifting::Int=0: degree up to which the elements of the Gröbner basis are lifted to QQ, 0 for complete lifting
  • 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])
-(Multivariate polynomial ring in 3 variables over GF(101), FqMPolyRingElem[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 generated by
-  x + 2*y + 2*z + 100
-  x^2 + 100*x + 2*y^2 + 2*z^2
-  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 generated by
-  x*y^2
-  y^5
-
-julia> L = leading_ideal([x*y^2-3*x, x^3-14*y^5], ordering=lex(R))
-Ideal generated by
-  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 generated by
-  x*y^2 - 3*x
-  x^3 - 14*y^5
-
-julia> L = leading_ideal(I, ordering=degrevlex(R))
-Ideal generated by
-  x*y^2
-  x^4
-  y^5
-
-julia> L = leading_ideal(I, ordering=lex(R))
-Ideal generated by
-  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 generated by
-  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 generated by
-  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(
-    a::Vector{T};
-    parent::Union{FreeMod{T}, Nothing} = nothing
-  ) where {T<:RingElem}

Return generators for the syzygies on the polynomials given as elements of a. The optional keyword argument can be used to specify the parent of the output.

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/PR4245/CommutativeAlgebra/GroebnerBases/groebner_bases_integers/index.html b/previews/PR4245/CommutativeAlgebra/GroebnerBases/groebner_bases_integers/index.html deleted file mode 100644 index 24a4f57fed10..000000000000 --- a/previews/PR4245/CommutativeAlgebra/GroebnerBases/groebner_bases_integers/index.html +++ /dev/null @@ -1,24 +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 [AL94] 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 generated by
-  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/PR4245/CommutativeAlgebra/GroebnerBases/orderings/index.html b/previews/PR4245/CommutativeAlgebra/GroebnerBases/orderings/index.html deleted file mode 100644 index 57c9af6fa876..000000000000 --- a/previews/PR4245/CommutativeAlgebra/GroebnerBases/orderings/index.html +++ /dev/null @@ -1,459 +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 \mathbb{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 \mathbb{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 $ \mathbb{N}^n$ such that $\alpha > \beta$ implies $ \gamma + \alpha > \gamma + \beta$ for all $\alpha , \beta, \gamma \in \mathbb{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 $\mathbb{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 R
-
-julia> cmp(lex(R)*invlex(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 }\; (\deg(x^\alpha) = \deg(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).\]

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 Inverse Lexicographical Ordering

The inverse lexicographical ordering invlex 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.\]

invlexMethod
invlex(R::MPolyRing) -> MonomialOrdering

Return the inverse lexicographical ordering on the set of monomials in the variables of R.

invlex(V::AbstractVector{<:MPolyRingElem}) -> MonomialOrdering

Given a vector V of variables, return the inverse 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 = invlex(R)
-invlex([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 = invlex([w, x])
-invlex([w, x])
-
-julia> o3 = invlex(gens(R)[3:4])
-invlex([y, z])
source

The Degree Inverse Lexicographical Ordering

The degree inverse lexicographical ordering deginvlex is defined by setting

\[x^\alpha > x^\beta \; \Leftrightarrow \deg(x^\alpha) > \deg(x^\beta) \;\text{ or }\;(\deg(x^\alpha) = \deg(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).\]

deginvlexMethod
deginvlex(R::MPolyRing) -> MonomialOrdering

Return the degree inverse lexicographical ordering on the set of monomials in the variables of R.

deginvlex(V::AbstractVector{<:MPolyRingElem}) -> MonomialOrdering

Given a vector V of variables, return the degree inverse 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 = deginvlex(R)
-deginvlex([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 = deginvlex([w, x])
-deginvlex([w, x])
-
-julia> o3 = deginvlex(gens(R)[3:4])
-deginvlex([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 }\;(\deg(x^\alpha) = \deg(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).\]

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 }\; (\deg(x^\alpha) = \deg(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).\]

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 Inverse Lexicographical Ordering

The negative inverse lexicographical ordering neginvlex 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.\]

neginvlexMethod
neginvlex(R::MPolyRing) -> MonomialOrdering

Return the negative inverse lexicographical ordering on the set of monomials in the variables of R.

neginvlex(V::AbstractVector{<:MPolyRingElem}) -> MonomialOrdering

Given a vector V of variables, return the negative inverse 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 = neginvlex(R)
-neginvlex([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 = neginvlex([w, x])
-neginvlex([w, x])
-
-julia> o3 = neginvlex(gens(R)[3:4])
-neginvlex([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 }\;(\deg(x^\alpha) = \deg(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).\]

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{<:IntegerUnion}, 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::MonomialOrdering)

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 invlex. 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 R
-
-julia> o1 = degrevlex(R)*invlex(gens(F))
-degrevlex([w, x, y, z])*invlex([gen(1), gen(2), gen(3)])
-
-julia> o2 = invlex(gens(F))*degrevlex(R)
-invlex([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 R
-
-julia> o = invlex(gens(F))*degrevlex(R)
-invlex([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/PR4245/CommutativeAlgebra/Miscellaneous/binomial_ideals/index.html b/previews/PR4245/CommutativeAlgebra/Miscellaneous/binomial_ideals/index.html deleted file mode 100644 index 783676e86380..000000000000 --- a/previews/PR4245/CommutativeAlgebra/Miscellaneous/binomial_ideals/index.html +++ /dev/null @@ -1,147 +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 generated by
-  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 generated by
-  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 generated by
-  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 generated by
-  x + y
-
-julia> is_unital(I)
-false
-
-julia> J = ideal(R, [x^2-y^3, z^2])
-Ideal generated by
-  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 generated by
-  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 generated by
-  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 generated by
-  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 generated by
-  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{QQAbFieldElem{AbsSimpleNumFieldElem}}}}:
- 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 generated by
-  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{QQAbFieldElem{AbsSimpleNumFieldElem}}}}:
- 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 generated by
-  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{QQAbFieldElem{AbsSimpleNumFieldElem}}}, MPolyIdeal{AbstractAlgebra.Generic.MPoly{QQAbFieldElem{AbsSimpleNumFieldElem}}}}}:
- (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 generated by
-  x - y
-  x^3 - 1
-  y^2*z - z
-
-julia> binomial_primary_decomposition(I)
-3-element Vector{Tuple{MPolyIdeal{AbstractAlgebra.Generic.MPoly{QQAbFieldElem{AbsSimpleNumFieldElem}}}, MPolyIdeal{AbstractAlgebra.Generic.MPoly{QQAbFieldElem{AbsSimpleNumFieldElem}}}}}:
- (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/PR4245/CommutativeAlgebra/ModulesOverMultivariateRings/complexes/index.html b/previews/PR4245/CommutativeAlgebra/ModulesOverMultivariateRings/complexes/index.html deleted file mode 100644 index 31a97e4eada4..000000000000 --- a/previews/PR4245/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/PR4245/CommutativeAlgebra/ModulesOverMultivariateRings/free_modules/index.html b/previews/PR4245/CommutativeAlgebra/ModulesOverMultivariateRings/free_modules/index.html deleted file mode 100644 index 77579bf1de7c..000000000000 --- a/previews/PR4245/CommutativeAlgebra/ModulesOverMultivariateRings/free_modules/index.html +++ /dev/null @@ -1,395 +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 modeled 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 R
-
-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 R at complement of prime ideal (x, y, z)
-
-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 RQ 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{FinGenAbGroupElem})

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])
-Z^2
-
-julia> g = gens(G)
-2-element Vector{FinGenAbGroupElem}:
- [1, 0]
- [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 (x*y), Map: R -> S)
-
-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::AdmissibleModuleFPRing, p::Int, W::Vector{FinGenAbGroupElem}=[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::AdmissibleModuleFPRing, W::Vector{FinGenAbGroupElem}, 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)
-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::AdmissibleModuleFPRing, 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::AdmissibleModuleFPRing, W::Union{ZZMatrix, Matrix{<:IntegerUnion}}, name::String="e")

As above, converting the columns of W.

graded_free_module(R::AdmissibleModuleFPRing, 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), number_of_generators(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)
-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{FinGenAbGroupElem}:
- [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 modeled 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 R
-
-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{T}; check::Bool=true) where {T<:AnyGradedRingElem}

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.

If check is set to false, then there is no check for homegeneity. This should be called internally on provably sane input, as it speeds up computation significantly.

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))
-FinGenAbGroupElem
-
-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> Rg, (x, y, z) = graded_polynomial_ring(QQ, [:x, :y, :z]);
-
-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 R
-
-julia> G = free_module(R, 2)
-Free module of rank 2 over R
-
-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 R
-Codomain:
-=========
-Free module of rank 2 over R
-
-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 R
-Codomain:
-=========
-Free module of rank 2 over R
-
-julia> a == b
-true
julia> Rg, (x, y, z) = graded_polynomial_ring(QQ, [:x, :y, :z]);
-
-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 R
-
-julia> G = free_module(R, 2)
-Free module of rank 2 over R
-
-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::ModuleFPHom)

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; check::Bool=true)

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)
-Z
source
diff --git a/previews/PR4245/CommutativeAlgebra/ModulesOverMultivariateRings/hom_operations/index.html b/previews/PR4245/CommutativeAlgebra/ModulesOverMultivariateRings/hom_operations/index.html deleted file mode 100644 index cbc14dd19a63..000000000000 --- a/previews/PR4245/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{<:ModuleFP, <:ModuleFP, Nothing}})

Given modules M and N which are products with r respective s factors, say $M = \prod_{i=1}^r M_i$, $N = \prod_{j=1}^s N_j$, and given a $r \times s$ 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/PR4245/CommutativeAlgebra/ModulesOverMultivariateRings/ideals_quorings_as_modules/index.html b/previews/PR4245/CommutativeAlgebra/ModulesOverMultivariateRings/ideals_quorings_as_modules/index.html deleted file mode 100644 index d8d916d95802..000000000000 --- a/previews/PR4245/CommutativeAlgebra/ModulesOverMultivariateRings/ideals_quorings_as_modules/index.html +++ /dev/null @@ -1,68 +0,0 @@ - -Ideals and Quotient Rings as Modules · Oscar.jl

Ideals and Quotient Rings as Modules

Ideals as Modules

ideal_as_moduleMethod
ideal_as_module(I::Union{MPolyIdeal, MPolyQuoIdeal, MPolyLocalizedIdeal, MPolyQuoLocalizedIdeal})

Return I considered as an object of type SubquoModule.

Examples

julia> R, (x, y) = polynomial_ring(QQ, [:x, :y]);
-
-julia> I = ideal(R, [x^2, y^3])
-Ideal generated by
-  x^2
-  y^3
-
-julia> ideal_as_module(I)
-Submodule with 2 generators
-1 -> x^2*e[1]
-2 -> y^3*e[1]
-represented as subquotient with no relations.
julia> S, (x, y) = graded_polynomial_ring(QQ, [:x, :y]);
-
-julia> I = ideal(S, [x^2, y^3])
-Ideal generated by
-  x^2
-  y^3
-
-julia> ideal_as_module(I)
-Graded submodule of S^1
-1 -> x^2*e[1]
-2 -> y^3*e[1]
-represented as subquotient with no relations
source

Quotient Rings as Modules

quotient_ring_as_moduleMethod
quotient_ring_as_module(A::MPolyQuoRing)

Return A considered as an object of type SubquoModule.

quotient_ring_as_module(I::Union{MPolyIdeal, MPolyQuoIdeal, MPolyLocalizedIdeal, MPolyQuoLocalizedIdeal})

As above, where A is the quotient of base_ring(I) modulo I.

Examples

julia> R, (x, y) = polynomial_ring(QQ, [:x, :y]);
-
-julia> IR = ideal(R, [x^2, y^3]);
-
-julia> quotient_ring_as_module(IR)
-Subquotient of Submodule with 1 generator
-1 -> e[1]
-by Submodule with 2 generators
-1 -> x^2*e[1]
-2 -> y^3*e[1]
-
-julia> base_ring(ans)
-Multivariate polynomial ring in 2 variables x, y
-  over rational field
-
-julia> A, _ = quo(R, ideal(R,[x*y]));
-
-julia> AI = ideal(A, [x^2, y^3]);
-
-julia> quotient_ring_as_module(AI)
-Subquotient of Submodule with 1 generator
-1 -> e[1]
-by Submodule with 2 generators
-1 -> x^2*e[1]
-2 -> y^3*e[1]
-
-julia> base_ring(ans)
-Quotient
-  of multivariate polynomial ring in 2 variables x, y
-    over rational field
-  by ideal (x*y)
-
julia> S, (x, y) = graded_polynomial_ring(QQ, [:x, :y]);
-
-julia> I = ideal(S, [x^2, y^3])
-Ideal generated by
-  x^2
-  y^3
-
-julia> quotient_ring_as_module(I)
-Graded subquotient of submodule of S^1 generated by
-1 -> e[1]
-by submodule of S^1 generated by
-1 -> x^2*e[1]
-2 -> y^3*e[1]
-
source
diff --git a/previews/PR4245/CommutativeAlgebra/ModulesOverMultivariateRings/intro/index.html b/previews/PR4245/CommutativeAlgebra/ModulesOverMultivariateRings/intro/index.html deleted file mode 100644 index 3b81fbd4654d..000000000000 --- a/previews/PR4245/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/PR4245/CommutativeAlgebra/ModulesOverMultivariateRings/module_operations/index.html b/previews/PR4245/CommutativeAlgebra/ModulesOverMultivariateRings/module_operations/index.html deleted file mode 100644 index 9b64e43ad8ec..000000000000 --- a/previews/PR4245/CommutativeAlgebra/ModulesOverMultivariateRings/module_operations/index.html +++ /dev/null @@ -1,453 +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 R
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> Rg, (x, y, z) = graded_polynomial_ring(QQ, [: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*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*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*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 R
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> Rg, (x, y, z) = graded_polynomial_ring(QQ, [: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> Rg, (x, y, z) = graded_polynomial_ring(QQ, [:x, :y, :z]);
-
-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
cokernel(F::FreeMod{R}, A::MatElem{R}) where R

Return the cokernel of A as an object of type SubquoModule with ambient free module F.

Examples

julia> R, (x,y,z) = polynomial_ring(QQ, [:x, :y, :z]);
-
-julia> F = free_module(R, 2)
-Free module of rank 2 over R
-
-julia> A = R[x y; 2*x^2 3*y^2]
-[    x       y]
-[2*x^2   3*y^2]
- 
-julia> M = cokernel(F, A)
-Subquotient of Submodule with 2 generators
-1 -> e[1]
-2 -> e[2]
-by Submodule with 2 generators
-1 -> x*e[1] + y*e[2]
-2 -> 2*x^2*e[1] + 3*y^2*e[2]
-
-julia> ambient_free_module(M) === F
-true
-
julia> Rg, (x, y, z) = graded_polynomial_ring(QQ, [:x, :y, :z]);
-
-julia> F = graded_free_module(Rg, [8,8])
-Graded free module Rg^2([-8]) of rank 2 over Rg
-
-julia> A = Rg[x y; 2*x^2 3*y^2]
-[    x       y]
-[2*x^2   3*y^2]
- 
-julia> M = cokernel(F, A)
-Graded subquotient of submodule of F generated by
-1 -> e[1]
-2 -> e[2]
-by submodule of F generated by
-1 -> x*e[1] + y*e[2]
-2 -> 2*x^2*e[1] + 3*y^2*e[2]
-
-julia> ambient_free_module(M) === F
-true
-
-julia> degrees_of_generators(M)
-2-element Vector{FinGenAbGroupElem}:
- [8]
- [8]
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(I::ModuleFP, g::FinGenAbGroupElem, 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

Twists

In the graded case, we have:

twistMethod
twist(M::ModuleFP{T}, g::FinGenAbGroupElem) where {T<:MPolyDecRingElem}

Return the twisted module M(g).

twist(M::ModuleFP{T}, W::Vector{<:IntegerUnion}) where {T<:MPolyDecRingElem}

Given a module M over a $\mathbb Z^m$-graded polynomial ring and a vector W of $m$ integers, convert W into an element g of the grading group of the ring and proceed as above.

twist(M::ModuleFP{T}, d::IntegerUnion) where {T<:MPolyDecRingElem}

Given a module M over a $\mathbb Z$-graded polynomial ring and an integer d, convert d into an element g of the grading group of the ring and proceed as above.

Examples

julia> R, (x, y) = graded_polynomial_ring(QQ, [:x, :y]);
-
-julia> I = ideal(R, [zero(R)])
-Ideal generated by
-  0
-
-julia> M = quotient_ring_as_module(I)
-Graded submodule of R^1
-1 -> e[1]
-represented as subquotient with no relations
-
-julia> degree(gen(M, 1))
-[0]
-
-julia> N = twist(M, 2)
-Graded submodule of R^1
-1 -> e[1]
-represented as subquotient with no relations
-
-julia> degree(gen(N, 1))
-[-2]
-
source
diff --git a/previews/PR4245/CommutativeAlgebra/ModulesOverMultivariateRings/subquotients/index.html b/previews/PR4245/CommutativeAlgebra/ModulesOverMultivariateRings/subquotients/index.html deleted file mode 100644 index 84260bec3081..000000000000 --- a/previews/PR4245/CommutativeAlgebra/ModulesOverMultivariateRings/subquotients/index.html +++ /dev/null @@ -1,1467 +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 modeled 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 R
-
-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 R at complement of prime ideal (x, y, z)
-
-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 RQ 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> Rg, (x, y, z) = graded_polynomial_ring(QQ, [:x, :y, :z]);
-
-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 = SubquoModule(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,
  • number_of_generators(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 R
-
-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> number_of_generators(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> Rg, (x, y, z) = graded_polynomial_ring(QQ, [:x, :y, :z]);
-
-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)
-Z
source
degrees_of_generatorsMethod
degrees_of_generators(M::SubquoModule; check::Bool=true)

Return the degrees of the generators of M.

Examples

julia> Rg, (x, y, z) = graded_polynomial_ring(QQ, [:x, :y, :z]);
-
-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{FinGenAbGroupElem}:
- [2]
- [2]
- [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 R
-
-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 R
-
-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 R
-
-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 R
-
-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> Rg, (x, y, z) = graded_polynomial_ring(QQ, [:x, :y, :z]);
-
-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> Rg, (x, y, z) = graded_polynomial_ring(QQ, [:x, :y, :z]);
-
-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; check::Bool=true)

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> Rg, (x, y, z) = graded_polynomial_ring(QQ, [:x, :y, :z]);
-
-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)
-[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)
-[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 R
-
-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> Rg, (x, y, z) = graded_polynomial_ring(QQ, [:x, :y, :z]);
-
-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 R
-
-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> Rg, (x, y, z) = graded_polynomial_ring(QQ, [:x, :y, :z]);
-
-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 R
-
-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 R
-
-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> Rg, (x, y, z) = graded_polynomial_ring(QQ, [:x, :y, :z]);
-
-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 R
-
-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> Rg, (x, y, z) = graded_polynomial_ring(QQ, [:x, :y, :z]);
-
-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 R
-
-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> Rg, (x, y, z) = graded_polynomial_ring(QQ, [:x, :y, :z]);
-
-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
annihilatorMethod
 annihilator(N::SubquoModule{T}) where T

Return the annihilator of N.

Note

By definition, the annihilator of $N$ is the ideal $0:N = \{a \in R \mid aN = 0\}$. Here, R = base_ring(N).

Examples

julia> R, (x, y, z) = polynomial_ring(QQ, [:x, :y, :z]);
-
-julia> F = free_module(R, 1);
-
-julia> AN = R[y;];
-
-julia> BN = R[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> J = annihilator(N)
-Ideal generated by
-  y^2
-  x^2
-  z^4
-
julia> S, (x, y, z) = polynomial_ring(QQ, [:x, :y, :z]);
-
-julia> I = ideal(S, [x*y*z])
-Ideal generated by
-  x*y*z
-
-julia> R, _ = quo(S, I)
-(Quotient of multivariate polynomial ring by ideal (x*y*z), Map: S -> R)
-
-julia> F = free_module(R, 1);
-
-julia> AN = R[y;];
-
-julia> BN = R[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> J = annihilator(N)
-Ideal generated by
-  x*z
-  y^2
-  x^2
-  z^4
-
source
quotientMethod
quotient(M::SubquoModule{T}, N::SubquoModule{T}) where T

Given subquotients M and N such that ambient_module(M) == ambient_module(N), return the module quotient of M by N regarded as submodules of the common ambient module.

Alternatively, use M:N.

Note

By definition, $M:N = \{a \in R \mid aN \subset M\}$. Here, R = base_ring(M) = base_ring(N).

Examples

julia> R, (x, y, z) = graded_polynomial_ring(QQ, [:x, :y, :z]);
-
-julia> F = graded_free_module(R, 1);
-
-julia> B = R[x^2; y^3; z^4];
-
-julia> AM = R[x;];
-
-julia> M = SubquoModule(F, AM, B)
-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 = R[y;];
-
-julia> N = SubquoModule(F, AN, B)
-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> L = quotient(M, N)
-Ideal generated by
-  x
-  y^2
-  z^4
-
source
quotientMethod
 quotient(M::SubquoModule{T}, J::MPolyIdeal{T}) where T

Return the quotient of M by J.

Alternatively, use M:J.

Note

By definition, $M:J = \{a \in A \mid Ja \subset M\}$. Here, $A$ is the ambient module of $M$.

Examples

julia> R, (x, y, z) = polynomial_ring(QQ, [:x, :y, :z]);
-
-julia> F = free_module(R, 1);
-
-julia> AM = R[x;];
-
-julia> BM = R[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> J = ideal(R, [x, y, z])^2
-Ideal generated by
-  x^2
-  x*y
-  x*z
-  y^2
-  y*z
-  z^2
-
-julia> L = quotient(M, J)
-Subquotient of Submodule with 5 generators
-1 -> x*e[1]
-2 -> y^3*e[1]
-3 -> z^4*e[1]
-4 -> y*z^3*e[1]
-5 -> y^2*z^2*e[1]
-by Submodule with 3 generators
-1 -> x^2*e[1]
-2 -> y^3*e[1]
-3 -> z^4*e[1]
-
-julia> ambient_free_module(L) == ambient_free_module(M)
-true
-
source

Submodules and Quotients

subMethod
sub(M::ModuleFP{T}, V::Vector{<:ModuleFPElem{T}}; cache_morphism::Bool=false) where T

Given a vector V of (homogeneous) elements of M, return the (graded) submodule I of M generated by these elements together with its inclusion map `inc : I ↪ M.

When cache_morphism is set to true, then inc will be cached and available for transport and friends.

If only the submodule itself is desired, use sub_object instead.

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 R
source
quoMethod
quo(M::ModuleFP{T}, V::Vector{<:ModuleFPElem{T}}; cache_morphism::Bool=false) where T

Given a vector V of (homogeneous) elements of M, return a pair (N, pr) consisting of the quotient N = M/⟨V⟩ and the projection map pr : M → N.

If one is only interested in the actual object M, but not the map, use quo_object instead.

If cache_morphism is set to true, the projection is cached and available to transport and friends.

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 R
-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 R
-
-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 R
-
-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> Rg, (x, y, z) = graded_polynomial_ring(QQ, [: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> 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 R
-
-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> Rg, (x, y, z) = graded_polynomial_ring(QQ, [: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> 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::ModuleFPHom)

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::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> Rg, (x, y, z) = graded_polynomial_ring(QQ, [: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);
-
-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; check::Bool=true)

If a is graded, return the degree of a.

Examples

julia> Rg, (x, y, z) = graded_polynomial_ring(QQ, [: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);
-
-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)
-[2]
source
grading_groupMethod
grading_group(a::SubQuoHom)

If a is graded, return the grading group of a.

Examples

julia> Rg, (x, y, z) = graded_polynomial_ring(QQ, [: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);
-
-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)
-Z
source
diff --git a/previews/PR4245/CommutativeAlgebra/affine_algebras/index.html b/previews/PR4245/CommutativeAlgebra/affine_algebras/index.html deleted file mode 100644 index f8004a136a7a..000000000000 --- a/previews/PR4245/CommutativeAlgebra/affine_algebras/index.html +++ /dev/null @@ -1,1197 +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

We emphasize: 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 monomial ordering entered by the user when creating the quotient; if no ordering is entered, OSCAR will use 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.

quo(R::MPolyRing, V::Vector{MPolyRingElem}; ordering::MonomialOrdering = default_ordering(R)) -> MPolyQuoRing, Map

As above, where I is the ideal of R generated by the polynomials in V.

Note

Once R/I is created, all computations within R/I relying on division with remainder and/or Gröbner bases are done with respect to ordering.

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 x, y
-    over rational field
-  by ideal (x^2 - y^3, x - y)
-
-julia> typeof(A)
-MPolyQuoRing{QQMPolyRingElem}
-
-julia> typeof(x)
-QQMPolyRingElem
-
-julia> p
-Map defined by a julia-function with inverse
-  from multivariate polynomial ring in 2 variables over QQ
-  to quotient of multivariate polynomial ring by ideal (x^2 - y^3, x - y)
-
-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 (x^2*z - y^3, x - y), Map: S -> B)
-
-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,
  • number_of_generators(A) / ngens(A) to the number of these generators,
  • gen(A, i) as well as A[i] to the i-th such generator, and
  • ordering(A) to the monomial ordering used in the construction 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> base_ring(A)
-Multivariate polynomial ring in 3 variables x, y, z
-  over rational field
-
-julia> modulus(A)
-Ideal generated by
-  -x^2 + y
-  -x^3 + z
-
-julia> gens(A)
-3-element Vector{MPolyQuoRingElem{QQMPolyRingElem}}:
- x
- y
- z
-
-julia> number_of_generators(A)
-3
-
-julia> gen(A, 2)
-y
-
-julia> ordering(A)
-degrevlex([x, y, z])
-

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)
-Z
source
monomial_basisMethod
monomial_basis(A::MPolyQuoRing, g::FinGenAbGroupElem)

Given an affine algebra A over a field which is graded by a free group of type FinGenAbGroup, 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 generated by
-  x^2
-
-julia> A, _ = quo(R, I)
-(Quotient of multivariate polynomial ring by ideal (x^2), Map: R -> A)
-
-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::FinGenAbGroupElem)

Given a graded quotient A of a multivariate polynomial ring over a field, where the grading group is free of type FinGenAbGroup, 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 defined by a julia-function with inverse
-  from R_[2] of dim 10
-  to graded multivariate polynomial ring in 4 variables over QQ
-
-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 defined by a julia-function with inverse
-  from quotient space over QQ with 7 generators and no relations
-  to quotient of multivariate polynomial ring by ideal (-x*z + y^2, -w*z + x*y, -w*y + x^2)
-
-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> G = abelian_group([0, 0])
-Z^2
-
-julia> W = [G[1], G[1], G[2], G[2], G[2]];
-
-julia> S, x, y = graded_polynomial_ring(QQ, :x => 1:2, :y => 1:3; weights = W);
-
-julia> L = homogeneous_component(S, [2,1]);
-
-julia> HC = gens(L[1]);
-
-julia> EMB = L[2]
-Map defined by a julia-function with inverse
-  from S_[2 1] of dim 9
-  to graded multivariate polynomial ring in 5 variables over QQ
-
-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 defined by a julia-function with inverse
-  from quotient space over QQ with 7 generators and no relations
-  to quotient of multivariate polynomial ring by ideal (x[1]*y[1] - x[2]*y[2])
-
-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
is_finite_dimensional_vector_spaceMethod
is_finite_dimensional_vector_space(A::MPolyQuoRing)

If, say, A = R/I, where R is a multivariate polynomial ring over a field K, and I is an ideal of R, return true if A is finite-dimensional as a K-vector space, false otherwise.

Note

A is finite-dimensional as a K-vector space iff it has Krull dimension zero. This condition is checked by the function.

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> is_finite_dimensional_vector_space(A)
-true
-
-julia> A, _ = quo(R, ideal(R, [x]));
-
-julia> is_finite_dimensional_vector_space(A)
-false
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 an ideal of R, return the dimension of A as a K-vector space.

Note

If A is not finite-dimensional as a K-vector space, an error is thrown.

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 generated by
-  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 an 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.

Note

If A is not finite-dimensional as a K-vector space, an error is thrown.

Examples

julia> R, (x, y) = graded_polynomial_ring(QQ, [:x, :y]);
-
-julia> I = ideal(R, [x^2, y^3])
-Ideal generated by
-  x^2
-  y^3
-
-julia> A, _ = quo(R, I)
-(Quotient of multivariate polynomial ring by ideal (x^2, y^3), Map: R -> A)
-
-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)

If f is an element of the affine algebra A = R/I, say, replace the internal polynomial representative of f by its normal form mod I with respect to ordering(A).

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
is_invertible_with_inverseMethod
is_invertible_with_inverse(f::MPolyQuoRingElem)

If f is invertible with inverse g, say, return (true, g). Otherwise, return (false, f).

Examples

julia> R, c = polynomial_ring(QQ, :c => (1:3));
-
-julia> R, c = grade(R, [1, 2, 3]);
-
-julia> I = ideal(R, [  -c[1]^3 + 2*c[1]*c[2] - c[3], c[1]^4 - 3*c[1]^2*c[2] + 2*c[1]*c[3] + c[2]^2,-c[1]^5 + 4*c[1]^3*c[2] - 3*c[1]^2*c[3] - 3*c[1]*c[2]^2 + 2*c[2]*c[3]]);
-
-julia> A, _ = quo(R, I);
-
-julia> f = A(c[1]^2 - c[1] - c[2] + 1)
-c[1]^2 - c[1] - c[2] + 1
-
-julia> tt, g = is_invertible_with_inverse(f)
-(true, c[1] + c[2] + c[3] + 1)
-
-julia> f*g
-1
-
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{FinGenAbGroupElem, MPolyQuoRingElem{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}} with 2 entries:
-  [4] => z^4
-  [3] => y^2*z
source
homogeneous_componentMethod
homogeneous_component(f::MPolyQuoRingElem{<:MPolyDecRingElem}, g::FinGenAbGroupElem)

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 (-x + y, -x^3 + z^3), Map: R -> A)
-
-julia> f = p(y^2-x^2+z^4)
--x^2 + y^2 + z^4
-
-julia> degree(f)
-[4]
-
-julia> typeof(degree(f))
-FinGenAbGroupElem
-
-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 generated by
-  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 generated by
-  x^2 - y^2
source

Reducing Polynomial Representatives of Generators

simplifyMethod
simplify(a::MPolyQuoIdeal)

If a is an ideal of the affine algebra A = R/I, say, replace the internal polynomial representative of each generator of a by its normal form mod I with respect to ordering(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 generated by
-  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 generated by
-  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,
  • number_of_generators(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 generated by
-  x - y
-  z^4
-
-julia> base_ring(a)
-Quotient
-  of multivariate polynomial ring in 3 variables x, y, z
-    over rational field
-  by ideal (-x^2 + y, -x^3 + z)
-
-julia> gens(a)
-2-element Vector{MPolyQuoRingElem{QQMPolyRingElem}}:
- x - y
- z^4
-
-julia> number_of_generators(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 generated by
-  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 generated by
-  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 generated by
-  x + y
-
-julia> a^2
-Ideal generated by
-  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 generated by
-  x + y
-
-julia> b = ideal(A, [x^2+y^2, x+y])
-Ideal generated by
-  x^2 + y^2
-  x + y
-
-julia> a+b
-Ideal generated by
-  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 generated by
-  x + y
-
-julia> b = ideal(A, [x^2+y^2, x+y])
-Ideal generated by
-  x^2 + y^2
-  x + y
-
-julia> a*b
-Ideal generated by
-  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 generated by
-  y^2
-
-julia> b = ideal(A, [x])
-Ideal generated by
-  x
-
-julia> intersect(a,b)
-Ideal generated by
-  x*y
-
-julia> intersect([a,b])
-Ideal generated by
-  x*y
source
intersectMethod
intersect(a::AlgAssAbsOrdIdl, b::AlgAssAbsOrdIdl) -> AlgAssAbsOrdIdl

Returns $a \cap b$.

source
intersect(a::AlgAssRelOrdIdl, b::AlgAssRelOrdIdl) -> AlgAssRelOrdIdl

Returns $a \cap b$.

source
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 generated by
-  x^3*y - x*y - y^3
-  x^4 - x^2 - x*y^2
-
-julia> intersect([I, J])
-Ideal generated by
-  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 generated by
-  y^2
-
-julia> b = ideal(A, [x])
-Ideal generated by
-  x
-
-julia> intersect(a,b)
-Ideal generated by
-  x*y
-
-julia> intersect([a,b])
-Ideal generated by
-  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 R
-
-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> Rg, (x, y, z) = graded_polynomial_ring(QQ, [:x, :y, :z]);
-
-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

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 generated by
-  y^2
-
-julia> b = ideal(A, [x])
-Ideal generated by
-  x
-
-julia> a:b
-Ideal generated by
-  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 generated by
-  x^2 + y^2
-  x + y
-
-julia> is_zero(a)
-false
-
-julia> b = ideal(A, [x^2-y])
-Ideal generated by
-  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 generated by
-  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 generated by
-  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 generated by
-  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 generated by
-  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 generated by
-  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 base_ring(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])
-Ring homomorphism
-  from quotient of multivariate polynomial ring by ideal (-x^2 + y, -x^3 + z)
-  to multivariate polynomial ring in 2 variables over QQ
-defined by
-  x -> s
-  y -> s^2
-  z -> s^3
source

Given a ring homomorphism F : A $\to$ S as above, domain(F) and codomain(F) refer to A and S, respectively. Given ring homomorphisms F : A $\to$ B and G : B $\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::MPolyAnyMap, I::Ideal)

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)
-Ring homomorphism
-  from graded multivariate polynomial ring in 4 variables over QQ
-  to graded multivariate polynomial ring in 2 variables over QQ
-defined by
-  w -> s^3
-  x -> s^2*t
-  y -> s*t^2
-  z -> t^3
-
-julia> twistedCubic = kernel(para)
-Ideal generated by
-  -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)
-Ring homomorphism
-  from graded multivariate polynomial ring in 3 variables over QQ
-  to quotient of multivariate polynomial ring by ideal (-x*z + y^2, -w*z + x*y, -w*y + x^2)
-defined by
-  a -> w - y
-  b -> x
-  c -> z
-
-julia> nodalCubic = kernel(proj)
-Ideal generated by
-  -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)
-Ring homomorphism
-  from multivariate polynomial ring in 3 variables over QQ
-  to multivariate polynomial ring in 3 variables over QQ
-defined by
-  y[1] -> x[1]*x[2]
-  y[2] -> x[1]*x[3]
-  y[3] -> x[2]*x[3]
-
-julia> sphere = ideal(C3, [x[1]^3 + x[2]^3  + x[3]^3 - 1])
-Ideal generated by
-  x[1]^3 + x[2]^3 + x[3]^3 - 1
-
-julia> steinerRomanSurface = preimage(F3, sphere)
-Ideal generated by
-  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)
-Ring homomorphism
-  from multivariate polynomial ring in 3 variables over QQ
-  to quotient of multivariate polynomial ring by ideal (-b^3 + c)
-defined by
-  x -> 2*a + c^2
-  y -> -a^2 + 7*b
-  z -> c^2
-
-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)
-Ring homomorphism
-  from multivariate polynomial ring in 3 variables over QQ
-  to multivariate polynomial ring in 2 variables over QQ
-defined by
-  x -> s*t
-  y -> t
-  z -> s^2
-
-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)
-Ring homomorphism
-  from multivariate polynomial ring in 1 variable over QQ
-  to quotient of multivariate polynomial ring by ideal (-x^2 + y, -x^3 + z)
-defined by
-  t -> x
-
-julia> G(t)
-x
source

Algebraic Independence

is_algebraically_independentMethod
is_algebraically_independent(V::Vector{T}) where T <: Union{MPolyRingElem, MPolyQuoRingElem}

Given a vector V of elements of a multivariate polynomial ring over a field K, say, or of a quotient of such a ring, return true if the elements of V are algebraically independent over K, and false otherwise.

Examples

julia> R, (x, y) = polynomial_ring(QQ, [:x, :y]);
-
-julia> V = [x, y, x^2+y^3]
-3-element Vector{QQMPolyRingElem}:
- x
- y
- x^2 + y^3
-
-julia> is_algebraically_independent(V)
-false
-
-julia> A, p = quo(R, [x*y]);
-
-julia> is_algebraically_independent([p(x), p(y)])
-false
source
is_algebraically_independent_with_relationsMethod
is_algebraically_independent_with_relations(V::Vector{T}) where T <: Union{MPolyRingElem, MPolyQuoRingElem}

Given a vector V of elements of a multivariate polynomial ring over a field K, say, or of a quotient of such a ring, return (true, Ideal (0)) if the elements of V are algebraically independent over K. Otherwise, return false together with the ideal of K-algebra relations.

Examples

julia> R, (x, y) = polynomial_ring(QQ, [:x, :y]);
-
-julia> V = [x, y, x^2+y^3]
-3-element Vector{QQMPolyRingElem}:
- x
- y
- x^2 + y^3
-
-julia> is_algebraically_independent_with_relations(V)
-(false, Ideal (t1^2 + t2^3 - t3))
-
-julia> A, p = quo(R, [x*y]);
-
-julia> is_algebraically_independent_with_relations([p(x), p(y)])
-(false, Ideal (t1*t2))
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 subset of the elements in V of minimal cardinality 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]
-Ring homomorphism
-  from quotient of multivariate polynomial ring by ideal (x*y, x*z)
-  to quotient of multivariate polynomial ring by ideal (2*x^2 + x*y, 10*x^2 + 5*x*y + x*z)
-defined by
-  x -> x
-  y -> 2*x + y
-  z -> 10*x + 5*y + z
-
-julia> L[3]
-Ring homomorphism
-  from quotient of multivariate polynomial ring by ideal (2*x^2 + x*y, 10*x^2 + 5*x*y + x*z)
-  to quotient of multivariate polynomial ring by ideal (x*y, x*z)
-defined by
-  x -> x
-  y -> -2*x + y
-  z -> -5*y + z
-

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$. If specified by algorithm = :isPrime, assume that $I$ is prime.

See [GLS10].

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 T(1), x, y
-    over rational field
-  by ideal (-T(1)*y + x, -T(1)*x + y^2, T(1)^2 - y, -x^2 + y^3)
-
-julia> LL[1][2]
-Ring homomorphism
-  from quotient of multivariate polynomial ring by ideal (x^5 - x^3*y^3 + x^3*y^2 - x*y^5)
-  to quotient of multivariate polynomial ring by ideal (-T(1)*y + x, -T(1)*x + y^2, T(1)^2 - y, -x^2 + y^3)
-defined by
-  x -> x
-  y -> y
-
-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 [BDLPSS13]. Alternatively, if specified by algorithm = :normal_global, the global normalization algorithm in [GLS10] is used. If $K = \mathbb Q$, it is recommended to apply the algorithm in [BDLP19], 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; check::Bool=true) -> Bool

Given an affine algebra A over a perfect field, return true if A is normal, and false otherwise.

Note

This function performs the first step of the normalization algorithm of Greuel, Laplagne, and Seelisch [GLS10] and may, thus, be more efficient than computing the full normalization of A.

Warning

If check is true, the function checks whether A is indeed reduced. This may take some time.

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 \mathbb{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 [MS05] 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 [MS05] 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 [Eis95]). 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 [KR05]). 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}}): \mathbb{N} \to \mathbb{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}}): \mathbb{N} \to \mathbb{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: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]
-Z^2
-
-julia> H[2][2]
-Identity map
-  of Z^2
-
-julia> G = abelian_group(ZZMatrix([1 -1]));
-
-julia> g = gen(G, 1)
-Abelian group element [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
-Z
-
-julia> iso
-Map
-  from Z
-  to finitely generated abelian group with 2 generators and 1 relation
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: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]
-Z^2
-
-julia> H[2][2]
-Identity map
-  of Z^2
-
-julia> G = abelian_group(ZZMatrix([1 -1]));
-
-julia> g = gen(G, 1)
-Abelian group element [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]
-Z
-
-julia> H[2][2]
-Map
-  from Z
-  to finitely generated abelian group with 2 generators and 1 relation
source
multi_hilbert_functionMethod
multi_hilbert_function(A::MPolyQuoRing, g::FinGenAbGroupElem)

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 \mathbb{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: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/PR4245/CommutativeAlgebra/homological_algebra/index.html b/previews/PR4245/CommutativeAlgebra/homological_algebra/index.html deleted file mode 100644 index 27b95ca384a3..000000000000 --- a/previews/PR4245/CommutativeAlgebra/homological_algebra/index.html +++ /dev/null @@ -1,998 +0,0 @@ - -Homological Algebra · Oscar.jl

Homological Algebra

Some OSCAR functions which are fundamental to homological algebra such as the kernel function for module homomorphisms and basic functions for handling chain and cochain complexes are discussed in the module section. Building on these functions, we here introduce further OSCAR functionality supporting computations in homological algebra.

Pruning Modules

prune_with_mapMethod
prune_with_map(M::ModuleFP)

If M is positively graded, return a module N and an isomorphism from N to M such that N is generated by a minimal number of elements.

If M is not (positively) graded, the function still aims at reducing the number of generators.

Examples

julia> R, (w, x, y, z) = graded_polynomial_ring(QQ, [:w, :x, :y, :z]);
-
-julia> Z = R(0)
-0
-
-julia> O = R(1)
-1
-
-julia> B = [Z Z Z O; w*y w*z-x*y x*z-y^2 Z];
-
-julia> A = transpose(matrix(B))
-[0         w*y]
-[0   w*z - x*y]
-[0   x*z - y^2]
-[1           0]
-
-julia> M = graded_cokernel(A)
-Graded subquotient of submodule of R^2 generated by
-1 -> e[1]
-2 -> e[2]
-by submodule of R^2 generated by
-1 -> w*y*e[2]
-2 -> (w*z - x*y)*e[2]
-3 -> (x*z - y^2)*e[2]
-4 -> e[1]
-
-julia> N, phi = prune_with_map(M);
-
-julia> N
-Graded subquotient of submodule of R^1 generated by
-1 -> e[1]
-by submodule of R^1 generated by
-1 -> (-x*z + y^2)*e[1]
-2 -> (-w*z + x*y)*e[1]
-3 -> w*y*e[1]
-
-julia> phi(first(gens(N)))
-e[2]
source

Presentations

presentationMethod
presentation(M::ModuleFP; minimal = false)

Return a (free) presentation of M.

Note

If minimal is true, and M is positively graded, a minimal presentation is returned. If minimal is true, and M is not (positively) graded, the function still aims at returning an ''improved'' presentation.

Examples

julia> R, (w, x, y, z) = graded_polynomial_ring(QQ, [:w, :x, :y, :z]);
-
-julia> Z = R(0)
-0
-
-julia> O = R(1)
-1
-
-julia> B = [Z Z Z O; w*y w*z-x*y x*z-y^2 Z];
-
-julia> A = transpose(matrix(B))
-[0         w*y]
-[0   w*z - x*y]
-[0   x*z - y^2]
-[1           0]
-
-julia> M = graded_cokernel(A)
-Graded subquotient of submodule of R^2 generated by
-1 -> e[1]
-2 -> e[2]
-by submodule of R^2 generated by
-1 -> w*y*e[2]
-2 -> (w*z - x*y)*e[2]
-3 -> (x*z - y^2)*e[2]
-4 -> e[1]
-
-julia> PM1 = presentation(M)
-0 <---- M <---- R^2 <---- R^4
-
-julia> PM2 = presentation(M, minimal = true)
-0 <---- M <---- R^1 <---- R^3
-
julia> Rg, (x, y, z) = graded_polynomial_ring(QQ, [:x, :y, :z]);
-
-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> Rg, (x, y, z) = graded_polynomial_ring(QQ, [: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);
-
-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

Free Resolutions

free_resolutionMethod
free_resolution(M::SubquoModule{T}; 
-    length::Int=0,
-    algorithm::Symbol = T <:MPolyRingElem ? :fres : :sres) where {T <: Union{MPolyRingElem, MPolyQuoRingElem}}

Return a free resolution of M.

If length != 0, the free resolution is only computed up to the length-th free module. Current options for algorithm are :fres, :nres, and :mres for modules over polynomial rings and :sres for modules over quotients of polynomial rings.

Note

The function first computes a presentation of M. It then successively computes higher syzygy modules.

Note
  • If algorithm == mres, and M is positively graded, a minimal free resolution is returned.
  • If algorithm == nres, and M is positively graded, the function proceeds as above except that it starts by computing a presentation which is not neccessarily minimal.

In both cases, if M is not (positively) graded, the function still aims at returning an ''improved'' resolution.

Note

If algorithm == fres, the function relies on an enhanced version of Schreyer's algorithm [EMSS16]. Typically, this is more efficient than the approaches above, but the resulting resolution is far from being minimal.

Note

If M is a module over a quotient of a polynomial ring then the length keyword must be set to a nonzero value.

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 R
-
-julia> fr
-Free resolution of M
-R^2 <---- R^6 <---- R^6 <---- R^2 <---- 0
-0         1         2         3         4
-
-julia> is_complete(fr)
-true
julia> R, (w, x, y, z) = graded_polynomial_ring(QQ, [:w, :x, :y, :z]);
-
-julia> Z = R(0)
-0
-
-julia> O = R(1)
-1
-
-julia> B = [Z Z Z O; w*y w*z-x*y x*z-y^2 Z];
-
-julia> A = transpose(matrix(B));
-
-julia> M = graded_cokernel(A)
-Graded subquotient of submodule of R^2 generated by
-1 -> e[1]
-2 -> e[2]
-by submodule of R^2 generated by
-1 -> w*y*e[2]
-2 -> (w*z - x*y)*e[2]
-3 -> (x*z - y^2)*e[2]
-4 -> e[1]
-
-julia> FM1 = free_resolution(M)
-Free resolution of M
-R^2 <---- R^7 <---- R^8 <---- R^3 <---- 0
-0         1         2         3         4
-
-julia> betti_table(FM1)
-       0  1  2  3
------------------
--1   : -  1  -  -
-0    : 2  -  -  -
-1    : -  3  3  1
-2    : -  3  5  2
------------------
-total: 2  7  8  3
-
-
-julia> matrix(map(FM1, 1))
-[1            0]
-[0   -x*z + y^2]
-[0   -w*z + x*y]
-[0          w*y]
-[0        x^2*z]
-[0        w*x*z]
-[0        w^2*z]
-
-julia> FM2 = free_resolution(M, algorithm = :nres)
-Free resolution of M
-R^2 <---- R^4 <---- R^4 <---- R^2 <---- 0
-0         1         2         3         4
-
-julia> betti_table(FM2)
-       0  1  2  3
------------------
--1   : -  1  -  -
-0    : 2  -  -  -
-1    : -  3  -  -
-2    : -  -  4  2
------------------
-total: 2  4  4  2
-
-
-julia> matrix(map(FM2, 1))
-[1            0]
-[0   -x*z + y^2]
-[0   -w*z + x*y]
-[0          w*y]
-
-julia> FM3 = free_resolution(M, algorithm = :mres)
-Free resolution of M
-R^1 <---- R^3 <---- R^4 <---- R^2 <---- 0
-0         1         2         3         4
-
-julia> betti_table(FM3)
-       0  1  2  3
------------------
-0    : 1  -  -  -
-1    : -  3  -  -
-2    : -  -  4  2
------------------
-total: 1  3  4  2
-
-
-julia> matrix(map(FM3, 1))
-[-x*z + y^2]
-[-w*z + x*y]
-[       w*y]
-

Note: Over rings other than polynomial rings or quotients of polynomial rings, the method will default to a lazy, iterative kernel computation.

source

Betti Tables

Given a $\mathbb Z$-graded multivariate polynomial ring $S$, and given a graded free resolution with finitely generated graded free $S$-modules

\[F_i=\bigoplus_j S(-j) ^{\beta_{ij}},\]

the numbers $\beta_{ij}$ are commonly known as the graded Betti numbers of the resolution. A convenient way of visualizing these numbers is to write a Betti table as in the example below:

       0  1  2  3  
-------------------
-0    : 1  -  -  -  
-1    : -  2  1  -  
-2    : -  2  3  1  
-------------------
-total: 1  4  4  1

A number $i$ in the top row of the table refers to the $i$-th free module $F_i$ of the resolution. More precisely, the column with first entry $i$ lists the number of free generators of $F_i$ in different degrees and, in the bottom row, the total number of free generators (that is, the rank of $F_i$). If $k$ is the first entry of a row containing a number $\beta$ in the column corresponding to $F_i$, then $F_i$ has $\beta$ generators in degree $k+i$. That is, for a free module $F_i$ written as a direct sum as above, $\beta$ is the number $\beta_{ij}$ with $j=k+i$. The explicit example table above indicates, for instance, that $F_2$ has one generator in degree 3 and three generators in degree 4. In total, the diagram corresponds to a graded free resolution of type

\[S \leftarrow S(-2)^2\oplus S(-3)^2 \leftarrow S(-3)\oplus S(-4)^3 \leftarrow S(-5) \leftarrow 0.\]

betti_tableMethod
betti_table(F::FreeResolution)

Given a $\mathbb Z$-graded free resolution F, return the graded Betti numbers of F in form of a Betti table.

Alternatively, use betti.

Examples

julia> R, (w, x, y, z) = graded_polynomial_ring(QQ, [:w, :x, :y, :z]);
-
-julia> I = ideal(R, [x*z, y*z, x*w^2, y*w^2])
-ideal(x*z, y*z, w^2*x, w^2*y)
-
-julia> A, _= quo(R, I)
-(Quotient of multivariate polynomial ring by ideal with 4 generators, Map from
-R to A defined by a julia-function with inverse)
-
-julia> FA  = free_resolution(A)
-Free resolution of A
-R^1 <---- R^4 <---- R^4 <---- R^1 <---- 0
-0         1         2         3         4
-
-julia> betti_table(FA)
-       0  1  2  3
-------------------
-0    : 1  -  -  -
-1    : -  2  1  -
-2    : -  2  3  1
-------------------
-total: 1  4  4  1
-
-julia> R, (x, y) = graded_polynomial_ring(QQ, [:x, :y]);
-
-julia> I = ideal(R, [x, y, x+y]);
-
-julia> M = quotient_ring_as_module(I);
-
-julia> FM = free_resolution(M, algorithm = :nres);
-
-julia> betti_table(FM)
-       0  1  2
----------------
--1   : -  -  1
-0    : 1  3  1
----------------
-total: 1  3  2
source
minimal_betti_tableMethod
minimal_betti_table(F::FreeResolution{T}; check::Bool=true) where {T<:ModuleFP}

Given a graded free resolution F over a standard $\mathbb Z$-graded multivariate polynomial ring with coefficients in a field, return the Betti table of the minimal free resolution arising from F.

Note

The algorithm proceeds without actually minimizing the resolution.

Examples

julia> R, (w, x, y, z) = graded_polynomial_ring(QQ, [:w, :x, :y, :z]);
-
-julia> I = ideal(R, [w^2-x*z, w*x-y*z, x^2-w*y, x*y-z^2, y^2-w*z]);
-
-julia> A, _ = quo(R, I)
-(Quotient of multivariate polynomial ring by ideal with 5 generators, Map from
-R to A defined by a julia-function with inverse)
-
-julia> FA = free_resolution(A)
-Free resolution of A
-R^1 <---- R^5 <---- R^6 <---- R^2 <---- 0
-0         1         2         3         4
-
-julia> betti_table(FA)
-       0  1  2  3  
-------------------
-0    : 1  -  -  -  
-1    : -  5  5  1  
-2    : -  -  1  1  
-------------------
-total: 1  5  6  2  
-
-julia> minimal_betti_table(FA)
-       0  1  2  3  
-------------------
-0    : 1  -  -  -  
-1    : -  5  5  -  
-2    : -  -  -  1  
-------------------
-total: 1  5  5  1  
source
minimal_betti_tableMethod
minimal_betti_table(M::ModuleFP{T}) where {T<:MPolyDecRingElem}
-minimal_betti_table(A::MPolyQuoRing{T}) where {T<:MPolyDecRingElem}
-minimal_betti_table(I::MPolyIdeal{T}) where {T<:MPolyDecRingElem}

Given a finitely presented graded module M over a standard $\mathbb Z$-graded multivariate polynomial ring with coefficients in a field, return the Betti Table of the minimal free resolution of M. Similarly for A and I.

Examples

julia> R, (w, x, y, z) = graded_polynomial_ring(QQ, [:w, :x, :y, :z]);
-
-julia> I = ideal(R, [w^2-x*z, w*x-y*z, x^2-w*y, x*y-z^2, y^2-w*z]);
-
-julia> A, _ = quo(R, I)
-(Quotient of multivariate polynomial ring by ideal with 5 generators, Map from
-R to A defined by a julia-function with inverse)
-
-julia> minimal_betti_table(A)
-       0  1  2  3
-------------------
-0    : 1  -  -  -
-1    : -  5  5  -
-2    : -  -  -  1
-------------------
-total: 1  5  5  1
source

Castelnuovo-Mumford Regularity

cm_regularityMethod
cm_regularity(M::ModuleFP; check::Bool=true)

Given a finitely presented graded module M over a standard $\mathbb Z$-graded multivariate polynomial ring with coefficients in a field, return the Castelnuovo-Mumford regularity of M.

cm_regularity(I::MPolyIdeal)

Given a (homogeneous) ideal I in a standard $\mathbb Z$-graded multivariate polynomial ring with coefficients in a field, return the Castelnuovo-Mumford regularity of I.

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)
-       0 1 2 3 
---------------
-0    : 1 - - - 
-1    : - 3 - - 
-2    : - - 3 - 
-3    : - - - 1 
---------------
-total: 1 3 3 1 
julia> R, (w, x, y, z) = graded_polynomial_ring(QQ, [:w, :x, :y, :z]);
-
-julia> I = ideal(R, [-x*z+y^2, x*y-w*z, x^2-w*y]);
-
-julia> cm_regularity(I)
-2
-
-julia> A, _ = quo(R, I);
-
-julia> minimal_betti_table(A)
-       0 1 2 
-------------
-0    : 1 - - 
-1    : - 3 2 
-------------
-total: 1 3 2 
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

homMethod
hom(M::ModuleFP, N::ModuleFP; algorithm::Symbol=:maps)

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.

The keyword algorithm can be set to :maps for the default algorithm or to :matrices for an alternative based on matrices.

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_object(F, V)
-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_object(F, V)
-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_object(F, V)
-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> is_welldefined(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_object(F, V)
-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 -> y*(e[1] -> e[1])
-2 -> x*(e[1] -> e[1])
-
-julia> ext(M, M, 1)
-Subquotient of Submodule with 2 generators
-1 -> (e[1] -> e[1])
-2 -> (e[2] -> e[1])
-by Submodule with 4 generators
-1 -> y*(e[1] -> e[1])
-2 -> x*(e[1] -> e[1])
-3 -> y*(e[2] -> e[1])
-4 -> x*(e[2] -> e[1])
-
-julia> ext(M, M, 2)
-Subquotient of Submodule with 1 generator
-1 -> (e[1] -> e[1])
-by Submodule with 2 generators
-1 -> y*(e[1] -> e[1])
-2 -> 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 2 generators
-1 -> x*e[1] \otimes e[1]
-2 -> x*y*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_object(F,U)
-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 generated by
-  0
-
-julia> fitting_ideal(M, 0)
-Ideal generated by
-  x^3 - y^2
-
-julia> fitting_ideal(M, 1)
-Ideal generated by
-  y
-  x
-
-julia> fitting_ideal(M, 2)
-Ideal generated by
-  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_object(F,U)
-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_object(F,U)
-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 generated by
-  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)
-[x   y   z]
-
-julia> koszul_matrix(V, 2)
-[-y   -z    0]
-[ x    0   -z]
-[ 0    x    y]
-
-julia> koszul_matrix(V, 1)
-[ z]
-[-y]
-[ x]
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   -z    0]
-[ x    0   -z]
-[ 0    x    y]
-
-julia> Kd = hom(K, free_module(R, 1));
-
-julia> matrix(map(Kd, 1))
-[-y    x   0]
-[-z    0   x]
-[ 0   -z   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

See [GP08] or [DL06] for the definition of the Koszul complex.

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)
-Subquotient of Submodule with 1 generator
-1 -> e[1]^e[2]^e[3]
-by Submodule with 3 generators
-1 -> y*z*e[1]^e[2]^e[3]
-2 -> -x*z*e[1]^e[2]^e[3]
-3 -> x*y*e[1]^e[2]^e[3]
-
-julia> koszul_homology(V, F, 1)
-Subquotient of Submodule with 2 generators
-1 -> y*e[1]^e[3] \otimes e[1] + z*e[2]^e[3] \otimes e[1]
-2 -> x*e[1]^e[2] \otimes e[1] - z*e[2]^e[3] \otimes e[1]
-by Submodule with 3 generators
-1 -> -x*z*e[1]^e[2] \otimes e[1] - y*z*e[1]^e[3] \otimes e[1]
-2 -> x*y*e[1]^e[2] \otimes e[1] - y*z*e[2]^e[3] \otimes e[1]
-3 -> x*y*e[1]^e[3] \otimes e[1] + x*z*e[2]^e[3] \otimes e[1]
-
-julia> koszul_homology(V, F, 2)
-Subquotient of Submodule with 1 generator
-1 -> x*y*e[1] \otimes e[1] + x*z*e[2] \otimes e[1] + y*z*e[3] \otimes e[1]
-by Submodule with 1 generator
-1 -> x*y*e[1] \otimes e[1] + x*z*e[2] \otimes e[1] + y*z*e[3] \otimes e[1]
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)
-Subquotient of Submodule with 1 generator
-1 -> e[1]^e[2]^e[3]
-by Submodule with 3 generators
-1 -> (w*y - x^2)*e[1]^e[2]^e[3]
-2 -> (-w*z + x*y)*e[1]^e[2]^e[3]
-3 -> (x*z - y^2)*e[1]^e[2]^e[3]
-
-julia> koszul_homology(gens(TC), F, 1)
-Subquotient of Submodule with 2 generators
-1 -> z*e[1]^e[2] \otimes e[1] + y*e[1]^e[3] \otimes e[1] + x*e[2]^e[3] \otimes e[1]
-2 -> y*e[1]^e[2] \otimes e[1] + x*e[1]^e[3] \otimes e[1] + w*e[2]^e[3] \otimes e[1]
-by Submodule with 3 generators
-1 -> (-w*z + x*y)*e[1]^e[2] \otimes e[1] + (-w*y + x^2)*e[1]^e[3] \otimes e[1]
-2 -> (x*z - y^2)*e[1]^e[2] \otimes e[1] + (-w*y + x^2)*e[2]^e[3] \otimes e[1]
-3 -> (x*z - y^2)*e[1]^e[3] \otimes e[1] + (w*z - x*y)*e[2]^e[3] \otimes e[1]
-
-julia> koszul_homology(gens(TC), F, 2)
-Subquotient of Submodule with 1 generator
-1 -> (-x*z + y^2)*e[1] \otimes e[1] + (-w*z + x*y)*e[2] \otimes e[1] + (-w*y + x^2)*e[3] \otimes e[1]
-by Submodule with 1 generator
-1 -> (x*z - y^2)*e[1] \otimes e[1] + (w*z - x*y)*e[2] \otimes e[1] + (w*y - x^2)*e[3] \otimes e[1]
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 generated by
-  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 generated by
-  y[1]
-  y[2]
-  y[3]
-  y[4]
-  y[5]
-
-julia> depth(I, M)
-1
source
diff --git a/previews/PR4245/CommutativeAlgebra/ideals/index.html b/previews/PR4245/CommutativeAlgebra/ideals/index.html deleted file mode 100644 index e9c4b4df428b..000000000000 --- a/previews/PR4245/CommutativeAlgebra/ideals/index.html +++ /dev/null @@ -1,802 +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 generated by
-  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 generated by
-  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,
  • number_of_generators(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 generated by
-  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> number_of_generators(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 generated by
-  -x^2 + y
-  x - z^3
-
-julia> dim(I)
-1
source

Codimension

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 generated by
-  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 generated by
-  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 with coefficients in a field, 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 [MS21].

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 generated by
-  -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 generated by
-  x
-  y
-
-julia> I^3
-Ideal generated by
-  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 generated by
-  x
-  y
-
-julia> J = ideal(R, [z^2])
-Ideal generated by
-  z^2
-
-julia> I+J
-Ideal generated by
-  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 generated by
-  x
-  y
-
-julia> J = ideal(R, [z^2])
-Ideal generated by
-  z^2
-
-julia> I*J
-Ideal generated by
-  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 generated by
-  x^3*y - x*y - y^3
-  x^4 - x^2 - x*y^2
-
-julia> intersect([I, J])
-Ideal generated by
-  x^3*y - x*y - y^3
-  x^4 - x^2 - x*y^2
source

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 generated by
-  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 generated by
-  x^2
-  x*y
-  x*z
-  y^2
-  y*z
-  z^2
-
-julia> L = quotient(I, J)
-Ideal generated by
-  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 generated by
-  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 generated by
-  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} = ideal(base_ring(I), gens(base_ring(I))); 
-           iteration::Bool=false) where T

Return the saturation of I with respect to J.

If the second ideal J is not given, the ideal generated by the generators (variables) of base_ring(I) is used.

If iteration is set to true, the saturation is done by carrying out successive ideal quotient computations as in the definition of saturation. Otherwise, a more sophisticated Gröbner basis approach is used which is typically faster. Applying the two approaches may lead to different generating sets of the saturation.

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 generated by
-  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 generated by
-  x
-  y
-  z
-
-julia> K = saturation(I, J)
-Ideal generated by
-  z
-  x*y
-
-julia> K = saturation(I)
-Ideal generated by
-  z
-  x*y
-
source
saturation_with_indexMethod
saturation_with_index(I::MPolyIdeal{T}, 
-                      J::MPolyIdeal{T} = ideal(base_ring(I), gens(base_ring(I)))) where T

Return $I:J^{\infty}$ together with the smallest integer $m$ such that $I:J^m = I:J^{\infty}$ (saturation index).

If the second ideal J is not given, the ideal generated by the generators (variables) of base_ring(I) is used.

Note

If the saturation index is not needed, we recommend to use saturation(I, J) which is typically faster.

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 generated by
-  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 generated by
-  x
-  y
-  z
-
-julia> K, m = saturation_with_index(I, J)
-(Ideal (z, x*y), 2)
-
-julia> K, m = saturation_with_index(I)
-(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 generated by
-  t - x
-  t^2 - y
-  t^3 - z
-
-julia> A = [t]
-1-element Vector{QQMPolyRingElem}:
- t
-
-julia> TC = eliminate(I, A)
-Ideal generated by
-  -x*z + y^2
-  x*y - z
-  x^2 - y
-
-julia> A = [1]
-1-element Vector{Int64}:
- 1
-
-julia> TC = eliminate(I, A)
-Ideal generated by
-  -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::FinGenAbGroupElem)

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 generated by
-  x
-  y^4
-  z^6
-
-julia> truncate(I, 3)
-Ideal generated by
-  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 generated by
-  x
-  y^4
-  z^6
-
-julia> truncate(I, 3)
-Ideal generated by
-  x
-  y^4
-  z^6
-
-julia> truncate(I, 4)
-Ideal generated by
-  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 generated by
-  -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 generated by
-  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, J::MPolyIdeal)

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 generated by
-  x^2
-
-julia> J = ideal(R, [x, y])^2
-Ideal generated by
-  x^2
-  x*y
-  y^2
-
-julia> is_subset(I, J)
-true
source

Equality of Ideals

==Method
==(I::MPolyIdeal, J::MPolyIdeal)

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 generated by
-  x^2
-
-julia> J = ideal(R, [x, y])^2
-Ideal generated by
-  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 generated by
-  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 generated by
-  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 generated by
-  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 generated by
-  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 [DGP99] for a survey.

Radical

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

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 [GTZ88], [SY96], and [PSS11].

Warning

The algorithm of Gianni, Trager, and Zacharias may not terminate over a small finite field. If it terminates, the result is correct.

Warning

If computations are done in a ring over a number field, then the output may contain redundant components.

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 generated by
-  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 generated by
-  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 generated by
-  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.

Warning

Over number fields this proceduce might return redundant output.

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 generated by
-  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{AbsSimpleNumFieldElem}}, 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^2), 3)
-
-julia> AP = AL[1][3]
-Ideal generated by
-  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 generated by
-  x^2 + y^2
-
-julia> AL = absolute_primary_decomposition(I)
-1-element Vector{Tuple{MPolyIdeal{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}, MPolyIdeal{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}, MPolyIdeal{MPolyDecRingElem{AbsSimpleNumFieldElem, AbstractAlgebra.Generic.MPoly{AbsSimpleNumFieldElem}}}, Int64}}:
- (Ideal (x^2 + y^2), Ideal (x^2 + y^2), Ideal (x + _a*y), 2)
-
-julia> AP = AL[1][3]
-Ideal generated by
-  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 [GTZ88] and [PSS11].

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 generated by
-  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 generated by
-  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 generated by
-  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 [EHV92].

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 generated by
-  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 generated by
-  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 with 1 generator
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 [KL91] and [Kem02].

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 generated by
-  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 generated by
-  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 [GTZ88], [KL91], and [PSS11].

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 generated by
-  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 generated by
-  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 generated by
-  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 generated by
-  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 generated by
-  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 [KL91] and [Kem02].

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 generated by
-  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 generated by
-  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 generated by
-  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 [KR05] for definitions and technical details, we discuss homogenization and dehomogenization in the context of $\mathbb Z^m$-gradings.

homogenizerMethod
homogenizer(P::MPolyRing, h::VarName;  pos::Int=1+ngens(P))

Create a "homogenizing operator" assuming a standard grading; h is the name of the homogenizing variable; pos indicates where to put the homogenizing variable in the list of generators of the graded polynomial ring (default is after all the other variables).

Examples

julia> P, (x,y) = polynomial_ring(QQ, [:x, :y]);
-
-julia> H = homogenizer(P, "h");
-
-julia> H(x^2+y)
-x^2 + y*h
-
-julia> V = H.([x^2+y, x+y^2]);
-
-julia> parent(V[1]) == parent(V[2])
-true
-
-julia> H(ideal([x^2+y]))
-Ideal generated by
-  x^2 + y*h
source
homogenizerMethod
homogenizer(P::MPolyRing, W::Union{ZZMatrix, Matrix{<:IntegerUnion}}, h::VarName;  pos::Int=1+ngens(P))

Create a "homogenizing operator" using the grading specified by the columns of W; h is the prefix for the homogenizing variables; pos indicates where to put the homogenizing variables in the list of generators of the graded polynomial ring (default is after all the other variables).

Examples

julia> P, (x,y) = polynomial_ring(QQ, [:x, :y]);
-
-julia> W = ZZMatrix(2,2, [2,3,5,7]);
-
-julia> H = homogenizer(P, W, "h");
-
-julia> H(x^2+y)
-x^2 + y*h[1]*h[2]^3
-
-julia> V = H.([x^2+y, x+y^2]);
-
-julia> parent(V[1]) == parent(V[2])
-true
-
-julia> H(ideal([x^2+y]))
-Ideal generated by
-  x^2 + y*h[1]*h[2]^3
source
dehomogenizerMethod
dehomogenizer(H::Homogenizer)

Create a "dehomogenizing operator" from a Homogenizer; it is effectively a polynomial ring homomorphism mapping all homogenizing variables to 1. A Dehomogenizer is a post-inverse for the Homogenizer it was created from.

Examples

julia> P, (x,y) = polynomial_ring(QQ, [:x, :y]);
-
-julia> H = homogenizer(P, "h");
-
-julia> DH = dehomogenizer(H);
-
-julia> F = H(x^2+y)
-x^2 + y*h
-
-julia> DH(F)
-x^2 + y
-
-julia> V = [x^2+y, x*y+y^2]; HV = H.(V);
-
-julia> parent(DH(HV[1])) == P  &&  parent(DH(HV[2])) == P
-true
-
-julia> DH(H(ideal(V)))
-Ideal generated by
-  x*y + y^2
-  x^2 + y
-  y^3 + y^2
source
julia> P, (x, y) = polynomial_ring(QQ, [:x, :y]);
-
-julia> I = ideal([x^2+y, x*y+y^2]);
-
-julia> H = homogenizer(P, "h");
-
-julia> Ih = H(I)     # homogenization of ideal I
-Ideal generated by
-  x*y + y^2
-  x^2 + y*h
-  y^3 + y^2*h
-
-julia> DH = dehomogenizer(H);
-
-julia> DH(Ih) == I   # dehomogenization of Ih
-true

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 generated by
-  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 generated by
-  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/PR4245/CommutativeAlgebra/intro/index.html b/previews/PR4245/CommutativeAlgebra/intro/index.html deleted file mode 100644 index 97ae33466c8f..000000000000 --- a/previews/PR4245/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 related to multivariate polynomial rings discussed in this chapter apply to both the ungraded and graded case. 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/PR4245/CommutativeAlgebra/localizations/index.html b/previews/PR4245/CommutativeAlgebra/localizations/index.html deleted file mode 100644 index 52e0e0e63d00..000000000000 --- a/previews/PR4245/CommutativeAlgebra/localizations/index.html +++ /dev/null @@ -1,517 +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=true)

Given a prime ideal $P$ of a polynomial ring $R$, say, return the multiplicatively closed subset $R\setminus P.$

Note

Since 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 generated by
-  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 (x)
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 generated by
-  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 generated by
-  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 x, y, z
-    over rational field
-  at complement of prime ideal (x)
-
-julia> iota
-Ring homomorphism
-  from multivariate polynomial ring in 3 variables over QQ
-  to localization of multivariate polynomial ring in 3 variables over QQ at complement of prime ideal (x)
-defined by
-  x -> x
-  y -> y
-  z -> z
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 generated by
-  2*x^2 - y^3
-  2*x^2 - y^5
-
-julia> P = ideal(R, [y-1, x-a])
-Ideal generated by
-  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 K
-
-julia> RQ, _ = quo(R, I);
-
-julia> RQL, iota = localization(RQ, U);
-
-julia> RQL
-Localization
-  of quotient
-    of multivariate polynomial ring in 2 variables x, y
-      over number field of degree 2 over QQ
-    by ideal (2*x^2 - y^3, 2*x^2 - y^5)
-  at complement of prime ideal (y - 1, x - a)
-
-julia> iota
-Map defined by a julia-function
-  from quotient of multivariate polynomial ring by ideal (2*x^2 - y^3, 2*x^2 - y^5)
-  to localization of RQ at complement of prime ideal
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 generated by
-  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 generated by
-  2*x^2 - y^3
-  2*x^2 - y^5
-
-julia> P = ideal(R, [y-1, x-a])
-Ideal generated by
-  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 K
-
-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 generated by
-  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 generated by
-  2*x^2 - y^3
-  2*x^2 - y^5
-
-julia> P = ideal(R, [y-1, x-a])
-Ideal generated by
-  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 K
-
-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 behavior 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 generated by
-  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 x, y, z
-    over rational field
-  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 generated by
-  2*x^2 - y^3
-  2*x^2 - y^5
-
-julia> P = ideal(R, [y-1, x-a])
-Ideal generated by
-  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 K
-
-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 in 2 variables x, y
-      over number field of degree 2 over QQ
-    by ideal (2*x^2 - y^3, 2*x^2 - y^5)
-  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 generated by
-  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 generated by
-  2*x^2 - y^3
-  2*x^2 - y^5
-
-julia> P = ideal(R, [y-1, x-a])
-Ideal generated by
-  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 K
-
-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 RQ at complement of maximal ideal
-  to localization of multivariate polynomial ring in 1 variable over QQ at complement of maximal ideal of point (0)
-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 of point (0)
-  to localization of RQ 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)
-Ring homomorphism
-  from multivariate polynomial ring in 3 variables over QQ
-  to localization of multivariate polynomial ring in 1 variable over QQ at complement of maximal ideal of point (0)
-defined by
-  x -> t
-  y -> t^2
-  z -> t^3
-
-julia> psi = restricted_map(PSI)
-Ring homomorphism
-  from multivariate polynomial ring in 1 variable over QQ
-  to localization of RQ at complement of maximal ideal
-defined by
-  t -> x
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 generated by
-  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,
  • number_of_generators(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, [Eis95]). 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 generated by
-  x^2 + x
-
-julia> SI = saturated_ideal(I)
-Ideal generated by
-  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 generated by
-  x^2 + x
-
-julia> saturated_ideal(I)
-Ideal generated by
-  x
source
diff --git a/previews/PR4245/CommutativeAlgebra/rings/index.html b/previews/PR4245/CommutativeAlgebra/rings/index.html deleted file mode 100644 index c97e3c7b837d..000000000000 --- a/previews/PR4245/CommutativeAlgebra/rings/index.html +++ /dev/null @@ -1,621 +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, xs::AbstractVector{<:VarName}; cached::Bool = true)

Given a ring C and a vector xs of Symbols, Strings, or Characters, return a tuple R, vars, say, which consists of a polynomial ring R with coefficient ring C and a vector vars of generators (variables) which print according to the entries of xs.

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.

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, _ = polynomial_ring(ZZ, [:x, :y, :z]);
-
-julia> R2, _ = polynomial_ring(ZZ, ["x", "y", "z"]);
-
-julia> R3, _ = polynomial_ring(ZZ, ['x', 'y', 'z']);
-
-julia> R1 === R2 === R3
-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{FqMPolyRingElem}:
- 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)
-Prime field of characteristic 3
-
-julia> GF(ZZ(2)^127 - 1)
-Prime field of characteristic 170141183460469231731687303715884105727
-

Finite fields $\mathbb{F}_{p^n}$ with $p^n$ elements, $p$ a prime

julia> finite_field(2, 70, "a")
-(Finite field of degree 70 and characteristic 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)
-Prime field of characteristic 3
-
-julia> T, t = polynomial_ring(F, :t)
-(Univariate polynomial ring in t over F, t)
-
-julia> K, a = finite_field(t^2 + 1, "a")
-(Finite field of degree 2 and characteristic 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 [MS05] and [KR05] 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 [MS05]).

Note

Given a G-grading on R in OSCAR, we say that R is $\mathbb Z^m$-graded if is_free(G) && number_of_generators(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) && number_of_generators(G) == rank(G) == 1 evaluates to true, elements of G may be converted to integers and vice versa.

Types

Multivariate rings with gradings are modeled 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{FinGenAbGroupElem})

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])
-Z
-
-julia> g = gen(G, 1)
-Abelian group element [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])
-Z^2
-
-julia> g = gens(G)
-2-element Vector{FinGenAbGroupElem}:
- [1, 0]
- [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])
-Finitely generated abelian group
-  with 4 generators and 4 relations and 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]]
-5-element Vector{FinGenAbGroupElem}:
- [1, 0, 1, 1]
- [0, 1, 0, 1]
- [1, 0, 1, 0]
- [0, 1, 0, 0]
- [1, 1, 0, 0]
-
-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::AbstractVector{<:AbstractVector{<:IntegerUnion}})

Given a vector W of ngens(R) integer vectors of the same size m, say, create a free abelian group of type FinGenAbGroup 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, AbstractMatrix{<: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::AbstractVector{<:IntegerUnion})

Given a vector W of ngens(R) integers, create a free abelian group of type FinGenAbGroup 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, args...; weights, kwargs...)

Create a multivariate polynomial_ring with coefficient ring C and variables as described by args... (using the exact same syntax as polynomial_ring), and grade this ring according to the data provided by the keyword argument weights. Return the graded ring as an object of type MPolyDecRing, together with the variables.

If weights is omitted the grading is the standard $\mathbb Z$-grading, i.e. all variables are graded with weight 1.

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; weights = 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]; weights = [1, 2, 3])
-(Graded multivariate polynomial ring in 3 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x, y, z])
-
-julia> T, x = graded_polynomial_ring(QQ, :x => 1:3)
-(Graded multivariate polynomial ring in 3 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x[1], x[2], x[3]])
-
-julia> T, x, y = graded_polynomial_ring(QQ, :x => 1:3, :y => (1:2, 1:2); weights=1:7)
-(Graded multivariate polynomial ring in 7 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x[1], x[2], x[3]], MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[y[1, 1] y[1, 2]; y[2, 1] y[2, 2]])
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> S, (x, y, z) = graded_polynomial_ring(QQ, [:x, :y, :z]; weights = [1, 2, 3])
-(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 G is free abelian of rank 1, and ngens(G) == 1.

Examples

julia> S, (x, y, z) = graded_polynomial_ring(QQ, [:x, :y, :z]; weights = [1, 2, 3])
-(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 G is free abelian of rank m, and ngens(G) == m.

Examples

julia> G = abelian_group([0, 0, 2, 2])
-Finitely generated abelian group
-  with 4 generators and 4 relations and relation matrix
-  [0   0   0   0]
-  [0   0   0   0]
-  [0   0   2   0]
-  [0   0   0   2]
-
-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 = graded_polynomial_ring(QQ, :x => 1:5; weights=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)
-Abelian group element [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> S, (t, x, y) = graded_polynomial_ring(QQ, [:t, :x, :y]; weights = [-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> G = abelian_group([0, 2])
-Finitely generated abelian group
-  with 2 generators and 2 relations and relation matrix
-  [0   0]
-  [0   2]
-
-julia> W = [gen(G, 1)+gen(G, 2), gen(G, 1)]
-2-element Vector{FinGenAbGroupElem}:
- [1, 1]
- [1, 0]
-
-julia> S, (x, y) = graded_polynomial_ring(QQ, [:x, :y]; weights = 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,
  • number_of_generators(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> number_of_generators(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)
-Z
source
monomial_basisMethod
monomial_basis(R::MPolyDecRing, g::FinGenAbGroupElem)

Given a polynomial ring R over a field which is graded by a free group of type FinGenAbGroup, 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)
-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::FinGenAbGroupElem)

Given a polynomial ring R over a field which is graded by a free group, 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 will be thrown.

Examples

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, _ = graded_polynomial_ring(QQ, :x => 1:2, :y => 1:3; weights = W);
-
-julia> G = grading_group(S)
-Z^2
-
-julia> L = homogeneous_component(S, [1, 1]);
-
-julia> L[1]
-S_[1 1] of dim 6
-
-julia> FG = gens(L[1]);
-
-julia> EMB = L[2]
-Map defined by a julia-function with inverse
-  from S_[1 1] of dim 6
-  to graded multivariate polynomial ring in 5 variables over QQ
-
-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 R
-
-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), FqMPolyRingElem[x, y])
-
-julia> c = map(GF(5), [1, 2, 3])
-3-element Vector{FqFieldElem}:
- 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 prime 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{FinGenAbGroupElem, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}} with 2 entries:
-  [2] => x^2 + y
-  [3] => z
-
-julia> G = abelian_group([0, 0, 2, 2])
-Finitely generated abelian group
-  with 4 generators and 4 relations and relation matrix
-  [0   0   0   0]
-  [0   0   0   0]
-  [0   0   2   0]
-  [0   0   0   2]
-
-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 = graded_polynomial_ring(QQ, :x => 1:5; weights=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{FinGenAbGroupElem, 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::FinGenAbGroupElem)

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> G = abelian_group([0, 0, 2, 2])
-Finitely generated abelian group
-  with 4 generators and 4 relations and relation matrix
-  [0   0   0   0]
-  [0   0   0   0]
-  [0   0   2   0]
-  [0   0   0   2]
-
-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 = graded_polynomial_ring(QQ, :x => 1:5; weights=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:4; weights=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]; weights=[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> G = abelian_group([0, 0, 2, 2])
-Finitely generated abelian group
-  with 4 generators and 4 relations and relation matrix
-  [0   0   0   0]
-  [0   0   0   0]
-  [0   0   2   0]
-  [0   0   0   2]
-
-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 = graded_polynomial_ring(QQ, :x => 1:5; weights=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)
-Abelian group element [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: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))
-FinGenAbGroupElem
-
-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 = finite_field(2, 2, "a");
-
-julia> R, (x, y) = polynomial_ring(K, [:x, :y]);
-
-julia> F = hom(R, R, z -> z^2, [y, x])
-Ring homomorphism
-  from multivariate polynomial ring in 2 variables over K
-  to multivariate polynomial ring in 2 variables over K
-defined by
-  x -> y
-  y -> x
-with map on coefficients
-  #1
-
-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])
-Ring homomorphism
-  from multivariate polynomial ring in 2 variables over Qi
-  to multivariate polynomial ring in 2 variables over Qi
-defined by
-  x -> x^2
-  y -> y^2
-with map on coefficients
-  Map: Qi -> Qi
-
-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))
-Ring homomorphism
-  from multivariate polynomial ring in 2 variables over ZZ
-  to multivariate polynomial ring in 2 variables over GF(2)
-defined by
-  x -> x
-  y -> y
-
-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/PR4245/DeveloperDocumentation/AbstractCollection/index.html b/previews/PR4245/DeveloperDocumentation/AbstractCollection/index.html deleted file mode 100644 index 974d5f3caded..000000000000 --- a/previews/PR4245/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/PR4245/DeveloperDocumentation/SubObjectIterator/index.html b/previews/PR4245/DeveloperDocumentation/SubObjectIterator/index.html deleted file mode 100644 index 65997f79d0ac..000000000000 --- a/previews/PR4245/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, n_rays(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 n_rays(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, n_rays(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/PR4245/DeveloperDocumentation/caching/index.html b/previews/PR4245/DeveloperDocumentation/caching/index.html deleted file mode 100644 index ac5b5fee7f4a..000000000000 --- a/previews/PR4245/DeveloperDocumentation/caching/index.html +++ /dev/null @@ -1,28 +0,0 @@ - -Caching parent objects in OSCAR · Oscar.jl

Caching parent objects in OSCAR

Many functions in OSCAR that construct parent objects (such as rings, modules, groups, etc.) have an optional keyword argument cached::Bool. If set to true then the object is put into a cache, and when the construction function is later called again with identical inputs, then the cached object is returned instead of creating a new object. In contrast when cached is set to false then each time a new object is returned.

Example:

julia> R1, = polynomial_ring(QQ, :x; cached = true);
-
-julia> R2, = polynomial_ring(QQ, :x; cached = true);
-
-julia> R1 === R2  # identical as both were created with `cached = true`
-true
-
-julia> R3, = polynomial_ring(QQ, :x; cached = false);
-
-julia> R1 === R3  # not identical as R3 was created with `cached = false`
-false
-
-julia> R4, = polynomial_ring(QQ, :y; cached = true);
-
-julia> R1 === R4  # not identical despite `cached = true` due to differing variable names
-false

Why cache parent objects?

The main reason for supporting caching of parent objects is user convenience: experience shows that most mathematicians (espescially those who are not also programmers; but it really affects all) are surprised if, say, QQ[:x] == Q[:x] produces false.

For interactive use, it is often simply convenient: e.g. in the following example, we use map_coefficients to map polynomials over the integers to polynomials over a finite field, and the results can be added – this is only possible because the new polynomials have the same parent, thanks to caching.

julia> Zx, x = ZZ[:x]
-(Univariate polynomial ring in x over ZZ, x)
-
-julia> F = GF(2);
-
-julia> map_coefficients(F, x^2) + map_coefficients(F, x)
-x^2 + x

Caching parents also has downsides. E.g. all those cached objects take up memory which in some cases can add up to significant amounts.

Rules for implementations

In the following we describe some rules related to caching for people implementing parent constructor functions

  1. Don't use caching in code inside OSCAR (caching is for end users!)
    • i.e., code inside OSCAR by default should always construct rings with cached = false.
    • In other words: internal code should not rely on caching being active. Usually the need for using cached parents can be overcome by allowing callers to pass in a parent object as an additional function argument. One may still provide a default value for that as a user convenience, but these default parents then should be created with cached=false.
    • Rationale: this avoids clogging the system with cached objects the user never asked for. It also eliminates sources of bugs: a cached ring may have attributes assigned that modify its behavior in a way that it is completely unexpected in code dealing with "newly created" ring
  2. All end-user facing constructors should have a cached::Bool keyword argument with a default value, regardless of whether caching is actually supported or not.
    • if caching is supported, then cached should default to true
    • if caching is not supported, then cached should default to false
    • Rationale: this allows us to comply pro-actively with the first rule: when creating a parent object, you always pass in cached = false. If not all constructors support this, we can't comply with it. Even if a constructor does not support caching right now: this might change in the future. So by allowing the cached argument in all cases, we can write future-proof code.
  3. Caches must not overflow
    • the simplest solution to achieve this is to use an AbstractAlgebra.CacheDictType instances (which really is an alias for WeakValueDict) together with get_cached! which automatically removes objects from caches if nothing outside the cache references it anymore
    • Alternatively one may offer a manual way for users to "flush" caches, but beware the problems this can cause when code relies on parents being cached – yet another reason for rule 1.

For convenience, Hecke also defines these "standard rings" for use in functions like cyclotomic_polynomial

module Globals
-  using Hecke
-  const Qx, _ = polynomial_ring(FlintQQ, :x, cached = false)
-  const Zx, _ = polynomial_ring(FlintZZ, :x, cached = false)
-  const Zxy, _ = polynomial_ring(FlintZZ, [:x, :y], cached = false)
-end

You can use these in your own code as well, or imitate this pattern if convenient.

As always, if in doubt what to do, please ask.

diff --git a/previews/PR4245/DeveloperDocumentation/debugging/index.html b/previews/PR4245/DeveloperDocumentation/debugging/index.html deleted file mode 100644 index 803fde3ae1f4..000000000000 --- a/previews/PR4245/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 behavior 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 behavior 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 behavior 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/PR4245/DeveloperDocumentation/design_decisions/index.html b/previews/PR4245/DeveloperDocumentation/design_decisions/index.html deleted file mode 100644 index b3b763ff94de..000000000000 --- a/previews/PR4245/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 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/PR4245/DeveloperDocumentation/documentation/index.html b/previews/PR4245/DeveloperDocumentation/documentation/index.html deleted file mode 100644 index ec937f181bcd..000000000000 --- a/previews/PR4245/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, warnonly=true, open_browser=true, start_server=false)

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.10 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 warnonly is passed on to makedocs of Documenter.jl and if set to false then according to the manual of Documenter.jl "a doctesting error will always make makedocs throw an error in this mode". Alternatively, one can pass a list of symbols to warnonly to suppress errors for the given error types.

To prevent the opening of the browser at the end, set the optional parameter open_browser to false.

Alternatively, one can use the optional parameter start_server to start a web server in the build directory which is accessible via 127.0.0.1:8000. If both start_server and open_browser are true, the browser will show this page. The server keeps running in the background until the julia session is terminated, so the proposed usage for this option is to run build_doc(start_server = true) for the first build and build_doc(open_browser = false) for following builds and only refresh the browser tab.

When working on the manual the Revise package can significantly speed 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, subsequent runs will be significantly faster.

source

Please also read the section below on repairing the jldoctests using build_doc.

Browser reports denied access

Depending on your system, it might happen that the browser opens after a successful build, but only informs you that the access to the file was denied. This happens, for example, on Ubuntu which comes with a sandboxed Firefox. In this case, using build_doc with start_server = true should circumvent this problem.

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)

If you just want to fix some of the jldoctests, and do not want to build the documentation, you can also use Oscar.doctest_fix:

doctest_fixFunction
doctest_fix(f::Function; set_meta::Bool = false)

Fixes all doctests for the given function f.

Example

The following call fixes all doctests for the function symmetric_group:

julia> Oscar.doctest_fix(symmetric_group)
source
doctest_fix(path::String; set_meta::Bool = false)

Fixes all doctests for all files in Oscar where path occurs in the full pathname.

Example

The following call fixes all doctests in files that live in a directory called Rings (or a subdirectory thereof), so e.g. everything in src/Rings/:

julia> Oscar.doctest_fix("/Rings/")
source
Danger

Please use these commands 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 these commands fail 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.

Please follow the additional guidelines below, that are not checked by bibtool:

  • Do not escape special characters like umlauts or accented characters. Instead, use the unicode character directly.
  • You do not need to use braces to preserve capitalization as DocumenterCitations.jl keeps entries as is (in contrast to bibtex). In some cases, braces can even be harmful, i.e., show up in the output.
  • If a DOI is available for your reference, please add it as a doi field to the BibTeX entry. In this case, please refrain from adding an additional url field.
  • If your reference has no DOI or the paper is not open-access, but is available as an arXiv preprint, you can add the arXiv link as a eprint field (even additionally to a doi field). For other preprint servers (e.g. HAL), please refer to the DocumenterCitations.jl docs.
  • Documents available only as an arXiv preprint should be added as @Misc entries with the arXiv-ID in the eprint field, e.g., archiveprefix = {arXiv} and eprint = {2008.12651}.
diff --git a/previews/PR4245/DeveloperDocumentation/gap_integration/index.html b/previews/PR4245/DeveloperDocumentation/gap_integration/index.html deleted file mode 100644 index dbefa5db6e57..000000000000 --- a/previews/PR4245/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::T) -> Map{T, 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)[1]mod(Integers, n)
finite_field(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.

Note also that R and S may differ w.r.t. some structural properties because GAP does not support all kinds of constructions that are possible in Oscar. For example, if R is a non-simple number field then S will be a simple extension because GAP knows only simple field extensions. Thus using Oscar.iso_oscar_gap(R) for objects R whose recursive structure is not fully supported in GAP will likely cause overhead at runtime.

source
iso_gap_oscarFunction
Oscar.iso_gap_oscar(R) -> Map{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)[1]
GF(p, d)finite_field(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/PR4245/DeveloperDocumentation/new_developers/index.html b/previews/PR4245/DeveloperDocumentation/new_developers/index.html deleted file mode 100644 index f2119c7b96a9..000000000000 --- a/previews/PR4245/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(path::AbstractString; new::Bool = true, timed::Bool=false, ignore=[])

Run the Oscar tests in path:

  • if path is relative then it will be set to <oscardir>/test/<path>
  • if path is a directory, run all test files in that directory and below
  • if path or path.jl is a file, run this file

If a directory contains a runtests.jl file only this file will be executed, otherwise all files will be included independently.

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.

With the optional parameter timed the function will return a dict mapping file names to a named tuple with compilation times and allocations. This only works for new=false.

The parameter ignore can be used to pass a list of String or Regex patterns. Test files or folders matching these will be skipped. Strings will be compared as suffixes. This only works for new=false.

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

If a test folder contains a file called setup_tests.jl it is included automatically before each file (directly) in this directory. This can be used to define helper functions that are used in multiple test files, for example test_save_load_roundtrip for serialization.

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/PR4245/DeveloperDocumentation/printing_details/index.html b/previews/PR4245/DeveloperDocumentation/printing_details/index.html deleted file mode 100644 index 252c413292b5..000000000000 --- a/previews/PR4245/DeveloperDocumentation/printing_details/index.html +++ /dev/null @@ -1,142 +0,0 @@ - -Printing in OSCAR · Oscar.jl

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 terse, where io is an IO object (such as stdout or an IOBuffer):

show(io, MIME"text/plain"(), x)                # detailed printing
-print(io, x)                                   # one line printing
-print(terse(io), x)                            # terse printing

For reference, string interpolation "$(x)" uses one line printing via print(io, x), while on the REPL detailed printing is used to show top level objects.

display

Please do not use display! From the Julia documentation of display: "In general, you cannot assume that display output goes to stdout [...]". In particular, the output of display will not work in the jldoctests.

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 terse printing.

function Base.show(io::IO, R::NewRing)
-  if is_terse(io)
-    # no nested printing
-    print(io, "terse printing of newring ")
-  else
-    # nested printing allowed, preferably terse
-    print(io, "one line printing of newring with ")
-    print(terse(io), "terse ", 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 terse QQ
- one line printing of newring with terse 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 terse printing as well.

struct NewRing2
-  base_ring
-end
-
-base_ring(R::NewRing2) = R.base_ring
-
-function Base.show(io::IO, R::NewRing2)
-  if is_terse(io)
-    # no nested printing
-    print(io, "terse printing of newring")
-  else
-    # nested printing allowed, preferably terse
-    print(io, "I am a new ring and always print in one line " )
-    print(terse(io), 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(terse(Base.stdout) ,R)
-terse printing of newring

The terse printing uses an IOContext (see IOContext from the Julia documentation) to pass information to other show methods invoked recursively (for example in nested printings). The same mechanism can be used to pass other context data. For instance, this is used by the Scheme code in some nested printings which invoke several objects whose printing depends on a given covering: we use IOContext to pass a fix covering to the printing of each sub-object for consistency and readability.

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 is_terse(io)
-    print(io, "terse printing of newring")
-  else # this is what we call one line
-    print(io, "one line printing of newring with ")
-    print(terse(io), "terse ", 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 terse QQ

Advanced printing functionality

To facilitate printing of nested mathematical structures, we provide a modified IOCustom object. To create one, we use the following command:

prettyMethod
pretty(io::IO) -> IOCustom

Wrap io into an IOCustom object.

Examples

julia> io = AbstractAlgebra.pretty(stdout);
source

The IOCustom object allows one to locally control:

  • indentation using Indent() and Dedent(),
  • capitalization using Lowercase() and LowercaseOff().

Example

We illustrate this with an example

struct A{T}
-  x::T
-end
-
-function Base.show(io::IO, a::A)
-  io = pretty(io)
-  println(io, "Something of type A")
-  print(io, Indent(), "over ", Lowercase(), a.x)
-  print(io, Dedent()) # don't forget to undo the indentation!
-end
-
-struct B
-end
-
-function Base.show(io::IO, b::B)
-  io = 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

Moreover, one can control the pluralization of nouns when printing a set of elements with a variable number of objects. For this, one can use ItemQuantity:

Example

We illustrate this with an example

julia> struct C{T}
-       x::Vector{T}
-       end
-
-julia> function Base.show(io::IO, c::C{T}) where T
-       x = c.x
-       n = length(x)
-       print(io, "Something with ", ItemQuantity(n, "element"), " of type $T")
-       end

At the REPL, this will then be printed as follows:

julia> C(Int[2,3,4])
-Something with 3 elements of type Int64
-
-julia> C(Int[])
-Something with 0 elements of type Int64
-
-julia> C(Int[6])
-Something with 1 element of type Int64

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.

Objects may follow the value of Oscar.is_unicode_allowed() at the time of their creation for their printing, i.e. ignore later changes of the setting. This is useful for objects storing a string representation of themselves, e.g. generators of a module.

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

On using @show_name, @show_special, @show_special_elem

  • All show methods for parent objects such as rings or modules should use the @show_name macro. This macro ensures that if the object has a name (including one derived from the name of a Julia REPL variable to which the object is currently assigned) then in a compact or terse io context it is printed using that name. Here is an example illustrating this:

    julia> vector_space(GF(2), 2)
    -Vector space of dimension 2 over prime field of characteristic 2
    -
    -julia> K = GF(2)
    -Finite field F_2
    -
    -julia> vector_space(K, 2)
    -Vector space of dimension 2 over K

    The documentation for AbstractAlgebra.get_name describes how the name is determined.

  • All show methods for parent objects should also use @show_special. This checks if an attribute :show is present. If so, it has to be a function taking IO, optionally a MIME-type, and the object. This is then called instead of the usual show function.

  • Similarly, all show methods for element objects may use @show_special_elem which checks if an attribute :show_elem is present in the object's parent. The semantics are the same as for @show_special.

For details please consult the Advanced printing section of the AbstractAlgebra documentation.

diff --git a/previews/PR4245/DeveloperDocumentation/release/index.html b/previews/PR4245/DeveloperDocumentation/release/index.html deleted file mode 100644 index bf35b07df6d8..000000000000 --- a/previews/PR4245/DeveloperDocumentation/release/index.html +++ /dev/null @@ -1,2 +0,0 @@ - -Release management · Oscar.jl

Release management

We roughly follow the julia release process. The following outlines the approach taken for OSCAR 1.0.0 but is subject to change depending in how this works out.

Before preparing the release branch two developers are chosen to take care of managing the branches and taking final decisions on which changes can be merged during the release process.

Branches

Assuming the current master has version number X.Y.0-DEV, in preparation for the next release a branch release-X.Y is created directly on GitHub. Once that is done the master should be set to X.Y+1.0-DEV.

Note

Please use the script etc/update_version.sh for version changes.

Backports

The backports should be mostly bug-fixes and small improvements but no major new features or refactorings, to minimize the risk of regressions. Every change that is considered for backporting has to be merged to master first. Once in the stage of release candidates only small bug-fixes and documentation changes should be added.

Changes for the release, after the branch was created, are mostly done by cherry-picking the commits from master that correspond to the already merged PRs. Preferrably with git cherry-pick -x to keep a reference to the original commit. The cherry-picked commits are collected on a backports-release-X.Y branch and a corresponding PR, like for release 1.0.0-rc1. Please take care to set the merge target for the PR to the release-X.Y branch.

Once this set of changes is complete the PR is merged to the release branch, using a proper merge commit, i.e. please do not squash or rebase this. The list of backported PRs may be added to the commit message for the merge.

Conflicts

If changes from another PR cannot be cleanly applied to the backports branch it may be necessary to create a separate PR targeting the backports branch to manually backport changes from that PR and resolve any conflicts. Make sure that the branch for this PR branches off from the release branch and not from master (to avoid picking up unrelated commits). Then cherry-pick the relevant commits and fix any conflicts.

Pre-releases

For the next pre-release create a new PR to the release branch adjusting the version, this may be merged with a rebase to avoid some extra commits. That commit can then be tagged on GitHub as a new pre-release.

Note

Pre-releases cannot be registered in the julia registry.

For OSCAR 1.0.0 we plan to have one or two release candidates but unlike julia and due to the tight schedule no -alpha or -beta versions.

Releases

Once the version is at X.Y.0 the version can be registered in the julia registry with @JuliaRegistrator register(). In this case TagBot will create the corresponding release, but preferrably recheck and clean up the list of changes since unfortunately TagBot currently does not take the branch into account and will show all PRs that have been merged to master.

Consider deploying a released version at zenodo.

Bugfix releases

Further bugfix releases X.Y.Z can be created in a similar manner, skipping the pre-releases.

diff --git a/previews/PR4245/DeveloperDocumentation/serialization/index.html b/previews/PR4245/DeveloperDocumentation/serialization/index.html deleted file mode 100644 index 13d0f1f4edd8..000000000000 --- a/previews/PR4245/DeveloperDocumentation/serialization/index.html +++ /dev/null @@ -1,127 +0,0 @@ - -Serialization · Oscar.jl

Serialization

This document summarizes the serialization efforts of OSCAR, how it works, and what our long-term vision is. Serialization broadly speaking is the process of reading and writing data. There are many reasons for this feature in OSCAR, but the main reason is communication on mathematics by mathematicians.

We implement our serialization in accordance with the MaRDI file format specification described here. Which means we use a JSON extension to serialize data.

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.mrdi", 42);
-
-julia> load("/tmp/fourtitwo.mrdi")
-42
-

The filename hints to the MaRDI file format, which employs JSON. The file looks as follows:

{
-  "_ns": {
-    "Oscar": [
-      "https://github.com/oscar-system/Oscar.jl",
-      "0.14.0-DEV-8fe2abbe39890a7d3324adcba7f91812119c586a"
-    ]
-  },
-  "_type": "Base.Int",
-  "data": "42"
-}

It contains the precise version of OSCAR used for this serialization. The content is "42", it represents a Base.Int, according to the _type field.

Implementation

To list and describe all implementations and encodings of all types in OSCAR is not a possible feat due to the arbitrarily deep and nested type structures available in OSCAR, we point any developer looking to understand the encodings of certain types to the OSCAR source code. All files for serialization can be found in the folder src/Serialization. The convention 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.

We include a basic example of the encoding for a QQPolyRingElem so one can get a taste before delving into the source code. Here we store the polynomial x^3 + 2x + 1//2. The encoding for polynomials is to store a list of tuples, where each entry in the list represents a term of the polynomial and where the first entry of the tuple is the exponent and the second entry is the coefficient. Here we serialize a univariate polynomial so the first entries are always integers, in general this may be an array of integers. The coefficients here are elements of QQ however in general the coefficients themselves may be described as polynomials of the generators of some field extension, i.e. the second entry may again be a list of tuples and so on. The nested structure of the coefficient will depend on the description of the field extension.

{
-  "_ns": {
-    "Oscar": [
-      "https://github.com/oscar-system/Oscar.jl",
-      "1.1.0-DEV-6f7e717c759f5fc281b64f665c28f58578013c21"
-    ]
-  },
-  "_refs": {
-    "e6c5972c-4052-4408-a408-0f4f11f21e49": {
-      "_type": "PolyRing",
-      "data": {
-        "base_ring": {
-          "_type": "QQField"
-        },
-        "symbols": [
-          "x"
-        ]
-      }
-    }
-  },
-  "_type": {
-    "name": "PolyRingElem",
-    "params": "e6c5972c-4052-4408-a408-0f4f11f21e49"
-  },
-  "data": [  [      "0",      "1//2"    ],
-	     [      "1",      "2"       ],
-	     [      "3",      "1"       ]  ]
-}
-

When trying to understand an encoding of a particular type in OSCAR it is always best to make a minimal example and store it. Then use a pretty printer to format the JSON, and have it close by while going through the source code.

Description of the saving and loading mechanisms

We require that any types serialized through OSCAR are registered using @register_serialization_type. This is to ensure user safety during the load process by avoiding code evaluation.

@register_serialization_typeMacro
@register_serialization_type NewType "String Representation of type" uses_id uses_params [:attr1, :attr2]

@register_serialization_type is a macro to ensure that the string we generate matches exactly the expression passed as first argument, and does not change in unexpected ways when import/export statements are adjusted.

Passing a string argument will override how the type is stored as a string.

When setting uses_id the object will be stored as a reference and will be referred to throughout the serialization sessions using a UUID. This should typically only be used for types that do not have a fixed normal form for example PolyRing and MPolyRing.

Using the uses_params flag will serialize the object with a more structured type description which will make the serialization more efficient see the discussion on save_type_params / load_type_params below.

Passing a vector of symbols that correspond to attributes of type indicates which attributes will be serialized when using save with with_attrs=true.

source

There are three pairs of saving and loading functions that are used during serialization:

  1. save_typed_object, load_typed_object
  2. save_object, load_object
  3. save_type_params, load_type_params

save_type_object / load_type_object

For the most part these functions should not be touched, they are high level functions and are used to (de)serialize the object with its type information as well as its data. The data and type nodes are set in save_typed_object resulting in a "data branch" and "type branch". The usage of these functions can be used inside save_object / load_object and save_type_params / load_type_params. However using save_typed_object inside a save_object implementation will lead to a verbose format and should at some point be moved to save_type_params. Their implemention can be found in the main.jl file.

save_object / load_object

These functions should be the first functions to be overloaded when implementing the serialization of a new type. The functions save_data_dict and save_data_array are helpers functions that structure the serialization.

The examples show how they can be used to save data using the structure of an array or dict. Each nested call to save_data_dict or save_data_array should be called with a key that can be passed as the second parameter.

Examples
Example 1
function save_object(s::SerializerState, obj::NewType)
-  save_data_array(s) do
-    save_object(s, obj.1)
-    save_object(s, obj.2)
-   save_data_dict(s) do
-      save_object(s, obj.3, :key1)
-      save_object(s, obj.4, :key2)
-    end
-  end
-end

This will result in a data format that looks like this.

[
-  obj.1,
-  obj.2,
-  {
-    "key1": obj.3,
-    "key2": obj.4
-  }
-]

With the corresponding loading function similar to this.

function load_object(s::DeserializerState, ::Type{<:NewType})
-  (obj1, obj2, obj3_4) = load_array_node(s) do (i, entry)
-    if entry isa JSON3.Object
-      obj3 = load_object(s, Obj3Type, :key1)
-      obj4 = load_object(s, Obj3Type, :key2)
-      return OtherType(obj3, obj4)
-    else
-      if p(entry) == c
-        load_object(s, Obj1Type)
-      else
-        load_object(s, Obj2Type)
-      end
-    end
-  end
-  return NewType(obj1, obj2, obj3_4)
-end
Example 2
function save_object(s::SerializerState, obj::NewType)
-  save_data_dict(s) do
-    save_object(s, obj.1, :key1)
-    save_data_array(s, :key2) do
-      save_object(s, obj.3)
-      save_typed_object(s, obj.4) # This is ok
-    end
-  end
-end

This will result in a data format that looks like this.

{
-  "key1": obj.1,
-  "key2":[
-    obj.3,
-    {
-      "type": "Type of obj.4",
-      "data": obj.4
-    }
-  ]
-}

The corresponding loading function would look something like this.

function load_object(s::DeserializerState, ::Type{<:NewType}, params::ParamsObj)
-   obj1 = load_object(s, Obj1Type, params[1], :key1)
-
-   (obj3, obj4) = load_array_node(s, :key2) do (i, entry)
-     if i == 1
-       load_object(s, Obj3Type, params[2])
-     else
-       load_typed_object(s)
-     end
-   end
-   return NewType(obj1, OtherType(obj3, obj4))
- end

This is ok

function save_object(s::SerializerState, obj:NewType)
-  save_object(s, obj.1)
-end

While this will throw an error

function save_object(s::SerializerState, obj:NewType)
-  save_object(s, obj.1, :key)
-end

If you insist on having a key you should use a save_data_dict.

function save_object(s::SerializerState, obj:NewType)
-  save_data_dict(s) do
-    save_object(s, obj.1, :key)
-  end
-end
-
-function load_object(s::SerializerState, ::Type{<:NewType})
-  load_node(s, :key) do x
-    info = do_something(x)
-
-    if info
-      load_object(s, OtherType)
-    else
-      load_object(s, AnotherType)
-    end
-  end
-end

Note for now save_typed_object must be wrapped in either a save_data_array or save_data_dict. Otherwise you will get a key override error.

save_type_params / load_type_params

The serialization mechanism stores data in the format of a tree, with the exception that some nodes may point to a shared reference. The "data branch" is anything that is a child node of a data node, whereas the "type branch" is any information that is stored in a node that is a child of a type node. Avoiding type information inside the data branch will lead to a more efficient serialization format. When the uses_params is set when registering the type with @register_serialization_type (de)serialization will use save_type_params / load_type_params to format the type information. In general we expect that implementing a save_type_params and load_type_params should not always be necessary. Many types will serialize their types in a similar fashion for example serialization of a FieldElem will use the save_type_params / load_type_params from RingElem since in both cases the only parameter needed for such types is their parent.

Import helper

When implementing the serialization of a new type in a module that is not Oscar (e.g. in a submodule of Oscar) it is necessary to import the a lot of helper functions (see the examples above). To ease this process, the @import_all_serialization_functions macro can be used.

@import_all_serialization_functionsMacro
Oscar.@import_all_serialization_functions

This macro imports all serialization related functions that one may need for implementing serialization for custom types from Oscar into the current module. One can instead import the functions individually if needed but this macro is provided for convenience.

source

Serializers

The code for the different types of serializers and their states is found in the serializers.jl file. Different serializers have different use cases, the default serializer JSONSerializer is used for writting to a file. Currently the only other serializer is the IPCSerializer which at the moment is quite similar to the JSONSerializer except that it does not store the refs of any types that are registered with the uses_id flag. When using the IPCSerializer it is left up to the user to guarantee that any refs required by a process are sent prior.

Upgrades

All upgrade scripts can be found in the src/Serialization/Upgrades folder. The mechanics of upgrading are found in the main.jl file where the Oscar.upgrade function provides the core functionality. Upgrading is triggered during load when the version of the file format to be loaded is older than the current Oscar version.

upgradeFunction
upgrade(format_version::VersionNumber, dict::Dict)

Finds the first version where an upgrade can be applied and then incrementally upgrades to each intermediate version until the structure of the current version has been achieved.

source
upgrade_dataFunction
upgrade_data(upgrade::Function, s::UpgradeState, dict::Dict)

upgrade_data is a helper function that provides functionality for recursing on the tree structure. It is independent of any particular file format version and can be used in any upgrade script.

source

Upgrade Scripts

All upgrade scripts should be contained in a file named after the version they upgrade to. For example a script that upgrades to Oscar version 0.13.0 should be named 0.13.0.jl.

UpgradeScriptType
UpgradeScript(version::VersionNumber, script::Function)

Any upgrade scripts schould be created using the UpgradeScript constructor and then pushed to the upgrade_scripts_set. The name of the function is not particularly important however one should be assigned so that it can be used for recursion if necessary for upgrade. The upgrde script should be independent from any Oscar code and should relie solely on julia core functionality so to avoid conflicts with any future Oscar code deprecations.

Example

push!(upgrade_scripts_set, UpgradeScript(
-  v"0.13.0",
-  function upgrade_0_13_0(s::UpgradeState, dict::Dict)
-      ...
-  end
-))
source

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.

External Implementations

Any external body implementing a save/load following the .mrdi format specification and using the OSCAR namespace should be sure to check validity against our schema defined here.

We make no attempt whatsoever to verify the mathematics of the file, and neither should anyone implementing a save/load. Loading should not throw a parse error if the mathematics of the file is incorrect, the file should be parsed and allow the computer algebra system to throw the error. We cannot guarantee that any file that has been manipulated by hand is still valid and should be validated against the schema. In the same way we cannot guarantee that any files created externally are valid in terms of the mathematics either, these will not lead to a parse error but instead will be handle as though the incorrect input has been passed to one of the Oscar functions.

External implementations should not be expected to read or write all possible Oscar types. It is perfectly valid for external implementations to throw parse errors when a certain file format is unexpected. For example Oscar will parse a QQFieldElem that has data value "0 0 7 // - 1 0" as -7//10, even though this is not how it is serialized. We feel we should not restrict users when deserializing to formats that may have issues deserializing the same format externally.

Allowing extensions to JSON is not recommended, this is to keep the scope of possible software that can parse the given JSON as large as possible. For example some JSON extensions allow comments in the files, Oscar cannot parse such JSONs and we recommend that any comments should be placed in the meta field.

When writing UUIDs, adhere to version four UUIDs specified by RFC 4122.

diff --git a/previews/PR4245/DeveloperDocumentation/styleguide/index.html b/previews/PR4245/DeveloperDocumentation/styleguide/index.html deleted file mode 100644 index 805d376ff84a..000000000000 --- a/previews/PR4245/DeveloperDocumentation/styleguide/index.html +++ /dev/null @@ -1,69 +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.
  • Whenever functions expect a ring, field, algebra, etc. as input they should be passed as the first argument, for example, polynomial_ring(QQ, :x).
  • 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...
  • Input sanity checks should be enabled by default, they can then be disabled internally if they are known to be true, and manually by users.
  • All user-facing functions that expect some kind of indeterminant name etc. (like polynomial_ring(QQ, <indeterminant_name>)) should accept a VarName = Union{Symbol, Char, String}, and convert it to a symbol for internal handling. Library and test code should (if possible) call such functions with Symbol arguments, as this is the most efficient way.

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.
  • A function returning the number of some things should be named number_of_things, alternatively it can be named n_things with an alias to number_of_things. The preferred style should be consistent throughout the corresponding part. For some very common things, like the number of generators, we additionally provide a shorter alias, e.g. ngens for number_of_generators. These aliases should be very short and without underscores.
  • 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

Before making some suggestions for code formatting rules, a warning: we deliberately are lax about enforcing these rules, as often contributors (esp. new ones) already struggle enough without being forced to also adhere to specific formatting rules. As long as code is sufficiently readable, we may accept it.

But in the same vein (i.e., to minimize frictions for others working on OSCAR), we ask everyone to generally refrain from reformatting large chunks of code (even if it is to make it adhere to the rules described below), unless this is carefully coordinated with all stakeholders of the affected code.

Also, ideally don't mix code reformatting with other changes, as this makes it harder to understand what is going on. At the very least, use different commits for the reformatting changes and the actual changes. But in general you shouldn't reformat code unrelated to the changes you are making.

Editor configuration

Please check if your editor can be configured to honor our .editorconfig file, see https://editorconfig.org for more information about this.

JuliaFormatter

There is a .JuliaFormatter.toml in our git repository. To format your files, first add JuliaFormatter.jl in Julia and then use

using JuliaFormatter
-format_file("path/to/file/file.jl")

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 Unicode printing 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.

Optional arguments for parents of return values

Several objects in OSCAR have parents, e.g. polynomials, group elements, ... Whenever a function creates such objects from an input which does not involve the output's parent, we strongly recommend that the user should have the possibility to pass on this parent as a keyword argument under the name parent. Beyond that you can make more entry points for such parents available for the user's convenience.

Let's see an example. Say, you want to implement the characteristic polynomial of a matrix. You could do it as follows:

function characteristic_polynomial(A::MatrixElem)
-  kk = base_ring(A)
-  P, x = kk[:x]
-  AP = change_base_ring(P, A)
-  return det(AP - x*one(AP))
-end

You can see that the polynomial ring P, i.e. the parent of the output, is newly created in the body of the function. In particular, calling this function two times on two different matrices A and B might produce incompatible polynomials p = det(A - x*one(A)) and q = det(B - x*one(B)) with different parents. Calling p + q will result in an error.

To solve this, we should have implemented the function differently:

# Implementation of the recommended keyword argument signature:
-function characteristic_polynomial(
-    A::MatrixElem;
-    parent::AbstractAlgebra.Ring=polynomial_ring(base_ring(A), :t)[1]
-  )
-  AP = change_base_ring(parent, A)
-  x = first(gens(ring))
-  return det(AP - x*one(AP))
-end
-
-# Optional second signature to also allow for the specification of the 
-# output's parent as the first argument:
-function characteristic_polynomial(
-    P::PolyRing,
-    A::MatrixElem
-  )
-  coefficient_ring(P) === base_ring(A) || error("coefficient rings incompatible")
-  return characteristic_polynomial(A, parent=P)
-end

In fact this now allows for two different entry points for the parent ring P of the output: First as the required parent keyword argument and second as the first argument of a method of characteristic_polynomial with an extended signature. Note that within the scope of the first method's body the OSCAR function parent is necessarily overwritten by the name of the keyword argument. Hence to call the actual parent of any other object, you must then use Oscar.parent. E.g. to get the MatrixSpace of the matrix A, write Oscar.parent(A).

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 terse. 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)
-
-# terse
-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 terse 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 terse can be anywhere.
  • commas must be enclosed in brackets so that printing tuples stays unambiguous

Terse 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 terse 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. If the interface did not change, it is enough to write:

# Deprecated after CURRENT_RELEASE_VERSION
-@deprecate old_function new_function

It is possible to transform the arguments 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(arg1::Type1, arg2::Type2, ...) new_function(transform_args_for_new_function(args))

In simple cases (like changing the order of arguments), you don't need an auxiliary function:

@deprecate old_function(arg1::Type1, arg2::Type2) new_function(arg2, arg1)

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.

If you renamed a type and want to deprecate the old one, please add a line like

Base.@deprecate_type OldType NewType

This makes it still possible to use OldType in signatures and type annotations, but it will throw a deprecation warning (if they are enabled).

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/PR4245/Experimental/AlgebraicStatistics/ci/index.html b/previews/PR4245/Experimental/AlgebraicStatistics/ci/index.html deleted file mode 100644 index 8abe8dfb4a04..000000000000 --- a/previews/PR4245/Experimental/AlgebraicStatistics/ci/index.html +++ /dev/null @@ -1,55 +0,0 @@ - -Conditional independence statements · Oscar.jl

Conditional independence statements

Conditional independence (CI) statements over a ground set $N$ are triples of pairwise disjoint subsets $I, J, K \subseteq N$ denoted as $[I \mathrel{⫫} J \mid K]$. The ground set indexes objects under consideration and the CI statement asserts that once the objects in $K$ are "controlled" (conditioned on, in statistical language), the objects in $I$ reveal no information about (are independent of) the objects in $J$.

The functionality documented here deals with CI statements are combinatorial objects. Collections of CI statements are often used to state Markov properties of graphical models in statistics and are ultimately used to define ideals. Their interpretations as polynomial equations depend on the ambient ring (markov_ring or gaussian_ring).

ci_stmtMethod
ci_stmt(I::Vector{<:VarName}, J::Vector{<:VarName}, K::Vector{<:VarName}; symmetric=true, semigraphoid=true)

A conditional independence statement asserting that I is independent of J given K. These parameters are lists of names of random variables. The sets I and J must be disjoint as this package cannot yet deal with functional dependencies.

If symmetric is true, CI statements are assumed to be symmetric in their I and J components. The constructor then reorders the arguments to make the I field lexicographically smaller than the J to ensure that comparisons and hashing respect the symmetry.

If semigraphoid is set to true, the constructor also removes elements in the intersection of I and K from I (and symetrically removes the intersection of J and K from J).

As all three fields are sets, each of them may be deduplicated and sorted to ensure consistent comparison and hashing.

Examples

julia> ci_stmt(["A"], ["B"], ["X"])
-[A _||_ B | X]
-
-julia> ci_stmt(["1"], ["2", "3"], ["4", "5"])
-[1 _||_ {2, 3} | {4, 5}]
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
@CI_strMacro
CI"I...,J...|K..."

A literal syntax for denoting CI statements is provided for cases in which all variable names consist of a single character. If I and J only consist of a single element, then even the comma may be omitted. Once the three sets are extracted, ci_stmt is called.

Examples

julia> CI"AB|X"
-[A _||_ B | X]
-
-julia> CI"1,23|5424"
-[1 _||_ 3 | {2, 4, 5}]
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
==Method
Base.:(==)(lhs::CIStmt, rhs::CIStmt)

Compares CIStmts for identity in all their three fields.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
hashMethod
Base.hash(stmt:;CIStmt, h::UInt)

Computes the hash of a CIStmt.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
ci_statementsMethod
ci_statements(random_variables::Vector{<:VarName})

Return a list of all elementary CI statements over a given set of variable names. A CIStmt(I, J, K) is elementary if both I and J have only one element.

As a consequence of the semigraphoid properties, these statements are enough to describe the entire CI structure of a probability distribution.

Examples

julia> ci_statements(["A", "B", "X", "Y"])
-24-element Vector{CIStmt}:
- [A _||_ Y | {}]
- [A _||_ Y | B]
- [A _||_ Y | X]
- [A _||_ Y | {B, X}]
- [B _||_ Y | {}]
- [B _||_ Y | A]
- [B _||_ Y | X]
- [B _||_ Y | {A, X}]
- [X _||_ Y | {}]
- [X _||_ Y | A]
- ⋮
- [A _||_ X | {B, Y}]
- [B _||_ X | {}]
- [B _||_ X | A]
- [B _||_ X | Y]
- [B _||_ X | {A, Y}]
- [A _||_ B | {}]
- [A _||_ B | X]
- [A _||_ B | Y]
- [A _||_ B | {X, Y}]
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
make_elementaryMethod
make_elementary(stmt::CIStmt; semigaussoid=false)

Convert a CIStmt into an equivalent list of CIStmts all of which are elementary. The default operation assumes the semigraphoid axioms and converts $[I \mathrel{⫫} J \mid K]$ into the list consisting of $[i \mathrel{⫫} j \mid L]$ for all $i \in I$, $j \in J$ and $L$ in the interval $K \subseteq L \subseteq (I \cup J \cup K) \setminus \{i,j\}$.

If semigaussoid is true, the stronger semigaussoid axioms are assumed and L in the above procedure does not range in the interval above K but is always fixed to K. Semigaussoids are also known as compositional graphoids.

Examples

julia> make_elementary(CI"12,34|56")
-16-element Vector{CIStmt}:
- [1 _||_ 3 | {5, 6}]
- [1 _||_ 3 | {5, 6, 2}]
- [1 _||_ 3 | {5, 6, 4}]
- [1 _||_ 3 | {5, 6, 2, 4}]
- [1 _||_ 4 | {5, 6}]
- [1 _||_ 4 | {5, 6, 2}]
- [1 _||_ 4 | {5, 6, 3}]
- [1 _||_ 4 | {5, 6, 2, 3}]
- [2 _||_ 3 | {5, 6}]
- [2 _||_ 3 | {5, 6, 1}]
- [2 _||_ 3 | {5, 6, 4}]
- [2 _||_ 3 | {5, 6, 1, 4}]
- [2 _||_ 4 | {5, 6}]
- [2 _||_ 4 | {5, 6, 1}]
- [2 _||_ 4 | {5, 6, 3}]
- [2 _||_ 4 | {5, 6, 1, 3}]
-
-julia> make_elementary(CI"12,34|56"; semigaussoid=true)
-4-element Vector{CIStmt}:
- [1 _||_ 3 | {5, 6}]
- [1 _||_ 4 | {5, 6}]
- [2 _||_ 3 | {5, 6}]
- [2 _||_ 4 | {5, 6}]
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
diff --git a/previews/PR4245/Experimental/AlgebraicStatistics/gaussian_graphical_models/index.html b/previews/PR4245/Experimental/AlgebraicStatistics/gaussian_graphical_models/index.html deleted file mode 100644 index b7290831f3c1..000000000000 --- a/previews/PR4245/Experimental/AlgebraicStatistics/gaussian_graphical_models/index.html +++ /dev/null @@ -1,87 +0,0 @@ - -Gaussian Graphical Models · Oscar.jl

Gaussian Graphical Models

The OSCAR type for graphical models is of parametrized form GraphicalModel{G, T} where T represents the type of ring in which the vanishing ideal of the model belongs and G represents the associated graph. Gaussian graphical models are those where the T is of type GaussianRing which is a multivariate polynomial ring equipped with some extra features.

Gaussian Rings

gaussian_ringMethod
gaussian_ring(n::Int; s_var_name::VarName="s", K::Field=QQ, cached=false)

A polynomial ring whose variables correspond to the entries of a covariance matrix of n Gaussian random variables. It is a multivariate polynomial ring whose variables are named s[i,j]and whose coefficient field K is by default QQ.

If cached is true, the internally generated polynomial ring will be cached.

Examples

julia> R = gaussian_ring(3)
-Gaussian ring over Rational field in 6 variables
-s[1, 1], s[1, 2], s[1, 3], s[2, 2], s[2, 3], s[3, 3]
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
gensMethod
gens(R::GaussianRing)

Return the generators of the multivariate polynomial ring inside the GaussianRing as a dictionary which can be easily indexed

Examples

julia> R = gaussian_ring(3)
-Gaussian ring over Rational field in 6 variables
-s[1, 1], s[1, 2], s[1, 3], s[2, 2], s[2, 3], s[3, 3]
-
-julia> gens(R)
-Dict{Tuple{Int64, Int64}, QQMPolyRingElem} with 6 entries:
-  (1, 2) => s[1, 2]
-  (1, 1) => s[1, 1]
-  (3, 3) => s[3, 3]
-  (1, 3) => s[1, 3]
-  (2, 2) => s[2, 2]
-  (2, 3) => s[2, 3]
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
covariance_matrixMethod
covariance_matrix(R::GaussianRing)

Return the covariance matrix associated to R as a matrix over the underlying polynomial ring of R

Examples

julia> R = gaussian_ring(3)
-Gaussian ring over Rational field in 6 variables
-s[1, 1], s[1, 2], s[1, 3], s[2, 2], s[2, 3], s[3, 3]
-
-julia> covariance_matrix(R)
-[s[1, 1]   s[1, 2]   s[1, 3]]
-[s[1, 2]   s[2, 2]   s[2, 3]]
-[s[1, 3]   s[2, 3]   s[3, 3]]
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source

Directed Gaussian Graphical Models

A directed Gaussian graphical model is constructed from G::Graph{Directed} and S::GaussianRing. Optionally, the user may specify a string l_var_name::String which corresponds to the edge weights in the parametrization of the model and a string w_var_name::String for labeling the error covariance parameters.

graphical_modelMethod
graphical_model(G::Graph{Directed}, S::GaussianRing; l_var_name::VarName="l", w_var_name::VarName="w", cached=false)

A parametric statistical model associated to a directed acyclic graph. It contains a directed acylic graph G, a GaussianRing S where the vanishing ideal of the model naturally lives, and a parameter ring whose variables l[i,j] correspond to the directed edges i -> j in G.

If cached is true, the internally generated polynomial ring will be cached.

Examples

julia> M = graphical_model(graph_from_edges(Directed, [[1,2], [2,3]]), gaussian_ring(3))
-Gaussian graphical model on a directed graph with edges:
-(1, 2), (2, 3)
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source

The parametrization for a directed Gaussian graphical model on a DAG $G$ is built from the weighted adjacency matrix $\Lambda$ and the covariance matrix $\Omega$ of the error terms. The model is then the set of all covariance matrices $\Sigma = (Id - \Lambda)^{-T} \Omega (Id - \Lambda)^{-1}$. $\Lambda$ and $\Omega$ can be built with the following functions:

directed_edges_matrixMethod
directed_edges_matrix(M::GraphicalModel{Graph{Directed}, GaussianRing})

Creates the weighted adjacency matrix $\Lambda$ of a directed graph G whose entries are the parameter ring of the graphical model M.

Examples

julia> M = graphical_model(graph_from_edges(Directed, [[1,2], [2,3]]), gaussian_ring(3))
-Gaussian graphical model on a directed graph with edges:
-(1, 2), (2, 3)
-
-julia> directed_edges_matrix(M)
-[0   l[1, 2]         0]
-[0         0   l[2, 3]]
-[0         0         0]
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
error_covariance_matrixMethod
error_covariance_matrix(M::GraphicalModel{Graph{Directed}, GaussianRing})

Creates the covariance matrix $ \Omega $ of the independent error terms in a directed Gaussian graphical model M

Examples

julia> M = graphical_model(graph_from_edges(Directed, [[1,2], [2,3]]), gaussian_ring(3))
-Gaussian graphical model on a directed graph with edges:
-(1, 2), (2, 3)
-
-julia> error_covariance_matrix(M)
-[w[1]      0      0]
-[   0   w[2]      0]
-[   0      0   w[3]]
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source

It is easy to create new types of graphical models by overloading the methods directed_edges_matrix and error_covariance_matrix. For instance, colored graphical models may easily be created by creating a new type of GraphicalModel{G, T} and a new directed_edges_matrix function. The following two functions will then work almost immediately on this new type.

parametrizationMethod
parametrization(M::GraphicalModel{Graph{Directed}, GaussianRing})

Creates the polynomial map which parametrizes the vanishing ideal of the directed Gaussian graphical model M. The vanishing ideal of the statistical model is the kernel of this map. This ring map is the pull back of the parametrization $\phi_G$ given by $(Id - \Lambda)^{-T} \Omega (Id - \Lambda)^{T} \mapsto \Sigma$ where $\Lambda =$ directed_edges_matrix(M) and $ \Omega = $ error_covariance_matrix(M).

Examples

julia> M = graphical_model(graph_from_edges(Directed, [[1,2], [2,3]]), gaussian_ring(3))
-Gaussian graphical model on a directed graph with edges:
-(1, 2), (2, 3)
-
-julia> parametrization(M)
-Ring homomorphism
-  from multivariate polynomial ring in 6 variables over QQ
-  to multivariate polynomial ring in 5 variables over QQ
-defined by
-  s[1, 1] -> w[1]
-  s[1, 2] -> l[1, 2]*w[1]
-  s[1, 3] -> l[1, 2]*l[2, 3]*w[1]
-  s[2, 2] -> l[1, 2]^2*w[1] + w[2]
-  s[2, 3] -> l[1, 2]^2*l[2, 3]*w[1] + l[2, 3]*w[2]
-  s[3, 3] -> l[1, 2]^2*l[2, 3]^2*w[1] + l[2, 3]^2*w[2] + w[3]
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
vanishing_idealMethod
vanishing_ideal(M::GraphicalModel)

Computes the vanishing ideal for a graphical model M. This is done by computing the kernel of the parametrization.

Examples

julia> M = graphical_model(graph_from_edges(Directed, [[1,2], [2,3]]), gaussian_ring(3))
-Gaussian graphical model on a directed graph with edges:
-(1, 2), (2, 3)
-
-julia> vanishing_ideal(M)
-Ideal generated by
-  -s[1, 2]*s[2, 3] + s[1, 3]*s[2, 2]
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source

With almost all graphical models, the vanishing ideal is computed by taking the kernel of the ring map given by parametrization(M:GraphicalModel{G, T}).

Undirected Gaussian Graphical Models

A undirected Gaussian graphical model is constructed from G::Graph{Undirected}, S::GaussianRing. Optionally, the user may specify a string k_var_name::String which corresponds to the entries of the concentration matrix.

graphical_modelMethod
graphical_model(G::Graph{Undirected}, S::GaussianRing; k_var_name::VarName="k", cached=false)

A parametric statistical model associated to an undirected graph. It contains an undirected graph G, a GaussianRing S where the vanishing ideal of the model naturally lives, and a parameter ring whose variables k[i,j] correspond to the edges i - j in G.

If cached is true, the internally generated polynomial ring will be cached.

Examples

julia> M = graphical_model(graph_from_edges([[1,2], [2,3]]), gaussian_ring(3))
-Gaussian graphical model on an undirected graph with edges:
-(1, 2), (2, 3)
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source

As with their directed counterpart, it is very easy to create new subtypes of graphical models by overloading the function concentration_matrix below. Unlike most other types of graphical models though, the vanishing ideal computation of an undirected graphical model is done by eliminating all concentration variables $k_{ij}$ from the ideal given by the equations $\Sigma K - Id$ after saturating by $\det(K)$.

concentration_matrixMethod
concentration_matrix(M::GraphicalModel{Graph{Undirected}, GaussianRing})

Creates the concentration matrix K of an undirected Gaussian graphical model which is a symmetric positive definite matrix whose nonzero entries correspond to the edges of the associated graph.

Examples

julia> M = graphical_model(graph_from_edges([[1,2], [2,3]]), gaussian_ring(3))
-Gaussian graphical model on an undirected graph with edges:
-(1, 2), (2, 3)
-
-julia> concentration_matrix(M)
-[k[1, 1]   k[1, 2]         0]
-[k[1, 2]   k[2, 2]   k[2, 3]]
-[      0   k[2, 3]   k[3, 3]]
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
parametrizationMethod
parametrization(M::GraphicalModel{Graph{Undirected}, GaussianRing})

Creates the polynomial map which parametrizes the vanishing ideal of the undirected Gaussian graphical model M. The vanishing ideal of the statistical model is the kernel of this map. This ring map is the pull back of the parametrization $\phi_G$ given by $ K \mapsto K^{-1}$ where $ K = $ concentration_matrix(M) and the entries of $ K^{-1} $ are given by the standard cofactor formula.

Examples

julia> M = graphical_model(graph_from_edges([[1,2], [2,3]]), gaussian_ring(3))
-Gaussian graphical model on an undirected graph with edges:
-(1, 2), (2, 3)
-
-julia> parametrization(M)
-Ring homomorphism
-  from multivariate polynomial ring in 6 variables over QQ
-  to fraction field of multivariate polynomial ring
-defined by
-  s[1, 1] -> (k[2, 2]*k[3, 3] - k[2, 3]^2)//(k[1, 1]*k[2, 2]*k[3, 3] - k[1, 1]*k[2, 3]^2 - k[1, 2]^2*k[3, 3])
-  s[1, 2] -> (-k[1, 2]*k[3, 3])//(k[1, 1]*k[2, 2]*k[3, 3] - k[1, 1]*k[2, 3]^2 - k[1, 2]^2*k[3, 3])
-  s[1, 3] -> (k[1, 2]*k[2, 3])//(k[1, 1]*k[2, 2]*k[3, 3] - k[1, 1]*k[2, 3]^2 - k[1, 2]^2*k[3, 3])
-  s[2, 2] -> (k[1, 1]*k[3, 3])//(k[1, 1]*k[2, 2]*k[3, 3] - k[1, 1]*k[2, 3]^2 - k[1, 2]^2*k[3, 3])
-  s[2, 3] -> (-k[1, 1]*k[2, 3])//(k[1, 1]*k[2, 2]*k[3, 3] - k[1, 1]*k[2, 3]^2 - k[1, 2]^2*k[3, 3])
-  s[3, 3] -> (k[1, 1]*k[2, 2] - k[1, 2]^2)//(k[1, 1]*k[2, 2]*k[3, 3] - k[1, 1]*k[2, 3]^2 - k[1, 2]^2*k[3, 3])
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
vanishing_idealMethod
vanishing_ideal(M::GraphicalModel{Graph{Undirected}, GaussianRing})

Computes the vanishing ideal of the undirected Gaussian graphical model M. This is done by saturating the ideal given by $ \Sigma K - Id $ by the determinant of $ K $ and then eliminating all variables k[i,j] where $ K =$ concentration_matrix(M).

Examples

julia> M = graphical_model(graph_from_edges([[1,2], [2,3]]), gaussian_ring(3))
-Gaussian graphical model on an undirected graph with edges:
-(1, 2), (2, 3)
-
-julia> vanishing_ideal(M)
-Ideal generated by
-  -s[1, 2]*s[2, 3] + s[1, 3]*s[2, 2]
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
diff --git a/previews/PR4245/Experimental/AlgebraicStatistics/graphical_models/index.html b/previews/PR4245/Experimental/AlgebraicStatistics/graphical_models/index.html deleted file mode 100644 index da94d646df09..000000000000 --- a/previews/PR4245/Experimental/AlgebraicStatistics/graphical_models/index.html +++ /dev/null @@ -1,8 +0,0 @@ - -Graphical Models · Oscar.jl

Graphical Models

The OSCAR type for graphical models is of parametrized form GraphicalModel{G, T} where T represents the type of ring in which the vanishing ideal of the model belongs and G represents the associated graph. This parametrized typing allows the user to easily build upon the existing functionality to work with newer variations on graphical models such as those with colours or hidden variables.

Many basic functions are defined for all graphical models M such as

  • graph(M) refers to the associated graph
  • ring(M) to the multivariate polynomial ring where the model resides
  • param_ring to the multivariate polynomial ring where the parameters reside
  • param_gens to the parameters of the model which are ring variables stored typically stored in a hash table for convienent indexing

This part of OSCAR also includes some basic graph functionality such as finding the vertices of a graph or its set of maximal cliques. Lastly, while many methods for graphical models depend heavily on whether or not they are discrete/Gaussian or directed/undirected some funcionality is independent of this and thus implemented simulataneously for all graphical models. For example, the vanishing ideal of the model:

vanishing_idealMethod
vanishing_ideal(M::GraphicalModel)

Computes the vanishing ideal for a graphical model M. This is done by computing the kernel of the parametrization.

Examples

julia> M = graphical_model(graph_from_edges(Directed, [[1,2], [2,3]]), gaussian_ring(3))
-Gaussian graphical model on a directed graph with edges:
-(1, 2), (2, 3)
-
-julia> vanishing_ideal(M)
-Ideal generated by
-  -s[1, 2]*s[2, 3] + s[1, 3]*s[2, 2]
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
diff --git a/previews/PR4245/Experimental/AlgebraicStatistics/introduction/index.html b/previews/PR4245/Experimental/AlgebraicStatistics/introduction/index.html deleted file mode 100644 index 3963bcfd1d33..000000000000 --- a/previews/PR4245/Experimental/AlgebraicStatistics/introduction/index.html +++ /dev/null @@ -1,2 +0,0 @@ - -Introduction · Oscar.jl

Introduction

Algebraic Statistics uses tools from algebra, geometry, and combinatorics to solve problems in statistics. In particular, since many parametric statistical models are parametrized by rational functions of their parameters, they can be viewed as algebraic varieties. This part of OSCAR provides functionality for working with the following commonly used models:

  • undirected and directed Gaussian graphical models
  • undirected and directed discrete graphical models
  • phylogenetic Markov models on trees and networks
  • discrete and Gaussian conditional independence models

Most of the above models are graphical models which are parametric statistical models $\mathcal{M}_G$ associated to a graph $G$. In all of the cases described above, the model $\mathcal{M}_G = \phi_{G}$ where $\phi_G$ is a rational map. Key features include:

  • Constructing and working with the parametrizations $\phi_G$
  • Computing a (partial) generating set of $\text{ker}(\phi_G)$
  • Determining the local and global conditional independence statements implied by $G$
  • Constructing critical ideals and computing maximum likelihood and euclidean distance degrees

General textbooks offering details on theory and algorithms include:

Contact

Please direct questions about this part of OSCAR to the following people:

diff --git a/previews/PR4245/Experimental/AlgebraicStatistics/markov/index.html b/previews/PR4245/Experimental/AlgebraicStatistics/markov/index.html deleted file mode 100644 index 371efe454187..000000000000 --- a/previews/PR4245/Experimental/AlgebraicStatistics/markov/index.html +++ /dev/null @@ -1,81 +0,0 @@ - -Discrete random variables · Oscar.jl

Discrete random variables

The joint probability distribution of random variables $X_1, \ldots, X_n$ is given by a tensor of order $n$. If the random variable $X_i$ takes $d_i$ states, the tensor is of format $d_1 \times \cdots \times d_n$ and consists of non-negative real numbers $p_{x_1 \cdots x_n}$, for all choices $x_i \in [d_i]$, which sum to $1$. The functions below deal with the ambient polynomial ring in these $p$ variables, special forms in them like marginals, and conditional independence ideals.

markov_ringMethod
markov_ring(rvs::Pair{<:VarName, <:AbstractArray}...; unknown::VarName="p", K::Field=QQ, cached=false)::MarkovRing
-tensor_ring(rvs::Pair{<:VarName, <:AbstractArray}...; unknown::VarName="p", K::Field=QQ, cached=false)::MarkovRing

The polynomial ring whose unknowns are the entries of a probability tensor. rvs is a list of pairs X => Q where X is the name of a random variable and Q is the list of states it takes. The polynomial ring being constructed will have one variable for each element in the cartesian product of the Qs. It is a multivariate polynomial ring whose variables are named p[...] and whose coefficient field K is by default QQ. These settings can be changed via the optional arguments.

If cached is true, the internally generated polynomial ring will be cached.

The name tensor_ring is an alias for the constructor markov_ring because that is really what a MarkovRing is: the coordinate ring of tensors of a fixed format. The name MarkovRing is kept for compatibility in terminology with the Macaulay2 package GraphicalModels.

Examples

julia> R = markov_ring("A" => 1:2, "B" => 1:2, "X" => 1:2, "Y" => 1:2)
-MarkovRing for random variables A -> {1, 2}, B -> {1, 2}, X -> {1, 2}, Y -> {1, 2} in 16 variables over Rational field
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
tensor_ringMethod
markov_ring(rvs::Pair{<:VarName, <:AbstractArray}...; unknown::VarName="p", K::Field=QQ, cached=false)::MarkovRing
-tensor_ring(rvs::Pair{<:VarName, <:AbstractArray}...; unknown::VarName="p", K::Field=QQ, cached=false)::MarkovRing

The polynomial ring whose unknowns are the entries of a probability tensor. rvs is a list of pairs X => Q where X is the name of a random variable and Q is the list of states it takes. The polynomial ring being constructed will have one variable for each element in the cartesian product of the Qs. It is a multivariate polynomial ring whose variables are named p[...] and whose coefficient field K is by default QQ. These settings can be changed via the optional arguments.

If cached is true, the internally generated polynomial ring will be cached.

The name tensor_ring is an alias for the constructor markov_ring because that is really what a MarkovRing is: the coordinate ring of tensors of a fixed format. The name MarkovRing is kept for compatibility in terminology with the Macaulay2 package GraphicalModels.

Examples

julia> R = markov_ring("A" => 1:2, "B" => 1:2, "X" => 1:2, "Y" => 1:2)
-MarkovRing for random variables A -> {1, 2}, B -> {1, 2}, X -> {1, 2}, Y -> {1, 2} in 16 variables over Rational field
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
ringMethod
ring(R::MarkovRing)

Return the multivariate polynomial ring inside R.

Examples

julia> R = markov_ring("A" => 1:2, "B" => 1:2, "X" => 1:2, "Y" => 1:2)
-MarkovRing for random variables A -> {1, 2}, B -> {1, 2}, X -> {1, 2}, Y -> {1, 2} in 16 variables over Rational field
-
-julia> ring(R)
-Multivariate polynomial ring in 16 variables p[1, 1, 1, 1], p[2, 1, 1, 1], p[1, 2, 1, 1], p[2, 2, 1, 1], ..., p[2, 2, 2, 2]
-  over rational field
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
random_variablesMethod
random_variables(R::MarkovRing)

Return the list of random variables used to create the MarkovRing.

Examples

julia> R = markov_ring("A" => 1:2, "B" => 1:2, "X" => 1:2, "Y" => 1:2)
-MarkovRing for random variables A -> {1, 2}, B -> {1, 2}, X -> {1, 2}, Y -> {1, 2} in 16 variables over Rational field
-
-julia> random_variables(R)
-4-element Vector{Union{Char, AbstractString, Symbol}}:
- "A"
- "B"
- "X"
- "Y"
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
ci_statementsMethod
ci_statements(R::MarkovRing)

Returns all the CIStmt objects which can be formed on the random_variables(R).

julia> R = markov_ring("A" => 1:2, "B" => 1:2, "X" => 1:2, "Y" => 1:2)
-MarkovRing for random variables A -> {1, 2}, B -> {1, 2}, X -> {1, 2}, Y -> {1, 2} in 16 variables over Rational field
-
-julia> ci_statements(R)
-24-element Vector{CIStmt}:
- [A _||_ Y | {}]
- [A _||_ Y | B]
- [A _||_ Y | X]
- [A _||_ Y | {B, X}]
- [B _||_ Y | {}]
- [B _||_ Y | A]
- [B _||_ Y | X]
- [B _||_ Y | {A, X}]
- [X _||_ Y | {}]
- [X _||_ Y | A]
- ⋮
- [A _||_ X | {B, Y}]
- [B _||_ X | {}]
- [B _||_ X | A]
- [B _||_ X | Y]
- [B _||_ X | {A, Y}]
- [A _||_ B | {}]
- [A _||_ B | X]
- [A _||_ B | Y]
- [A _||_ B | {X, Y}]
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
unknownsMethod
unknowns(R::MarkovRing)

Return the generators of the polynomial ring.

Examples

julia> R = markov_ring("A" => 1:2, "B" => 1:2, "X" => 1:2, "Y" => 1:2)
-MarkovRing for random variables A -> {1, 2}, B -> {1, 2}, X -> {1, 2}, Y -> {1, 2} in 16 variables over Rational field
-
-julia> unknowns(R)
-Dict{NTuple{4, Int64}, QQMPolyRingElem} with 16 entries:
-  (2, 2, 2, 2) => p[2, 2, 2, 2]
-  (2, 2, 2, 1) => p[2, 2, 2, 1]
-  (1, 2, 1, 2) => p[1, 2, 1, 2]
-  (1, 2, 1, 1) => p[1, 2, 1, 1]
-  (2, 2, 1, 2) => p[2, 2, 1, 2]
-  (2, 2, 1, 1) => p[2, 2, 1, 1]
-  (1, 1, 2, 2) => p[1, 1, 2, 2]
-  (1, 1, 2, 1) => p[1, 1, 2, 1]
-  (2, 1, 2, 2) => p[2, 1, 2, 2]
-  (2, 1, 2, 1) => p[2, 1, 2, 1]
-  (1, 1, 1, 2) => p[1, 1, 1, 2]
-  (1, 1, 1, 1) => p[1, 1, 1, 1]
-  (1, 2, 2, 2) => p[1, 2, 2, 2]
-  (1, 2, 2, 1) => p[1, 2, 2, 1]
-  (2, 1, 1, 2) => p[2, 1, 1, 2]
-  (2, 1, 1, 1) => p[2, 1, 1, 1]
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
gensMethod
gens(R::MarkovRing)

Alias for unknowns. Return generators of the polynomial ring.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
find_random_variablesMethod
find_random_variables(R::MarkovRing, K)

Given a subset K of random_variables(R) return its indices into the data structure R.random_variables.

source
find_stateMethod
find_state(R::MarkovRing, K, x)

Given a set of random variables K and a joint event x they can take, return the index vector y of x in the data structure R.state_spaces such that x[i] = R.state_spaces[J[i]][v[i]] where J = find_random_variables(R, K).

source
state_spaceFunction
state_space(R::MarkovRing, K=random_variables(R))

Return all states that the random subvector indexed by K can attain in the ring R. The result is an Iterators.product iterator unless K has only one element in which case it is a vector.

Examples

julia> R = markov_ring("A" => 1:2, "B" => 1:2, "X" => 1:2, "Y" => 1:2)
-MarkovRing for random variables A -> {1, 2}, B -> {1, 2}, X -> {1, 2}, Y -> {1, 2} in 16 variables over Rational field
-
-julia> collect(state_space(R, ["A", "B"]))
-2×2 Matrix{Tuple{Int64, Int64}}:
- (1, 1)  (1, 2)
- (2, 1)  (2, 2)
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
marginalMethod
marginal(R::MarkovRing, K, x)

Return a marginal as a sum of unknowns from R. The argument K lists random variables which are fixed to the event x; all other random variables in R are summed over their respective state spaces.

Examples

julia> R = markov_ring("A" => 1:2, "B" => 1:2, "X" => 1:2, "Y" => 1:2)
-MarkovRing for random variables A -> {1, 2}, B -> {1, 2}, X -> {1, 2}, Y -> {1, 2} in 16 variables over Rational field
-
-julia> marginal(R, ["A", "X"], [1,2])
-p[1, 1, 2, 1] + p[1, 2, 2, 1] + p[1, 1, 2, 2] + p[1, 2, 2, 2]
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
ci_idealMethod
ci_ideal(R::MarkovRing, stmts)::MPolyIdeal

Return the ideal for the conditional independence statements given by stmts.

Examples

julia> R = markov_ring("A" => 1:2, "B" => 1:2, "X" => 1:2)
-MarkovRing for random variables A -> {1, 2}, B -> {1, 2}, X -> {1, 2} in 8 variables over Rational field
-
-julia> ci_ideal(R, [CI"X,A|B", CI"X,B|A"])
-Ideal generated by
-  p[1, 1, 1]*p[2, 1, 2] - p[2, 1, 1]*p[1, 1, 2]
-  p[1, 2, 1]*p[2, 2, 2] - p[2, 2, 1]*p[1, 2, 2]
-  p[1, 1, 1]*p[1, 2, 2] - p[1, 2, 1]*p[1, 1, 2]
-  p[2, 1, 1]*p[2, 2, 2] - p[2, 2, 1]*p[2, 1, 2]
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
diff --git a/previews/PR4245/Experimental/AlgebraicStatistics/phylogenetics/index.html b/previews/PR4245/Experimental/AlgebraicStatistics/phylogenetics/index.html deleted file mode 100644 index 45d4922830d5..000000000000 --- a/previews/PR4245/Experimental/AlgebraicStatistics/phylogenetics/index.html +++ /dev/null @@ -1,197 +0,0 @@ - -Algebraic Phylogenetics · Oscar.jl

Algebraic Phylogenetics

The Algebraic Phylogenetics part of OSCAR provides functionality for

  • specifying phylogenetic models
  • parametrizing such models
  • calculating their algebraic invariants

Models

The five most common models in algebraic phylogenetics can automatically be specified by calling the below functions, each taking a tree as input and attaching transition matrices to its edges as defined by Jukes Cantor, Kimura, etc., respectively, returning a structure PhylogeneticModel or GroupBasedPhylogeneticModel.

cavender_farris_neyman_modelMethod
cavender_farris_neyman_model(graph::Graph{Directed})

Creates a PhylogeneticModel based on graph whose transition matrices are of type Cavender-Farris-Neyman.

Examples

julia> cavender_farris_neyman_model(graph_from_edges(Directed,[[4,1],[4,2],[4,3]]))
-Group-based phylogenetic model on a tree with 3 leaves and 3 edges 
- with distribution at the root [1//2, 1//2]. 
- The transition matrix associated to edge i is of the form 
- [a[i] b[i];
-  b[i] a[i]], 
- and the Fourier parameters are [x[i, 1] x[i, 2]].
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
jukes_cantor_modelMethod
jukes_cantor_model(graph::Graph{Directed})

Creates a PhylogeneticModel based on graph whose transition matrices are Jukes Cantor matrices.

Examples

julia> jukes_cantor_model(graph_from_edges(Directed,[[4,1],[4,2],[4,3]]))
-Group-based phylogenetic model on a tree with 3 leaves and 3 edges 
- with distribution at the root [1//4, 1//4, 1//4, 1//4]. 
- The transition matrix associated to edge i is of the form 
- [a[i] b[i] b[i] b[i];
-  b[i] a[i] b[i] b[i];
-  b[i] b[i] a[i] b[i];
-  b[i] b[i] b[i] a[i]], 
- and the Fourier parameters are [x[i, 1] x[i, 2] x[i, 2] x[i, 2]].
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
kimura2_modelMethod
kimura2_model(graph::Graph{Directed})

Creates a PhylogeneticModel based on graph whose transition matrices are Kimura 2-parameter matrices.

Examples

julia> kimura2_model(graph_from_edges(Directed,[[4,1],[4,2],[4,3]]))
-Group-based phylogenetic model on a tree with 3 leaves and 3 edges
- with distribution at the root [1//4, 1//4, 1//4, 1//4]. 
- The transition matrix associated to edge i is of the form 
- [a[i] b[i] c[i] b[i];
-  b[i] a[i] b[i] c[i];
-  c[i] b[i] a[i] b[i];
-  b[i] c[i] b[i] a[i]], 
- and the Fourier parameters are [x[i, 1] x[i, 3] x[i, 2] x[i, 2]].
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
kimura3_modelMethod
kimura3_model(graph::Graph{Directed})

Creates a PhylogeneticModel based on graph whose transition matrices are Kimura 3-parameter matrices.

Examples

julia> kimura3_model(graph_from_edges(Directed,[[4,1],[4,2],[4,3]]))
-Group-based phylogenetic model on a tree with 3 leaves and 3 edges 
- with distribution at the root [1//4, 1//4, 1//4, 1//4]. 
- The transition matrix associated to edge i is of the form 
- [a[i] b[i] c[i] d[i];
-  b[i] a[i] d[i] c[i];
-  c[i] d[i] a[i] b[i];
-  d[i] c[i] b[i] a[i]], 
- and the Fourier parameters are [x[i, 1] x[i, 2] x[i, 3] x[i, 4]].
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
general_markov_modelMethod
general_markov_model(graph::Graph{Directed})

Creates a PhylogeneticModel based on graph whose transition matrices are stochastic with no further constraints.

Examples

julia> general_markov_model(graph_from_edges(Directed,[[4,1],[4,2],[4,3]]))
-Phylogenetic model on a tree with 3 leaves and 3 edges 
- with distribution at the root [π[1], π[2], π[3], π[4]] 
- and transition matrix associated to edge i of the form 
- [m[i, 1, 1] m[i, 1, 2] m[i, 1, 3] m[i, 1, 4];
-  m[i, 2, 1] m[i, 2, 2] m[i, 2, 3] m[i, 2, 4];
-  m[i, 3, 1] m[i, 3, 2] m[i, 3, 3] m[i, 3, 4];
-  m[i, 4, 1] m[i, 4, 2] m[i, 4, 3] m[i, 4, 4]].
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source

The models are by default in projective space. For their affine versions, call

affine_phylogenetic_model!Method
affine_phylogenetic_model!(pm::PhylogeneticModel)

Moves a PhylogeneticModel or GroupBasedPhylogeneticModel from projective into affine space.

Examples

julia> pm = jukes_cantor_model(graph_from_edges(Directed,[[4,1],[4,2],[4,3]]));
-
-julia> affine_phylogenetic_model!(pm)
-Group-based phylogenetic model on a tree with 3 leaves and 3 edges
- with distribution at the root [1//4, 1//4, 1//4, 1//4].
- The transition matrix associated to edge i is of the form
- [-3*b[i]+1 b[i] b[i] b[i];
-  b[i] -3*b[i]+1 b[i] b[i];
-  b[i] b[i] -3*b[i]+1 b[i];
-  b[i] b[i] b[i] -3*b[i]+1],
- and the Fourier parameters are [1 x[i, 2] x[i, 2] x[i, 2]].
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source

Components of a model

PhylogeneticModel specifies any phylogenetic tree model in probability coordinates and GroupBasedPhylogeneticModel can specify group-based, e.g. Fourier, coordinates. For any model, we can call its graph, transition matrices attached to the graph's edges, the number of states of each vertex random variable, and the corresponding polynomial rings. For instance for Jukes Cantor on the star with three leaves:

graphMethod
graph(pm::PhylogeneticModel)

Return the graph of a PhylogeneticModel pm.

Examples

julia> pm = jukes_cantor_model(graph_from_edges(Directed,[[4,1],[4,2],[4,3]]));
-
-julia> graph(pm)
-Directed graph with 4 nodes and the following edges:
-(4, 1)(4, 2)(4, 3)
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
transition_matricesMethod
transition_matrices(pm::PhylogeneticModel)

Return a dictionary between the edges of the tree specifying the PhylogeneticModel pm and their attached transition matrices.

Examples

julia> pm = jukes_cantor_model(graph_from_edges(Directed,[[4,1],[4,2],[4,3]]));
-
-julia> transition_matrices(pm)
-Dict{Edge, MatElem{QQMPolyRingElem}} with 3 entries:
-  Edge(4, 1) => [a[1] b[1] b[1] b[1]; b[1] a[1] b[1] b[1]; b[1] b[1] a[1] b[1];…
-  Edge(4, 2) => [a[2] b[2] b[2] b[2]; b[2] a[2] b[2] b[2]; b[2] b[2] a[2] b[2];…
-  Edge(4, 3) => [a[3] b[3] b[3] b[3]; b[3] a[3] b[3] b[3]; b[3] b[3] a[3] b[3];…
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
number_statesMethod
number_states(pm::PhylogeneticModel)

Return the number of states of the PhylogeneticModel pm.

Examples

julia> pm = jukes_cantor_model(graph_from_edges(Directed,[[4,1],[4,2],[4,3]]));
-
-julia> number_states(pm)
-4
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
probability_ringMethod
probability_ring(pm::PhylogeneticModel)

Return the ring of probability coordinates of the PhylogeneticModel pm.

Examples

julia> pm = jukes_cantor_model(graph_from_edges(Directed,[[4,1],[4,2],[4,3]]));
-
-julia> probability_ring(pm)
-Multivariate polynomial ring in 6 variables a[1], a[2], a[3], b[1], ..., b[3]
-  over rational field
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
fourier_ringMethod
fourier_ring(pm::GroupBasedPhylogeneticModel)

Return the ring of Fourier coordinates of the PhylogeneticModel pm.

Examples

julia> pm = jukes_cantor_model(graph_from_edges(Directed,[[4,1],[4,2],[4,3]]));
-
-julia> fourier_ring(pm)
-Multivariate polynomial ring in 6 variables x[1, 1], x[2, 1], x[3, 1], x[1, 2], ..., x[3, 2]
-  over rational field
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
fourier_parametersMethod
fourier_parameters(pm::GroupBasedPhylogeneticModel)

Return the Fourier parameters of the GroupBasedPhylogeneticModel pm as a vector of eigenvalues of the transition matrices.

Examples

julia> pm = jukes_cantor_model(graph_from_edges(Directed,[[4,1],[4,2],[4,3]]));
-
-julia> fourier_parameters(pm)
-Dict{Edge, Vector{QQMPolyRingElem}} with 3 entries:
-  Edge(4, 1) => [x[1, 1], x[1, 2], x[1, 2], x[1, 2]]
-  Edge(4, 2) => [x[2, 1], x[2, 2], x[2, 2], x[2, 2]]
-  Edge(4, 3) => [x[3, 1], x[3, 2], x[3, 2], x[3, 2]]
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
group_of_modelMethod
group_of_model(pm::GroupBasedPhylogeneticModel)

Returns the group the GroupBasedPhylogeneticModel pm is based on.

Examples

julia> pm = jukes_cantor_model(graph_from_edges(Directed,[[4,1],[4,2],[4,3]]));
-
-julia> group_of_model(pm)
-4-element Vector{FinGenAbGroupElem}:
- [0, 0]
- [0, 1]
- [1, 0]
- [1, 1]
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source

Parametrization

For each phylogenetic model, we can calculate the parametrization, a map from transition matrices to probabilities, parametrized in probability or Fourier coordinates. For group-based models, we can reparametrize between these and return the transformation matrix, and we can calculate equivalence classes of probabilities with the same parametrization.

probability_mapMethod
probability_map(pm::PhylogeneticModel)

Create a parametrization for a PhylogeneticModel of type Dictionary.

Iterate through all possible states of the leaf random variables and calculates their corresponding probabilities using the root distribution and laws of conditional independence. Return a dictionary of polynomials indexed by the states. Use auxiliary function monomial_parametrization(pm::PhylogeneticModel, states::Dict{Int, Int}) and probability_parametrization(pm::PhylogeneticModel, leaves_states::Vector{Int}).

Examples

julia> pm = jukes_cantor_model(graph_from_edges(Directed,[[4,1],[4,2],[4,3]]));
-
-julia> p = probability_map(pm)
-Dict{Tuple{Vararg{Int64}}, QQMPolyRingElem} with 64 entries:
-  (1, 2, 1) => 1//4*a[1]*a[3]*b[2] + 1//4*a[2]*b[1]*b[3] + 1//2*b[1]*b[2]*b[3]
-  (3, 1, 1) => 1//4*a[1]*b[2]*b[3] + 1//4*a[2]*a[3]*b[1] + 1//2*b[1]*b[2]*b[3]
-  (4, 4, 2) => 1//4*a[1]*a[2]*b[3] + 1//4*a[3]*b[1]*b[2] + 1//2*b[1]*b[2]*b[3]
-  (1, 2, 3) => 1//4*a[1]*b[2]*b[3] + 1//4*a[2]*b[1]*b[3] + 1//4*a[3]*b[1]*b[2] …
-  (3, 1, 3) => 1//4*a[1]*a[3]*b[2] + 1//4*a[2]*b[1]*b[3] + 1//2*b[1]*b[2]*b[3]
-  (3, 2, 4) => 1//4*a[1]*b[2]*b[3] + 1//4*a[2]*b[1]*b[3] + 1//4*a[3]*b[1]*b[2] …
-  (3, 2, 1) => 1//4*a[1]*b[2]*b[3] + 1//4*a[2]*b[1]*b[3] + 1//4*a[3]*b[1]*b[2] …
-  (2, 1, 4) => 1//4*a[1]*b[2]*b[3] + 1//4*a[2]*b[1]*b[3] + 1//4*a[3]*b[1]*b[2] …
-  (3, 2, 3) => 1//4*a[1]*a[3]*b[2] + 1//4*a[2]*b[1]*b[3] + 1//2*b[1]*b[2]*b[3]
-  (2, 1, 1) => 1//4*a[1]*b[2]*b[3] + 1//4*a[2]*a[3]*b[1] + 1//2*b[1]*b[2]*b[3]
-  (1, 3, 2) => 1//4*a[1]*b[2]*b[3] + 1//4*a[2]*b[1]*b[3] + 1//4*a[3]*b[1]*b[2] …
-  (1, 4, 2) => 1//4*a[1]*b[2]*b[3] + 1//4*a[2]*b[1]*b[3] + 1//4*a[3]*b[1]*b[2] …
-  (2, 1, 3) => 1//4*a[1]*b[2]*b[3] + 1//4*a[2]*b[1]*b[3] + 1//4*a[3]*b[1]*b[2] …
-  (2, 2, 4) => 1//4*a[1]*a[2]*b[3] + 1//4*a[3]*b[1]*b[2] + 1//2*b[1]*b[2]*b[3]
-  (4, 3, 4) => 1//4*a[1]*a[3]*b[2] + 1//4*a[2]*b[1]*b[3] + 1//2*b[1]*b[2]*b[3]
-  (2, 2, 1) => 1//4*a[1]*a[2]*b[3] + 1//4*a[3]*b[1]*b[2] + 1//2*b[1]*b[2]*b[3]
-  (4, 4, 4) => 1//4*a[1]*a[2]*a[3] + 3//4*b[1]*b[2]*b[3]
-  (4, 3, 1) => 1//4*a[1]*b[2]*b[3] + 1//4*a[2]*b[1]*b[3] + 1//4*a[3]*b[1]*b[2] …
-  (3, 3, 2) => 1//4*a[1]*a[2]*b[3] + 1//4*a[3]*b[1]*b[2] + 1//2*b[1]*b[2]*b[3]
-  ⋮         => ⋮
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
fourier_mapMethod
fourier_map(pm::GroupBasedPhylogeneticModel)

Create a parametrization for a GroupBasedPhylogeneticModel of type Dictionary.

Iterate through all possible states of the leaf random variables and calculates their corresponding probabilities using group actions and laws of conditional independence. Return a dictionary of polynomials indexed by the states. Use auxiliary function monomial_fourier(pm::GroupBasedPhylogeneticModel, leaves_states::Vector{Int}) and fourier_parametrization(pm::GroupBasedPhylogeneticModel, leaves_states::Vector{Int}).

Examples

julia> pm = jukes_cantor_model(graph_from_edges(Directed,[[4,1],[4,2],[4,3]]));
-
-julia> q = fourier_map(pm)
-Dict{Tuple{Vararg{Int64}}, QQMPolyRingElem} with 64 entries:
-  (1, 2, 1) => 0
-  (3, 1, 1) => 0
-  (4, 4, 2) => 0
-  (1, 2, 3) => 0
-  (3, 1, 3) => x[2, 1]*x[1, 2]*x[3, 2]
-  (3, 2, 4) => x[1, 2]*x[2, 2]*x[3, 2]
-  (3, 2, 1) => 0
-  (2, 1, 4) => 0
-  (3, 2, 3) => 0
-  (2, 1, 1) => 0
-  (1, 3, 2) => 0
-  (1, 4, 2) => 0
-  (2, 1, 3) => 0
-  (2, 2, 4) => 0
-  (4, 3, 4) => 0
-  (2, 2, 1) => x[3, 1]*x[1, 2]*x[2, 2]
-  (4, 4, 4) => 0
-  (4, 3, 1) => 0
-  (3, 3, 2) => 0
-  ⋮         => ⋮
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
compute_equivalent_classesMethod
compute_equivalent_classes(parametrization::Dict{Tuple{Vararg{Int64}}, QQMPolyRingElem})

Given the parametrization of a PhylogeneticModel, cancel all duplicate entries and return equivalence classes of states which are attached the same probabilities.

Examples

julia> pm = jukes_cantor_model(graph_from_edges(Directed,[[4,1],[4,2],[4,3]]));
-
-julia> p = probability_map(pm);
-
-julia> q = fourier_map(pm);
-
-julia> p_equivclasses = compute_equivalent_classes(p);
-
-julia> p_equivclasses.parametrization
-Dict{Tuple{Vararg{Int64}}, QQMPolyRingElem} with 5 entries:
-  (1, 2, 1) => 1//4*a[1]*a[3]*b[2] + 1//4*a[2]*b[1]*b[3] + 1//2*b[1]*b[2]*b[3]
-  (1, 1, 1) => 1//4*a[1]*a[2]*a[3] + 3//4*b[1]*b[2]*b[3]
-  (1, 2, 2) => 1//4*a[1]*b[2]*b[3] + 1//4*a[2]*a[3]*b[1] + 1//2*b[1]*b[2]*b[3]
-  (1, 2, 3) => 1//4*a[1]*b[2]*b[3] + 1//4*a[2]*b[1]*b[3] + 1//4*a[3]*b[1]*b[2] …
-  (1, 1, 2) => 1//4*a[1]*a[2]*b[3] + 1//4*a[3]*b[1]*b[2] + 1//2*b[1]*b[2]*b[3]
-
-julia> p_equivclasses.classes
-Dict{Tuple{Vararg{Int64}}, Vector{Tuple{Vararg{Int64}}}} with 5 entries:
-  (1, 2, 1) => [(1, 2, 1), (1, 3, 1), (1, 4, 1), (2, 1, 2), (2, 3, 2), (2, 4, 2…
-  (1, 1, 1) => [(1, 1, 1), (2, 2, 2), (3, 3, 3), (4, 4, 4)]
-  (1, 2, 2) => [(1, 2, 2), (1, 3, 3), (1, 4, 4), (2, 1, 1), (2, 3, 3), (2, 4, 4…
-  (1, 2, 3) => [(1, 2, 3), (1, 2, 4), (1, 3, 2), (1, 3, 4), (1, 4, 2), (1, 4, 3…
-  (1, 1, 2) => [(1, 1, 2), (1, 1, 3), (1, 1, 4), (2, 2, 1), (2, 2, 3), (2, 2, 4…
-
-julia> q_equivclasses = compute_equivalent_classes(q);
-
-julia> q_equivclasses.parametrization
-Dict{Tuple{Vararg{Int64}}, QQMPolyRingElem} with 5 entries:
-  (1, 1, 1) => x[1, 1]*x[2, 1]*x[3, 1]
-  (2, 3, 4) => x[1, 2]*x[2, 2]*x[3, 2]
-  (2, 2, 1) => x[3, 1]*x[1, 2]*x[2, 2]
-  (1, 2, 2) => x[1, 1]*x[2, 2]*x[3, 2]
-  (2, 1, 2) => x[2, 1]*x[1, 2]*x[3, 2]
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
sum_equivalent_classesMethod
sum_equivalent_classes(equivalent_classes::NamedTuple{(:parametrization, :classes), Tuple{Dict{Tuple{Vararg{Int64}}, QQMPolyRingElem}, Dict{Tuple{Vararg{Int64}}, Vector{Tuple{Vararg{Int64}}}}}})

Take the output of the function compute_equivalent_classes for PhylogeneticModel and multiply by a factor to obtain probabilities as specified on the original small trees database.

Examples

julia> pm = jukes_cantor_model(graph_from_edges(Directed,[[4,1],[4,2],[4,3]]));
-
-julia> p = probability_map(pm);
-
-julia> p_equivclasses = compute_equivalent_classes(p);
-
-julia> sum_equivalent_classes(p_equivclasses)
-Dict{Tuple{Int64, Int64, Int64}, QQMPolyRingElem} with 5 entries:
-  (1, 2, 1) => 3*a[1]*a[3]*b[2] + 3*a[2]*b[1]*b[3] + 6*b[1]*b[2]*b[3]
-  (1, 1, 1) => a[1]*a[2]*a[3] + 3*b[1]*b[2]*b[3]
-  (1, 2, 2) => 3*a[1]*b[2]*b[3] + 3*a[2]*a[3]*b[1] + 6*b[1]*b[2]*b[3]
-  (1, 2, 3) => 6*a[1]*b[2]*b[3] + 6*a[2]*b[1]*b[3] + 6*a[3]*b[1]*b[2] + 6*b[1]*…
-  (1, 1, 2) => 3*a[1]*a[2]*b[3] + 3*a[3]*b[1]*b[2] + 6*b[1]*b[2]*b[3]
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
specialized_fourier_transformMethod
specialized_fourier_transform(pm::GroupBasedPhylogeneticModel, p_classes::Dict{Tuple{Vararg{Int64}}, Vector{Tuple{Vararg{Int64}}}}, q_classes::Dict{Tuple{Vararg{Int64}}, Vector{Tuple{Vararg{Int64}}}})

Reparametrize between a model specification in terms of probability and Fourier cooordinates. The input of equivalent classes is optional, if they are not entered they will be computed.

Examples

julia> pm = jukes_cantor_model(graph_from_edges(Directed,[[4,1],[4,2],[4,3]]));
-
-julia> p_equivclasses = compute_equivalent_classes(probability_map(pm));
-
-julia> q_equivclasses = compute_equivalent_classes(fourier_map(pm));
-
-julia> specialized_fourier_transform(pm, p_equivclasses.classes, q_equivclasses.classes)
-5×5 Matrix{QQMPolyRingElem}:
- 1  1      1      1      1
- 1  -1//3  -1//3  1      -1//3
- 1  -1//3  1      -1//3  -1//3
- 1  1      -1//3  -1//3  -1//3
- 1  -1//3  -1//3  -1//3  1//3
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
inverse_specialized_fourier_transformMethod
inverse_specialized_fourier_transform(pm::GroupBasedPhylogeneticModel, p_classes::Dict{Tuple{Vararg{Int64}}, Vector{Tuple{Vararg{Int64}}}}, q_classes::Dict{Tuple{Vararg{Int64}}, Vector{Tuple{Vararg{Int64}}}})

Reparametrize between a model specification in terms of Fourier and probability cooordinates.

Examples

julia> pm = jukes_cantor_model(graph_from_edges(Directed,[[4,1],[4,2],[4,3]]));
-
-julia> p_equivclasses = compute_equivalent_classes(probability_map(pm));
-
-julia> q_equivclasses = compute_equivalent_classes(fourier_map(pm));
-
-julia> inverse_specialized_fourier_transform(pm, p_equivclasses.classes, q_equivclasses.classes)
-5×5 Matrix{QQMPolyRingElem}:
- 1//16  3//16   3//16   3//16   3//8
- 3//16  -3//16  -3//16  9//16   -3//8
- 3//16  -3//16  9//16   -3//16  -3//8
- 3//16  9//16   -3//16  -3//16  -3//8
- 3//8   -3//8   -3//8   -3//8   3//4
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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/PR4245/Experimental/BasisLieHighestWeight/introduction/index.html b/previews/PR4245/Experimental/BasisLieHighestWeight/introduction/index.html deleted file mode 100644 index 3a8c2b859f55..000000000000 --- a/previews/PR4245/Experimental/BasisLieHighestWeight/introduction/index.html +++ /dev/null @@ -1,2 +0,0 @@ - -Introduction · Oscar.jl

Introduction

This subproject contains the code for the OSCAR book chapter by Ghislain Fourier and Xin Fang on the bases of highest weight modules.

Status

This part of OSCAR is in an experimental state; please see Adding new projects to experimental for what this means. More documentation is to come in the future.

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/PR4245/Experimental/BasisLieHighestWeight/user_functions/index.html b/previews/PR4245/Experimental/BasisLieHighestWeight/user_functions/index.html deleted file mode 100644 index 1a5c55e1e192..000000000000 --- a/previews/PR4245/Experimental/BasisLieHighestWeight/user_functions/index.html +++ /dev/null @@ -1,285 +0,0 @@ - -Functions for a monomial basis of highest weight modules · Oscar.jl

Functions for a monomial basis of highest weight modules

basis_lie_highest_weight_operatorsFunction
basis_lie_highest_weight_operators(type::Symbol, rank::Int)

Lists the operators available for a given simple Lie algebra of type type_rank, together with their index. Operators $f_\alpha$ of negative roots are shown as the coefficients of the corresponding positive root. w.r.t. the simple roots $\alpha_i$.

Example

julia> basis_lie_highest_weight_operators(:B, 2)
-4-element Vector{Tuple{Int64, Vector{QQFieldElem}}}:
- (1, [1, 0])
- (2, [0, 1])
- (3, [1, 1])
- (4, [1, 2])
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
basis_lie_highest_weightFunction
basis_lie_highest_weight(type::Symbol, rank::Int, highest_weight::Vector{Int}; monomial_ordering::Symbol=:degrevlex)
-basis_lie_highest_weight(type::Symbol, rank::Int, highest_weight::Vector{Int}, birational_sequence::Vector{Int}; monomial_ordering::Symbol=:degrevlex)
-basis_lie_highest_weight(type::Symbol, rank::Int, highest_weight::Vector{Int}, birational_sequence::Vector{Vector{Int}}; monomial_ordering::Symbol=:degrevlex)

Computes a monomial basis for the highest weight module with highest weight highest_weight (in terms of the fundamental weights $\omega_i$), for a simple Lie algebra of type type_rank.

If no birational sequence is specified, all operators in the order of basis_lie_highest_weight_operators are used. A birational sequence of type Vector{Int} is a sequence of indices of operators in basis_lie_highest_weight_operators. A birational sequence of type Vector{Vector{Int}} is a sequence of weights in terms of the simple roots $\alpha_i$.

monomial_ordering describes the monomial ordering used for the basis. If this is a weighted ordering, the height of the corresponding root is used as weight.

Examples

julia> base = basis_lie_highest_weight(:A, 2, [1, 1])
-Monomial basis of a highest weight module
-  of highest weight [1, 1]
-  of dimension 8
-  with monomial ordering degrevlex([x1, x2, x3])
-over Lie algebra of type A2
-  where the used birational sequence consists of the following roots (given as coefficients w.r.t. alpha_i):
-    [1, 0]
-    [0, 1]
-    [1, 1]
-  and the basis was generated by Minkowski sums of the bases of the following highest weight modules:
-    [1, 0]
-    [0, 1]
-
-julia> base = basis_lie_highest_weight(:A, 3, [2, 2, 3]; monomial_ordering = :lex)
-Monomial basis of a highest weight module
-  of highest weight [2, 2, 3]
-  of dimension 1260
-  with monomial ordering lex([x1, x2, x3, x4, x5, x6])
-over Lie algebra of type A3
-  where the used birational sequence consists of the following roots (given as coefficients w.r.t. alpha_i):
-    [1, 0, 0]
-    [0, 1, 0]
-    [0, 0, 1]
-    [1, 1, 0]
-    [0, 1, 1]
-    [1, 1, 1]
-  and the basis was generated by Minkowski sums of the bases of the following highest weight modules:
-    [1, 0, 0]
-    [0, 1, 0]
-    [0, 0, 1]
-
-julia> base = basis_lie_highest_weight(:A, 2, [1, 0], [1,2,1])
-Monomial basis of a highest weight module
-  of highest weight [1, 0]
-  of dimension 3
-  with monomial ordering degrevlex([x1, x2, x3])
-over Lie algebra of type A2
-  where the used birational sequence consists of the following roots (given as coefficients w.r.t. alpha_i):
-    [1, 0]
-    [0, 1]
-    [1, 0]
-  and the basis was generated by Minkowski sums of the bases of the following highest weight modules:
-    [1, 0]
-
-julia> base = basis_lie_highest_weight(:A, 2, [1, 0], [[1,0], [0,1], [1,0]])
-Monomial basis of a highest weight module
-  of highest weight [1, 0]
-  of dimension 3
-  with monomial ordering degrevlex([x1, x2, x3])
-over Lie algebra of type A2
-  where the used birational sequence consists of the following roots (given as coefficients w.r.t. alpha_i):
-    [1, 0]
-    [0, 1]
-    [1, 0]
-  and the basis was generated by Minkowski sums of the bases of the following highest weight modules:
-    [1, 0]
-
-julia> base = basis_lie_highest_weight(:C, 3, [1, 1, 1]; monomial_ordering = :lex)
-Monomial basis of a highest weight module
-  of highest weight [1, 1, 1]
-  of dimension 512
-  with monomial ordering lex([x1, x2, x3, x4, x5, x6, x7, x8, x9])
-over Lie algebra of type C3
-  where the used birational sequence consists of the following roots (given as coefficients w.r.t. alpha_i):
-    [1, 0, 0]
-    [0, 1, 0]
-    [0, 0, 1]
-    [1, 1, 0]
-    [0, 1, 1]
-    [1, 1, 1]
-    [0, 2, 1]
-    [1, 2, 1]
-    [2, 2, 1]
-  and the basis was generated by Minkowski sums of the bases of the following highest weight modules:
-    [1, 0, 0]
-    [0, 1, 0]
-    [0, 0, 1]
-    [0, 1, 1]
-    [1, 1, 1]
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
basis_lie_highest_weight_fflFunction
basis_lie_highest_weight_ffl(type::Symbol, rank::Int, highest_weight::Vector{Int})

Computes a monomial basis for the highest weight module with highest weight highest_weight (in terms of the fundamental weights $\omega_i$), for a simple Lie algebra $L$ of type type_rank.

Then the birational sequence used consists of all operators in descening height of the corresponding root.

The monomial ordering is fixed to degrevlex.

Examples

julia> basis_lie_highest_weight_ffl(:A, 3, [1,1,1])
-Monomial basis of a highest weight module
-  of highest weight [1, 1, 1]
-  of dimension 64
-  with monomial ordering degrevlex([x1, x2, x3, x4, x5, x6])
-over Lie algebra of type A3
-  where the used birational sequence consists of the following roots (given as coefficients w.r.t. alpha_i):
-    [1, 1, 1]
-    [0, 1, 1]
-    [1, 1, 0]
-    [0, 0, 1]
-    [0, 1, 0]
-    [1, 0, 0]
-  and the basis was generated by Minkowski sums of the bases of the following highest weight modules:
-    [1, 0, 0]
-    [0, 1, 0]
-    [0, 0, 1]
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
basis_lie_highest_weight_lusztigFunction
basis_lie_highest_weight_lusztig(type::Symbol, rank::Int, highest_weight::Vector{Int}, reduced_expression::Vector{Int})

Computes a monomial basis for the highest weight module with highest weight highest_weight (in terms of the fundamental weights $\omega_i$), for a simple Lie algebra $L$ of type type_rank.

Let $\omega_0 = s_{i_1} \cdots s_{i_N}$ be a reduced expression of the longest element in the Weyl group of $L$ given as indices $[i_1, \dots, i_N]$ in reduced_expression. Then the birational sequence used consists of $\beta_1, \dots, \beta_N$ where $\beta_1 := \alpha_{i_1}$ and \betak := s{i1} \cdots s{i{k-1}} \alpha{i_k}$ for $k = 2, \dots, N$.

The monomial ordering is fixed to wdegrevlex (weighted degree reverse lexicographic order).

Examples

julia> base = basis_lie_highest_weight_lusztig(:D, 4, [1,1,1,1], [4,3,2,4,3,2,1,2,4,3,2,1])
-Monomial basis of a highest weight module
-  of highest weight [1, 1, 1, 1]
-  of dimension 4096
-  with monomial ordering wdegrevlex([x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12], [1, 1, 3, 2, 2, 1, 5, 4, 3, 3, 2, 1])
-over Lie algebra of type D4
-  where the used birational sequence consists of the following roots (given as coefficients w.r.t. alpha_i):
-    [0, 0, 0, 1]
-    [0, 0, 1, 0]
-    [0, 1, 1, 1]
-    [0, 1, 1, 0]
-    [0, 1, 0, 1]
-    [0, 1, 0, 0]
-    [1, 2, 1, 1]
-    [1, 1, 1, 1]
-    [1, 1, 0, 1]
-    [1, 1, 1, 0]
-    [1, 1, 0, 0]
-    [1, 0, 0, 0]
-  and the basis was generated by Minkowski sums of the bases of the following highest weight modules:
-    [1, 0, 0, 0]
-    [0, 1, 0, 0]
-    [0, 0, 1, 0]
-    [0, 0, 0, 1]
-    [0, 0, 1, 1]
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
basis_lie_highest_weight_nzFunction
basis_lie_highest_weight_nz(type::Symbol, rank::Int, highest_weight::Vector{Int}, reduced_expression::Vector{Int})

Computes a monomial basis for the highest weight module with highest weight highest_weight (in terms of the fundamental weights $\omega_i$), for a simple Lie algebra $L$ of type type_rank.

Let $\omega_0 = s_{i_1} \cdots s_{i_N}$ be a reduced expression of the longest element in the Weyl group of $L$ given as indices $[i_1, \dots, i_N]$ in reduced_expression. Then the birational sequence used consists of $\alpha_{i_1}, \dots, \alpha_{i_N}$.

The monomial ordering is fixed to degrevlex (degree reverse lexicographic order).

Examples

julia> basis_lie_highest_weight_nz(:C, 3, [1,1,1], [3,2,3,2,1,2,3,2,1])
-Monomial basis of a highest weight module
-  of highest weight [1, 1, 1]
-  of dimension 512
-  with monomial ordering degrevlex([x1, x2, x3, x4, x5, x6, x7, x8, x9])
-over Lie algebra of type C3
-  where the used birational sequence consists of the following roots (given as coefficients w.r.t. alpha_i):
-    [0, 0, 1]
-    [0, 1, 0]
-    [0, 0, 1]
-    [0, 1, 0]
-    [1, 0, 0]
-    [0, 1, 0]
-    [0, 0, 1]
-    [0, 1, 0]
-    [1, 0, 0]
-  and the basis was generated by Minkowski sums of the bases of the following highest weight modules:
-    [1, 0, 0]
-    [0, 1, 0]
-    [0, 0, 1]
-
-julia> basis_lie_highest_weight_nz(:A, 4, [1,1,1,1], [4,3,2,1,2,3,4,3,2,3])
-Monomial basis of a highest weight module
-  of highest weight [1, 1, 1, 1]
-  of dimension 1024
-  with monomial ordering degrevlex([x1, x2, x3, x4, x5, x6, x7, x8, x9, x10])
-over Lie algebra of type A4
-  where the used birational sequence consists of the following roots (given as coefficients w.r.t. alpha_i):
-    [0, 0, 0, 1]
-    [0, 0, 1, 0]
-    [0, 1, 0, 0]
-    [1, 0, 0, 0]
-    [0, 1, 0, 0]
-    [0, 0, 1, 0]
-    [0, 0, 0, 1]
-    [0, 0, 1, 0]
-    [0, 1, 0, 0]
-    [0, 0, 1, 0]
-  and the basis was generated by Minkowski sums of the bases of the following highest weight modules:
-    [1, 0, 0, 0]
-    [0, 1, 0, 0]
-    [0, 0, 1, 0]
-    [0, 0, 0, 1]
-    [0, 1, 0, 1] 
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
basis_lie_highest_weight_stringFunction
basis_lie_highest_weight_string(type::Symbol, rank::Int, highest_weight::Vector{Int}, reduced_expression::Vector{Int})

Computes a monomial basis for the highest weight module with highest weight highest_weight (in terms of the fundamental weights $\omega_i$), for a simple Lie algebra $L$ of type type_rank.

Let $\omega_0 = s_{i_1} \cdots s_{i_N}$ be a reduced expression of the longest element in the Weyl group of $L$ given as indices $[i_1, \dots, i_N]$ in reduced_expression. Then the birational sequence used consists of $\alpha_{i_1}, \dots, \alpha_{i_N}$.

The monomial ordering is fixed to neglex (negative lexicographic order).

Examples

julia> basis_lie_highest_weight_string(:B, 3, [1,1,1], [3,2,3,2,1,2,3,2,1])
-Monomial basis of a highest weight module
-  of highest weight [1, 1, 1]
-  of dimension 512
-  with monomial ordering neglex([x1, x2, x3, x4, x5, x6, x7, x8, x9])
-over Lie algebra of type B3
-  where the used birational sequence consists of the following roots (given as coefficients w.r.t. alpha_i):
-    [0, 0, 1]
-    [0, 1, 0]
-    [0, 0, 1]
-    [0, 1, 0]
-    [1, 0, 0]
-    [0, 1, 0]
-    [0, 0, 1]
-    [0, 1, 0]
-    [1, 0, 0]
-  and the basis was generated by Minkowski sums of the bases of the following highest weight modules:
-    [1, 0, 0]
-    [0, 1, 0]
-    [0, 0, 1]
-
-julia> basis_lie_highest_weight_string(:A, 4, [1,1,1,1], [4,3,2,1,2,3,4,3,2,3])
-Monomial basis of a highest weight module
-  of highest weight [1, 1, 1, 1]
-  of dimension 1024
-  with monomial ordering neglex([x1, x2, x3, x4, x5, x6, x7, x8, x9, x10])
-over Lie algebra of type A4
-  where the used birational sequence consists of the following roots (given as coefficients w.r.t. alpha_i):
-    [0, 0, 0, 1]
-    [0, 0, 1, 0]
-    [0, 1, 0, 0]
-    [1, 0, 0, 0]
-    [0, 1, 0, 0]
-    [0, 0, 1, 0]
-    [0, 0, 0, 1]
-    [0, 0, 1, 0]
-    [0, 1, 0, 0]
-    [0, 0, 1, 0]
-  and the basis was generated by Minkowski sums of the bases of the following highest weight modules:
-    [1, 0, 0, 0]
-    [0, 1, 0, 0]
-    [0, 0, 1, 0]
-    [0, 0, 0, 1]
-    [0, 1, 0, 1]
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source

Functions for Kodaira embeddings

basis_coordinate_ring_kodairaFunction
basis_coordinate_ring_kodaira(type::Symbol, rank::Int, highest_weight::Vector{Int}, degree::Int; monomial_ordering::Symbol=:degrevlex)
-basis_coordinate_ring_kodaira(type::Symbol, rank::Int, highest_weight::Vector{Int}, degree::Int, birational_sequence::Vector{Int}; monomial_ordering::Symbol=:degrevlex)
-basis_coordinate_ring_kodaira(type::Symbol, rank::Int, highest_weight::Vector{Int}, degree::Int, birational_sequence::Vector{Vector{Int}}; monomial_ordering::Symbol=:degrevlex)

Compute monomial bases for the degree-truncated coordinate ring (for all degrees up to degree) of the Kodaira embedding of the generalized flag variety into the projective space of the highest weight module with highest weight highest_weight for a simple Lie algebra $L$ of type type and rank rank. Furthermore, for each degree, return the monomials that are not contained in the Minkowski sum of the bases of the lower degrees.

Warn

Currently, this function expects $-w_0(\lambda)$ instead of $\lambda$ as the highest_weight input. This might change in a minor release.

If no birational sequence is specified, all operators in the order of basis_lie_highest_weight_operators are used. A birational sequence of type Vector{Int} is a sequence of indices of operators in basis_lie_highest_weight_operators. A birational sequence of type Vector{Vector{Int}} is a sequence of weights in terms of the simple roots $\alpha_i$.

monomial_ordering describes the monomial ordering used for the basis. If this is a weighted ordering, the height of the corresponding root is used as weight.

Example

julia> bases = basis_coordinate_ring_kodaira(:G, 2, [1,0], 6; monomial_ordering = :invlex)
-6-element Vector{Tuple{MonomialBasis, Vector{ZZMPolyRingElem}}}:
- (Monomial basis of a highest weight module with highest weight [1, 0] over Lie algebra of type G2, [1, x1, x3, x1*x3, x1^2*x3, x3*x4, x1*x3*x4])
- (Monomial basis of a highest weight module with highest weight [2, 0] over Lie algebra of type G2, [x4, x1*x4, x4^2, x3*x4^2, x1*x3*x4^2])
- (Monomial basis of a highest weight module with highest weight [3, 0] over Lie algebra of type G2, [x1^2*x4^2, x4^3, x1*x4^3, x4^4, x1*x4^4, x3*x4^4, x5, x2*x5, x1*x2*x5, x1^2*x2*x5, x3^2*x5, x1*x3^2*x5, x3^3*x5, x1*x3^3*x5])
- (Monomial basis of a highest weight module with highest weight [4, 0] over Lie algebra of type G2, [x4^5, x1*x4^5, x4^6, x3^2*x4*x5, x1*x3^2*x4*x5, x3^2*x4^2*x5, x3^3*x4^2*x5])
- (Monomial basis of a highest weight module with highest weight [5, 0] over Lie algebra of type G2, [x1^2*x4^6, x4^7, x1*x4^7, x2*x4^3*x5, x1*x2*x4^3*x5, x2*x3*x4^3*x5, x1*x2*x3*x4^3*x5, x1^2*x2*x3*x4^3*x5, x2*x3^2*x4^3*x5, x1*x2*x3^2*x4^3*x5, x1^2*x2*x3^2*x4^3*x5, x2*x4^4*x5])
- (Monomial basis of a highest weight module with highest weight [6, 0] over Lie algebra of type G2, [x4^9, x1*x3*x4^4*x5, x2*x4^5*x5, x3*x4^5*x5, x3^2*x4^5*x5, x2*x3^2*x4^5*x5, x1*x2*x3^2*x4^5*x5, x3^4*x4*x5^2])
-
-julia> [length(basis[2]) for basis in bases]
-6-element Vector{Int64}:
-  7
-  5
- 14
-  7
- 12
-  8
-
-julia> bases[end][1]
-Monomial basis of a highest weight module
-  of highest weight [6, 0]
-  of dimension 714
-  with monomial ordering invlex([x1, x2, x3, x4, x5, x6])
-over Lie algebra of type G2
-  where the used birational sequence consists of the following roots (given as coefficients w.r.t. alpha_i):
-    [1, 0]
-    [0, 1]
-    [1, 1]
-    [2, 1]
-    [3, 1]
-    [3, 2]
-  and the basis was generated by Minkowski sums of the bases of the following highest weight modules:
-    [1, 0]
-    [2, 0]
-    [3, 0]
-    [4, 0]
-    [5, 0]
-    [6, 0]
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
basis_coordinate_ring_kodaira_fflFunction
basis_coordinate_ring_kodaira_ffl(type::Symbol, rank::Int, highest_weight::Vector{Int}, degree::Int; monomial_ordering::Symbol=:degrevlex)

Compute monomial bases for the degree-truncated coordinate ring (for all degrees up to degree) of the Kodaira embedding of the generalized flag variety into the projective space of the highest weight module with highest weight highest_weight for a simple Lie algebra $L$ of type type and rank rank. Furthermore, for each degree, return the monomials that are not contained in the Minkowski sum of the bases of the lower degrees.

Warn

Currently, this function expects $-w_0(\lambda)$ instead of $\lambda$ as the highest_weight input. This might change in a minor release.

The the birational sequence used consists of all operators in descening height of the corresponding root, i.e. a "good" ordering.

The monomial ordering is fixed to degrevlex.

Example

julia> bases = basis_coordinate_ring_kodaira_ffl(:G, 2, [1,0], 6)
-6-element Vector{Tuple{MonomialBasis, Vector{ZZMPolyRingElem}}}:
- (Monomial basis of a highest weight module with highest weight [1, 0] over Lie algebra of type G2, [1, x6, x4, x3, x2, x1, x1*x6])
- (Monomial basis of a highest weight module with highest weight [2, 0] over Lie algebra of type G2, [])
- (Monomial basis of a highest weight module with highest weight [3, 0] over Lie algebra of type G2, [])
- (Monomial basis of a highest weight module with highest weight [4, 0] over Lie algebra of type G2, [])
- (Monomial basis of a highest weight module with highest weight [5, 0] over Lie algebra of type G2, [])
- (Monomial basis of a highest weight module with highest weight [6, 0] over Lie algebra of type G2, [])
-
-julia> [length(basis[2]) for basis in bases]
-6-element Vector{Int64}:
- 7
- 0
- 0
- 0
- 0
- 0
-
-julia> bases[end][1]
-Monomial basis of a highest weight module
-  of highest weight [6, 0]
-  of dimension 714
-  with monomial ordering degrevlex([x1, x2, x3, x4, x5, x6])
-over Lie algebra of type G2
-  where the used birational sequence consists of the following roots (given as coefficients w.r.t. alpha_i):
-    [3, 2]
-    [3, 1]
-    [2, 1]
-    [1, 1]
-    [0, 1]
-    [1, 0]
-  and the basis was generated by Minkowski sums of the bases of the following highest weight modules:
-    [1, 0]
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
diff --git a/previews/PR4245/Experimental/DoubleAndHyperComplexes/advice_for_the_programmer/index.html b/previews/PR4245/Experimental/DoubleAndHyperComplexes/advice_for_the_programmer/index.html deleted file mode 100644 index 3b1380207c4a..000000000000 --- a/previews/PR4245/Experimental/DoubleAndHyperComplexes/advice_for_the_programmer/index.html +++ /dev/null @@ -1,58 +0,0 @@ - -Advice for the programmer · Oscar.jl

Advice for the programmer

How to implement my custom double complex?

The implementation for Double complexes is generically lazy. We provide a concrete type which takes care of handling the user's requests to entries and morphisms and their caching: DoubleComplexOfMorphisms.

In order to work properly, any DoubleComplexOfMorphisms D needs to be able to produce entries D[i, j] for legitimate indices (i, j) and the morphisms between these on request. To this end, the internal constructor of DoubleComplexOfMorphisms requires the programmer to pass on certain "factories". For the production of the entries D[i, j], these must be concrete instances of

    abstract type ChainFactory{ChainType} end

For this type the call syntax must be overwritten as follows:

    function (fac::ChainFactory{ChainType})(D::AbsDoubleComplexOfMorphisms, i::Int, j::Int)::ChainType where {ChainType}

This will be called by the internals of DoubleComplex whenever production of the (i, j)-th entry is requested. The first argument will then always be the concrete double complex D itself, so that the factory has access to all information that has already been computed when trying to compute the entry for (i, j). Beware not to produce infinite feedback loops when implementing this!

Moreover, any factory is supposed to be able to communicate whether or not a specific entry is computable. To this end one also needs to overwrite

    function can_compute(fac::ChainFactory{ChainType}, D::AbsDoubleComplexOfMorphisms, i::Int, j::Int)::Bool where {ChainType}

Let's see this in an example. Suppose we want to implement the "zero double complex of modules" over a multivariate polynomial ring R, i.e. the unbounded double complex which consists entirely of zero modules and the trivial homomorphisms between them. Then the factory would be

mutable struct ZeroModuleFactory{ChainType} <: ChainFactory{ChainType}
-  R::MPolyRing
-  
-  function ZeroModuleFactory(R::MPolyRing)
-    return new{ModuleFP{elem_type(R)}}(R)
-  end
-end
-
-function (fac::ZeroModuleFactory)(D::AbsDoubleComplexOfMorphisms, i::Int, j::Int)
-  return FreeMod(fac.R, 0)
-end
-
-function can_compute(fac::ZeroModuleFactory, D::AbsDoubleComplexOfMorphisms, i::Int, j::Int)
-  return true
-end

The horizontal and vertical morphisms also need their factories. Similar to the above, these need to be concrete instances of

    abstract type ChainMorphismFactory{MorphismType} end

and the programmer must overwrite the functions

    function (fac::ChainMorphismFactory{MorphismType})(dc::AbsDoubleComplexOfMorphisms, i::Int, j::Int)::MorphismType where {MorphismType}
-    function can_compute(fac::ChainMorphismFactory{MorphismType}, dc::AbsDoubleComplexOfMorphisms, i::Int, j::Int)::Bool where {MorphismType}

In the above example we would implement

mutable struct VerticalZeroMaps{MorphismType} <: ChainMorphismFactory{MorphismType}
-  R::MPolyRing
-
-  function VerticalZeroMaps(R::MPolyRing)
-    return new{ModuleFPHom}(R)
-  end
-end
-
-mutable struct HorizontalZeroMaps{MorphismType} <: ChainMorphismFactory{MorphismType}
-  R::MPolyRing
-
-  function HorizontalZeroMaps(R::MPolyRing)
-    return new{ModuleFPHom}(R)
-  end
-end

Then we would overwrite the call syntax as follows.

function (fac::VerticalZeroMaps)(D::AbsDoubleComplexOfMorphisms, i::Int, j::Int)
-   dom = D[i, j]
-   inc = (vertical_direction(D) == :chain ? -1 : 1)
-   cod = D[i, j + inc]
-   return hom(dom, cod, elem_type(cod)[])
-end
-
-function (fac::HorizontalZeroMaps)(D::AbsDoubleComplexOfMorphisms, i::Int, j::Int)
-   dom = D[i, j]
-   inc = (horizontal_direction(D) == :chain ? -1 : 1)
-   cod = D[i + inc, j]
-   return hom(dom, cod, elem_type(cod)[])
-end
-  
-function can_compute(fac::HorizontalZeroMaps, D::AbsDoubleComplexOfMorphisms, i::Int, j::Int)
-  return true
-end
-
-function can_compute(fac::VerticalZeroMaps, D::AbsDoubleComplexOfMorphisms, i::Int, j::Int)
-  return true
-end

In order to finally create our zero double complex we implement the constructor as follows.

function zero_double_complex(R::MPolyRing)
-  entry_fac = ZeroModuleFactory(R)
-  vert_map_fac = VerticalZeroMaps(R)
-  horz_map_fac = HorizontalZeroMaps(R)
-  
-  result = DoubleComplexOfMorphisms(entry_fac, horz_map_fac, vert_map_fac, horizontal_direction=:chain, vertical_direction=:chain)
-  return result
-end

Note that any concrete complex Z created by zero_double_complex is unbounded in every direction. In particular, has_upper_bound(Z) etc. will return false and upper_bound(Z) will throw an error. At the same time can_compute_index(Z, i, j) will always return true and calling Z[i, j] will produce a reasonable and cached result. See the source code of the internal constructor of DoubleComplexOfMorphisms for how to alter these settings.

Another example for an implementation of a double complex can be found in experimental/DoubleComplexes/test/double_complex_interface.jl. There we write an implementation to turn a bounded simple ComplexOfMorphisms for modules over polynomial rings C into a bounded DoubleComplexOfMorphisms D which knows how to extend itself with zeroes to the left and to the right, but is concentrated in the zeroeth row.

How to make use of the generic functionality?

For double complexes we have some generic functionality available, e.g. total_complex(D::AbsDoubleComplexOfMorphisms{ChainType, MorphismType}). Such generic functionality assumes certain methods to be implemented for the ChainType and the MorphismType of the double complex D. For instance, it must be possible to compose two morphisms of type <:MorphismType and get a new object of type <:MorphismType. Sometimes, the required functionality is not streamlined throughout OSCAR (and there is little hope to achieve this). One example for this are direct sums: For finitely generated modules, the function takes a special keyword argument task to indicate whether the inclusion and projection maps should also be returned, while for TorQuadModules, this keyword argument is not even available. To potentially accomodate all these different types in our double complexes, the generic code uses an internal method

    _direct_sum(u::Vector{T}) where {T}

to make sure that the output has the correct format (s, inc, pr) consisting of the direct sum s itself, together with the vectors of inclusion- and projection maps inc and pr.

If any generic functionality, such as forming a total complex, does not work for your custom implementation of a double complex, check whether this might be due to a missing implementation of this method or others.

diff --git a/previews/PR4245/Experimental/DoubleAndHyperComplexes/user_interface/index.html b/previews/PR4245/Experimental/DoubleAndHyperComplexes/user_interface/index.html deleted file mode 100644 index b1d70e9f6422..000000000000 --- a/previews/PR4245/Experimental/DoubleAndHyperComplexes/user_interface/index.html +++ /dev/null @@ -1,16 +0,0 @@ - -Double complexes – the user's interface · Oscar.jl

Double complexes – the user's interface

We briefly review the mathematical notion of a double complex. Let $\mathcal A$ be an Abelian category. A double complex $D_{\bullet, \bullet}$ consists of a collection of objects $D_{i, j}$ in $\mathcal A$ with indices $(i, j) \in \mathbb Z^2$ and usually arranged in a matrix-like grid, together with two collections of morphisms $D_{i, j} \to D_{i \pm 1, j}$, the horizontal morphisms, and $D_{i, j} \to D_{i, j \pm 1}$, the vertical morphisms, so that both the rows and the columns of $D_{\bullet, \bullet}$ are complexes in the classical sense and such that all resulting squares of maps commute.

In practice one usually encounters complexes which are bounded in the sense that outside some specified area of indices $(i, j) \in \mathbb Z^2$ the entries $D_{i, j}$ are all zero. Such entries are then usually omitted.

Basic getters and attributes

In OSCAR the generic functionality for double complexes is declared for the abstract type AbsDoubleComplexOfMorphisms. These functions comprise

  getindex(D::AbsDoubleComplexOfMorphisms, i::Int, j::Int) # Get the `(i,j)`-th entry of `D`
horizontal_mapMethod
horizontal_map(dc::AbsDoubleComplexOfMorphisms, i::Int, j::Int)

Return the morphism $dc[i, j] → dc[i ± 1, j]$ (the sign depending on the horizontal_direction of dc).

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
vertical_mapMethod
vertical_map(dc::AbsDoubleComplexOfMorphisms, i::Int, j::Int)

Return the morphism $dc[i, j] → dc[i, j ± 1]$ (the sign depending on the vertical_direction of dc).

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source

In which direction the maps in the rows and columns go can be asked with the following methods:

horizontal_directionMethod
horizontal_direction(dc::AbsDoubleComplexOfMorphisms)

Return a symbol :chain or :cochain depending on whether the morphisms of the rows of dc decrease or increase the (co-)homological index.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
vertical_directionMethod
vertical_direction(dc::AbsDoubleComplexOfMorphisms)

Return a symbol :chain or :cochain depending on whether the morphisms of the columns of dc decrease or increase the (co-)homological index.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source

Double complexes can be bounded or unbounded. It is important to note that even if such bounds exist and are known, this is a priori not related to whether or not certain entries are computable! I.e. even in the case of a bounded complex dc it might still be valid to call dc[i, j] beyond that bound. In general, one should use the following functions to determine whether or not it is legitimate to ask for a specific entry.

has_indexMethod
has_index(D::AbsDoubleComplexOfMorphisms, i::Int, j::Int)

Return true if the (i, j)-th entry of D is already known, false otherwise.

If the result is false, then it might nevertheless still be possible to compute D[i, j]; use can_compute_index for such queries.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
can_compute_indexMethod
can_compute_index(D::AbsDoubleComplexOfMorphisms, i::Int, j::Int)

Return true if the entry D[i, j] is known or D knows how to compute it.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
has_horizontal_mapMethod
has_horizontal_map(dc::AbsDoubleComplexOfMorphisms, i::Int, j::Int)

Checks whether the double complex dc has the horizontal morphism dc[i, j] → dc[i ± 1, j], the sign depending on the horizontal_direction of dc.

If this returns false this might just mean that the map has not been computed, yet. Use can_compute_horizontal_map to learn whether or not this is possible.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
can_compute_horizontal_mapMethod
can_compute_horizontal_map(dc::AbsDoubleComplexOfMorphisms, i::Int, j::Int)

Return true if dc can compute the horizontal morphism dc[i, j] → dc[i ± 1, j], the sign depending on the horizontal_direction of dc, and false otherwise.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
has_vertical_mapMethod
has_vertical_map(dc::AbsDoubleComplexOfMorphisms, i::Int, j::Int)

Checks whether the double complex dc has the vertical morphism dc[i, j] → dc[i, j ± 1], the sign depending on the vertical_direction of dc.

If this returns false this might just mean that the map has not been computed, yet. Use can_compute_vertical_map to learn whether or not this is possible.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
can_compute_vertical_mapMethod
can_compute_vertical_map(dc::AbsDoubleComplexOfMorphisms, i::Int, j::Int)

Return true if dc can compute the vertical morphism dc[i, j] → dc[i, j ± 1], the sign depending on the vertical_direction of dc, and false otherwise.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source

Explicitly known bounds for the non-zero entries of a complex are nevertheless relevant for various generic functionalities. For example, computing a total complex is only possible in practice if one has an a priori estimate where the non-zero entries are located. For such purposes, we provide the following functionality:

has_upper_boundMethod
has_upper_bound(D::AbsDoubleComplexOfMorphisms)

Return true if a universal upper bound $j ≤ B$ for non-zero D[i, j] is known; false otherwise.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
has_lower_boundMethod
has_lower_bound(D::AbsDoubleComplexOfMorphisms)

Return true if a universal upper bound $B ≤ j$ for non-zero D[i, j] is known; false otherwise.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
has_right_boundMethod
has_right_bound(D::AbsDoubleComplexOfMorphisms)

Return true if a universal upper bound $i ≤ B$ for non-zero D[i, j] is known; false otherwise.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
has_left_boundMethod
has_left_bound(D::AbsDoubleComplexOfMorphisms)

Return true if a universal upper bound $B ≤ i$ for non-zero D[i, j] is known; false otherwise.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source

If they exist, these bounds can be asked for using

right_boundMethod
right_bound(D::AbsDoubleComplexOfMorphisms)

Return a bound $B$ such that D[i, j] can be assumed to be zero for $i > B$. Whether or not requests for D[i, j] beyond that bound are legitimate can be checked using can_compute_index.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
left_boundMethod
left_bound(D::AbsDoubleComplexOfMorphisms)

Return a bound $B$ such that D[i, j] can be assumed to be zero for $i < B$. Whether or not requests for D[i, j] beyond that bound are legitimate can be checked using can_compute_index.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
upper_boundMethod
upper_bound(D::AbsDoubleComplexOfMorphisms)

Return a bound $B$ such that D[i, j] can be assumed to be zero for $j > B$. Whether or not requests for D[i, j] beyond that bound are legitimate can be checked using can_compute_index.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
lower_boundMethod
lower_bound(D::AbsDoubleComplexOfMorphisms)

Return a bound $B$ such that D[i, j] can be assumed to be zero for $j < B$. Whether or not requests for D[i, j] beyond that bound are legitimate can be checked using can_compute_index.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source

It is also possible to query whether or not a double complex is already complete in the sense that it knows about all of its non-zero entries.

is_completeMethod
is_complete(dc::AbsDoubleComplexOfMorphisms)

Return true if for all indices (i, j) with has_index(dc, i, j) = true and dc[i, j] non-zero, the vertex (i, j) is lying on an "island" of non-zero entries in the grid of the double complex, which is bounded by either zero entries or entries for indices (i', j') where can_compute_index(dc, i', j') = false. At least one index dc[i, j] must be known for this to return true.

    ⋮   ⋮   ⋮   ⋮   ⋮   ⋮   ⋮   ⋮   ⋮   ⋮   ⋮   ⋮   ⋮   ⋮   ⋮   ⋮   
-    ↑   ↑   ↑   ↑   ↑   ↑   ↑   ↑   ↑   ↑   ↑   ↑   ↑   ↑   ↑   ↑   
-… → ? → ? → ? → ? → ? → ? → ? → ? → ? → ? → ? → 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 → 0 → 0 → 0 → * → * → 0 → 0 → - → - → …
-    ↑   ↑   ↑   ↑   ↑   ↑   ↑   ↑   ↑   ↑   ↑   ↑   ↑   ↑   ↑   ↑   
-… → ? → 0 → 0 → 0 → ? → ? → ? → ? → ? → ? → 0 → 0 → ? → ? → - → - → …
-    ↑   ↑   ↑   ↑   ↑   ↑   ↑   ↑   ↑   ↑   ↑   ↑   ↑   ↑   ↑   ↑   
-    ⋮   ⋮   ⋮   ⋮   ⋮   ⋮   ⋮   ⋮   ⋮   ⋮   ⋮   ⋮   ⋮   ⋮   ⋮   ⋮

Example of a pattern of a double complex with is_complete = true. 0 : zero entry - : entry can not be computed (can_compute_index returns false) * : non-zero entry which has been computed ? : entry can be computed, but that has not yet been done

!!! note If the double complex has several of the above "islands", then is_complete might return true even though one or more of the "islands" have not yet been uncovered. Use this carefully if your full double complex might be separated by zero entries!

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source

Generic functionality

total_complexMethod
total_complex(D::AbsDoubleComplexOfMorphisms)

Construct the total complex of the double complex D.

Note that D needs to be reasonably bounded for this to work so that the strands $⨁ ᵢ₊ⱼ₌ₖ Dᵢⱼ$ are finite for every k. Moreover, the generic code uses the internal function _direct_sum. See the docstring of that function to learn more.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source

Constructors

tensor_productMethod
tensor_product(C::ComplexOfMorphisms{ChainType}, D::ComplexOfMorphisms{ChainType}) where {ChainType}

Create the tensor product of two complexes C and D as a double complex.

In order for the generic implementation to work for your specific ChainType the following needs to be implemented.

  • morphism_type(ChainType) must produce the type of morphisms between objects of type ChainType;
  • the call signature for function (fac::TensorProductFactory{ChainType})(dc::AbsDoubleComplexOfMorphisms, i::Int, j::Int) needs to be overwritten for your specific instance of ChainType to produce the (i, j)-th entry of the double complex, i.e. the tensor product of C[i] and D[j];
  • the call signature for function (fac::HorizontalTensorMapFactory{ChainType})(dc::AbsDoubleComplexOfMorphisms, i::Int, j::Int) needs to be overwritten to produce the map on tensor products C[i] ⊗ D[j] → C[i±1] ⊗ D[j] induced by the (co-)boundary map on C (the sign depending on the typ of C);
  • similarly for the VerticalTensorMapFactory.

See the file experimental/DoubleComplex/src/tensor_products.jl for examples.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
diff --git a/previews/PR4245/Experimental/FTheoryTools/g4/index.html b/previews/PR4245/Experimental/FTheoryTools/g4/index.html deleted file mode 100644 index e26f075b3c6f..000000000000 --- a/previews/PR4245/Experimental/FTheoryTools/g4/index.html +++ /dev/null @@ -1,46 +0,0 @@ - -G4-Fluxes · Oscar.jl

G4-Fluxes

\[G_4\]

-fluxes are at the heart of F-theory model building.

Constructors

We currently support the following constructor:

g4_fluxMethod
g4_flux(model::AbstractFTheoryModel, class::CohomologyClass)

Construct a G4-flux candidate on an F-theory model. This functionality is currently limited to

  • Weierstrass models,
  • global Tate models,
  • hypersurface models.

Furthermore, our functionality requires a concrete geometry. That is, the base space as well as the ambient space must be toric varieties. In the toric ambient space $X_\Sigma$, the elliptically fibered space $Y$ that defines the F-theory model, is given by a hypersurface (cut out by the Weierstrass, Tate or hypersurface polynomial, respectively).

In this setting, we assume that a $G_4$-flux candidate is represented by a cohomology class $h$ in $H^{(2,2)} (X_\Sigma)$. The actual $G_4$-flux candidate is then obtained by restricting $h$ to $Y$.

It is worth recalling that the $G_4$-flux candidate is subject to the quantization condition $G_4 + \frac{1}{2} c_2(Y) \in H^{/2,2)}( Y_, \mathbb{Z})$ (see [Wit97]). This condition is very hard to verify. However, it is relatively easy to gather evidence for this condition to be satisfied/show that it is violated. To this end, let $D_1$, $D_2$ be two toric divisors in $X_\Sigma$, then the topological intersection number $\left[ h|_Y \right] \cdot \left[ P \right] \cdot \left[ D_1 \right] \cdot \left[ D_2 \right]$ must be an integer. Even this rather elementary check can be computationally expensive. Users can therefore decide to skip this check upon construction by setting the parameter check to the value false.

Another bottleneck can be the computation of the cohomology ring, which is necessary to work with cohomology classes on the toric ambient space, which in turn define the G4-flux, as explained above. The reason for this is, that by employing the theory explained in [CLS11], we can only work out the cohomology ring of simpicial and complete (i.e. compact) toric varieties. However, checking if a toric variety is complete (i.e. compact) can take a long time. If the geometry in question is involved and you already know that the variety is simplicial and complete, then we recommend to trigger the computation of the cohomology ring with check = false. This will avoid this time consuming test.

An example is in order.

Examples

julia> qsm_model = literature_model(arxiv_id = "1903.00009", model_parameters = Dict("k" => 4))
-Hypersurface model over a concrete base
-
-julia> cohomology_ring(ambient_space(qsm_model), check = false);
-
-julia> g4_class = cohomology_class(anticanonical_divisor_class(ambient_space(qsm_model)))^2;
-
-julia> g4f = g4_flux(qsm_model, g4_class)
-G4-flux candidate
-
-julia> g4f2 = g4_flux(qsm_model, g4_class, check = false)
-G4-flux candidate lacking elementary quantization checks
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source

Attributes

We currently support the following attributes:

modelMethod
model(gf::G4Flux)

Return the F-theory model for which this $G_4$-flux candidate is defined.

julia> qsm_model = literature_model(arxiv_id = "1903.00009", model_parameters = Dict("k" => 4))
-Hypersurface model over a concrete base
-
-julia> cohomology_ring(ambient_space(qsm_model), check = false);
-
-julia> g4_class = cohomology_class(anticanonical_divisor_class(ambient_space(qsm_model)))^2;
-
-julia> g4f = g4_flux(qsm_model, g4_class, check = false)
-G4-flux candidate lacking elementary quantization checks
-
-julia> model(g4f)
-Hypersurface model over a concrete base
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
cohomology_classMethod
cohomology_class(gf::G4Flux)

Return the cohomology class which defines the $G_4$-flux candidate.

julia> qsm_model = literature_model(arxiv_id = "1903.00009", model_parameters = Dict("k" => 4))
-Hypersurface model over a concrete base
-
-julia> cohomology_ring(ambient_space(qsm_model), check = false);
-
-julia> g4_class = cohomology_class(anticanonical_divisor_class(ambient_space(qsm_model)))^2;
-
-julia> g4f = g4_flux(qsm_model, g4_class, check = false)
-G4-flux candidate lacking elementary quantization checks
-
-julia> cohomology_class(g4f) == g4_class
-true
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source

Properties

We currently support the following properties:

passes_elementary_quantization_checksMethod
passes_elementary_quantization_checks(gf::G4Flux)

G4-fluxes are subject to the quantization condition [Wit97] $G_4 + \frac{1}{2} c_2(Y) \in H^{(2,2)}(Y, \mathbb{Z})$. It is hard to verify that this condition is met. However, we can execute a number of simple consistency checks, by verifying that $\int_{Y}{G_4 \wedge [D_1] \wedge [D_2]} \in \mathbb{Z}$ for any two toric divisors $D_1$, $D_2$. If all of these simple consistency checks are met, this method will return true and otherwise false.

It is worth mentioning that currently (August 2024), we only support this check for $G_4$-fluxes defined on Weierstrass, global Tate and hypersurface models. If this condition is not met, this method will return an error.

julia> qsm_model = literature_model(arxiv_id = "1903.00009", model_parameters = Dict("k" => 4))
-Hypersurface model over a concrete base
-
-julia> cohomology_ring(ambient_space(qsm_model), check = false);
-
-julia> g4_class = cohomology_class(anticanonical_divisor_class(ambient_space(qsm_model)))^2;
-
-julia> g4 = g4_flux(qsm_model, g4_class, check = false)
-G4-flux candidate lacking elementary quantization checks
-
-julia> passes_elementary_quantization_checks(g4)
-true
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source

Methods

diff --git a/previews/PR4245/Experimental/FTheoryTools/generalities/index.html b/previews/PR4245/Experimental/FTheoryTools/generalities/index.html deleted file mode 100644 index bed6cbfad4f3..000000000000 --- a/previews/PR4245/Experimental/FTheoryTools/generalities/index.html +++ /dev/null @@ -1,393 +0,0 @@ - -Functionality for all F-theory models · Oscar.jl

Functionality for all F-theory models

All F-theory models focus on elliptic (or genus-one) fibrations. Details depend on the specific way in which the fibration is constructed/described. Still, some functionality is common among all or at least the majority of all supported models. We will document such common functionality here.

Family of Spaces

Many F-theory constructions (e.g. in the literature) work without fully specifying the base space of the elliptic fibrations. Put differently, those works consider an entire family of base spaces. We aim to support this data structure.

Note of caution: This data structure is subject to discussion. The exact implementation details may change drastically in the future. Use with care (as all experimental code, of course).

Constructors

We currently support the following constructor:

family_of_spacesMethod
family_of_spaces(coordinate_ring::MPolyRing, grading::Matrix{Int64}, dim::Int)

Return a family of spaces that is (currently) used to build families of F-theory models, defined by using a family of base spaces for an elliptic fibration. It is specified by the following data:

  • A polynomial ring. This may be thought of as the coordinate ring of the generic member in this family of spaces.
  • A grading for this polynomial ring. This may be thought of as specifying certain line bundles on the generic member in this family of spaces. Of particular interest for F-theory is always the canonical bundle. For this reason, the first row is always thought of as grading the coordinate ring with regard to the canonical bundle. Or put differently, if a variable shares the weight 1 in the first row, then this means that we should think of this coordinate as a section of 1 times the canonical bundle.
  • An integer, which specifies the dimension of the generic member within this family of spaces.

Note that the coordinate ring can have strictly more variables than the dimension. This is a desired feature for most, if not all, F-theory literature constructions.

julia> coord_ring, _ = QQ[:f, :g, :Kbar, :u];
-
-julia> grading = [4 6 1 0; 0 0 0 1]
-2×4 Matrix{Int64}:
- 4  6  1  0
- 0  0  0  1
-
-julia> d = 3
-3
-
-julia> f = family_of_spaces(coord_ring, grading, d)
-A family of spaces of dimension d = 3
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source

Attributes

We currently support the following attributes:

coordinate_ringMethod
coordinate_ring(f::FamilyOfSpaces)

Return the coordinate ring of a generic member of the family of spaces.

julia> ring, (f, g, Kbar, u) = QQ[:f, :g, :Kbar, :u]
-(Multivariate polynomial ring in 4 variables over QQ, QQMPolyRingElem[f, g, Kbar, u])
-
-julia> grading = [4 6 1 0; 0 0 0 1]
-2×4 Matrix{Int64}:
- 4  6  1  0
- 0  0  0  1
-
-julia> d = 3
-3
-
-julia> f = family_of_spaces(ring, grading, d)
-A family of spaces of dimension d = 3
-
-julia> coordinate_ring(f)
-Multivariate polynomial ring in 4 variables f, g, Kbar, u
-  over rational field
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
weightsMethod
weights(f::FamilyOfSpaces)

Return the grading of the coordinate ring of a generic member of the family of spaces.

julia> ring, (f, g, Kbar, u) = QQ[:f, :g, :Kbar, :u]
-(Multivariate polynomial ring in 4 variables over QQ, QQMPolyRingElem[f, g, Kbar, u])
-
-julia> grading = [4 6 1 0; 0 0 0 1]
-2×4 Matrix{Int64}:
- 4  6  1  0
- 0  0  0  1
-
-julia> d = 3
-3
-
-julia> f = family_of_spaces(ring, grading, d)
-A family of spaces of dimension d = 3
-
-julia> weights(f)
-2×4 Matrix{Int64}:
- 4  6  1  0
- 0  0  0  1
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
dimMethod
dim(f::FamilyOfSpaces)

Return the dimension of the generic member of the family of spaces.

julia> ring, (f, g, Kbar, u) = QQ[:f, :g, :Kbar, :u]
-(Multivariate polynomial ring in 4 variables over QQ, QQMPolyRingElem[f, g, Kbar, u])
-
-julia> grading = [4 6 1 0; 0 0 0 1]
-2×4 Matrix{Int64}:
- 4  6  1  0
- 0  0  0  1
-
-julia> d = 3
-3
-
-julia> f = family_of_spaces(ring, grading, d)
-A family of spaces of dimension d = 3
-
-julia> dim(f)
-3
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
irrelevant_idealMethod
irrelevant_ideal(f::FamilyOfSpaces)

Return the equivalent of the irrelevant ideal for the generic member of the family of spaces.

julia> coord_ring, (f, g, Kbar, u) = QQ[:f, :g, :Kbar, :u]
-(Multivariate polynomial ring in 4 variables over QQ, QQMPolyRingElem[f, g, Kbar, u])
-
-julia> grading = [4 6 1 0; 0 0 0 1]
-2×4 Matrix{Int64}:
- 4  6  1  0
- 0  0  0  1
-
-julia> d = 3
-3
-
-julia> f = family_of_spaces(coord_ring, grading, d)
-A family of spaces of dimension d = 3
-
-julia> irrelevant_ideal(f)
-Ideal generated by
-  u
-  Kbar
-  g
-  f
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
ideal_of_linear_relationsMethod
ideal_of_linear_relations(f::FamilyOfSpaces)

Return the equivalent of the ideal of linear relations for the generic member of the family of spaces.

julia> coord_ring, (f, g, Kbar, u) = QQ[:f, :g, :Kbar, :u]
-(Multivariate polynomial ring in 4 variables over QQ, QQMPolyRingElem[f, g, Kbar, u])
-
-julia> grading = [4 6 1 0; 0 0 0 1]
-2×4 Matrix{Int64}:
- 4  6  1  0
- 0  0  0  1
-
-julia> f = family_of_spaces(coord_ring, grading, 3)
-A family of spaces of dimension d = 3
-
-julia> ideal_of_linear_relations(f)
-Ideal generated by
-  -5*f + 3*g + 2*Kbar
-  -3*f + 2*g
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source

Printouts

The user can decide to get information whenever a family of spaces is being used. To this end, one invokes set_verbosity_level(:FTheoryModelPrinter, 1). More information is available here.

Attributes of all (or most) F-theory models

ambient_spaceMethod
ambient_space(m::AbstractFTheoryModel)

Return the ambient space of the F-theory 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> ambient_space(m)
-A family of spaces of dimension d = 5
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
base_spaceMethod
base_space(m::AbstractFTheoryModel)

Return the base space of the F-theory 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> base_space(m)
-A family of spaces of dimension d = 3
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
fiber_ambient_spaceMethod
fiber_ambient_space(m::AbstractFTheoryModel)

Return the fiber ambient space of an F-theory 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)
-Normal toric variety
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
explicit_model_sectionsMethod
explicit_model_sections(m::AbstractFTheoryModel)

Return the model sections in explicit form, that is as polynomials of the base space coordinates.

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> explicit_model_sections(t)
-Dict{String, QQMPolyRingElem} with 9 entries:
-  "a6"  => 0
-  "a21" => a21
-  "a3"  => w^2*a32
-  "w"   => w
-  "a2"  => w*a21
-  "a1"  => a1
-  "a4"  => w^3*a43
-  "a43" => a43
-  "a32" => a32
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
defining_section_parametrizationMethod
defining_section_parametrization(m::AbstractFTheoryModel)

Return the model sections in explicit form, that is as polynomials of the base space coordinates.

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> defining_section_parametrization(t)
-Dict{String, MPolyRingElem} with 4 entries:
-  "a6" => 0
-  "a3" => w^2*a32
-  "a2" => w*a21
-  "a4" => w^3*a43
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
classes_of_model_sectionsMethod
classes_of_model_sections(m::AbstractFTheoryModel)

Return the divisor classes of all model sections.

julia> B3 = projective_space(NormalToricVariety, 3)
-Normal toric variety
-
-julia> w = torusinvariant_prime_divisors(B3)[1]
-Torus-invariant, prime divisor on a normal toric variety
-
-julia> t = literature_model(arxiv_id = "1109.3454", equation = "3.1", base_space = B3, defining_classes = Dict("w" => w), completeness_check = false)
-Construction over concrete base may lead to singularity enhancement. Consider computing singular_loci. However, this may take time!
-
-Global Tate model over a concrete base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)
-
-julia> classes_of_model_sections(t)
-Dict{String, ToricDivisorClass} with 9 entries:
-  "a21" => Divisor class on a normal toric variety
-  "a6"  => Divisor class on a normal toric variety
-  "a3"  => Divisor class on a normal toric variety
-  "w"   => Divisor class on a normal toric variety
-  "a2"  => Divisor class on a normal toric variety
-  "a1"  => Divisor class on a normal toric variety
-  "a43" => Divisor class on a normal toric variety
-  "a4"  => Divisor class on a normal toric variety
-  "a32" => Divisor class on a normal toric variety
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
defining_classesMethod
defining_classes(m::AbstractFTheoryModel)

Return the defining divisor classes of the model in question.

julia> B3 = projective_space(NormalToricVariety, 3)
-Normal toric variety
-
-julia> w = torusinvariant_prime_divisors(B3)[1]
-Torus-invariant, prime divisor on a normal toric variety
-
-julia> t = literature_model(arxiv_id = "1109.3454", equation = "3.1", base_space = B3, defining_classes = Dict("w" => w), completeness_check = false)
-Construction over concrete base may lead to singularity enhancement. Consider computing singular_loci. However, this may take time!
-
-Global Tate model over a concrete base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)
-
-julia> defining_classes(t)
-Dict{String, ToricDivisorClass} with 2 entries:
-  "w"    => Divisor class on a normal toric variety
-  "Kbar" => Divisor class on a normal toric variety
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
gauge_algebraMethod
gauge_algebra(m::AbstractFTheoryModel)

Return the gauge algebra of the given model. If no gauge algebra is known, an error is raised. This information is typically available for all models, however.

julia> t = literature_model(arxiv_id = "1408.4808", equation = "3.190", type = "hypersurface")
-Assuming that the first row of the given grading is the grading under Kbar
-
-Hypersurface model over a not fully specified base
-
-julia> gauge_algebra(t)
-Direct sum Lie algebra
-  of dimension 13
-with summands
-  sl_2
-  sl_2
-  sl_2
-  sl_2
-  linear Lie algebra
-over field of algebraic numbers
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
global_gauge_quotientsMethod
global_gauge_quotients(m::AbstractFTheoryModel)

Return list of lists of matrices, where each list of matrices corresponds to a gauge factor of the same index given by gauge_algebra(m). These matrices are elements of the center of the corresponding gauge factor and quotienting by them replicates the action of some discrete group on the center of the lie algebra. This list combined with gauge_algebra(m) completely determines the gauge group of the model. If no gauge quotients are known, an error is raised.

julia> t = literature_model(arxiv_id = "1408.4808", equation = "3.190", type = "hypersurface")
-Assuming that the first row of the given grading is the grading under Kbar
-
-Hypersurface model over a not fully specified base
-
-julia> global_gauge_quotients(t)
-5-element Vector{Vector{String}}:
- ["-identity_matrix(C,2)", "-identity_matrix(C,2)"]
- ["-identity_matrix(C,2)"]
- ["-identity_matrix(C,2)"]
- ["-identity_matrix(C,2)", "-identity_matrix(C,2)"]
- ["-identity_matrix(C,1)"]
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
chern_classMethod
chern_class(m::AbstractFTheoryModel, k::Int; check::Bool = true)

If the elliptically fibered n-fold $Y_n$ underlying the F-theory model in question is given as a hypersurface in a toric ambient space, we can compute a cohomology class $h$ on the toric ambient space $X_\Sigma$, such that its restriction to $Y_n$ is the k-th Chern class $c_k$ of the tangent bundle of $Y_n$. If those assumptions are satisfied, this method returns this very cohomology class $h$, otherwise it raises an error.

The theory guarantees that the implemented algorithm works for toric ambient spaces which are smooth and complete. The check for completeness can be very time consuming. This check can be switched off by setting the optional argument check to the value false, as demonstrated below.

julia> qsm_model = literature_model(arxiv_id = "1903.00009", model_parameters = Dict("k" => 4))
-Hypersurface model over a concrete base
-
-julia> h = chern_class(qsm_model, 4; check = false);
-
-julia> is_trivial(h)
-false
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
chern_classesMethod
chern_classes(m::AbstractFTheoryModel; check::Bool = true)

If the elliptically fibered n-fold $Y_n$ underlying the F-theory model in question is given as a hypersurface in a toric ambient space, we can compute a cohomology class $h$ on the toric ambient space $X_\Sigma$, such that its restriction to $Y_n$ is the k-th Chern class $c_k$ of the tangent bundle of $Y_n$. If those assumptions are satisfied, this method returns a vector with the cohomology classes corresponding to all non-trivial Chern classes $c_k$ of $Y_n$. Otherwise, this methods raises an error.

As of right now, this method is computationally expensive for involved toric ambient spaces, such as in the example below.

The theory guarantees that the implemented algorithm works for toric ambient spaces which are simplicial and complete. The check for completeness can be very time consuming. This check can be switched off by setting the optional argument check to the value false, as demonstrated below.

julia> qsm_model = literature_model(arxiv_id = "1903.00009", model_parameters = Dict("k" => 4))
-Hypersurface model over a concrete base
-
-julia> h = chern_classes(qsm_model; check = false);
-
-julia> is_one(polynomial(h[1]))
-true
-
-julia> is_trivial(h[2])
-true
-
-julia> is_trivial(h[3])
-false
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
euler_characteristicMethod
euler_characteristic(m::AbstractFTheoryModel; check::Bool = true)

If the elliptically fibered n-fold $Y_n$ underlying the F-theory model in question is given as a hypersurface in a toric ambient space, we can compute the Euler characteristic. If this assumptions is satisfied, this method returns the Euler characteristic, otherwise it raises an error.

julia> qsm_model = literature_model(arxiv_id = "1903.00009", model_parameters = Dict("k" => 4))
-Hypersurface model over a concrete base
-
-julia> h = euler_characteristic(qsm_model; check = false)
-378
-
-julia> h = euler_characteristic(qsm_model; check = false)
-378
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source

Properties of all (or most) F-theory models

is_base_space_fully_specifiedMethod
is_base_space_fully_specified(m::AbstractFTheoryModel)

Return true if the F-theory 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> is_base_space_fully_specified(t)
-false
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
is_calabi_yauMethod
is_calabi_yau(m::AbstractFTheoryModel; check::Bool = true)

Verify if the first Chern class of the tangent bundle of the F-theory geometry $Y_n$ vanishes. If so, this confirms that this geometry is indeed Calabi-Yau, as required by the reasoning of F-theory.

The implemented algorithm works for hypersurface, Weierstrass and global Tate models, which are defined in a toric ambient space. It expresses $c_1(Y_n)$ as the restriction of a cohomology class $h$ on the toric ambient space. This in turn requires that the toric ambient space is simplicial and complete. We provide a switch to turn off these computationally very demanding checks. This is demonstrated in the example below.

julia> qsm_model = literature_model(arxiv_id = "1903.00009", model_parameters = Dict("k" => 4))
-Hypersurface model over a concrete base
-
-julia> is_calabi_yau(qsm_model, check = false)
-true
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
is_partially_resolvedMethod
is_partially_resolved(m::AbstractFTheoryModel)

Return true if resolution techniques were applied to the F-theory model, thereby potentially resolving its singularities. Otherwise, return false.

julia> B3 = projective_space(NormalToricVariety, 3)
-Normal toric variety
-
-julia> w = torusinvariant_prime_divisors(B3)[1]
-Torus-invariant, prime divisor on a normal toric variety
-
-julia> t = literature_model(arxiv_id = "1109.3454", equation = "3.1", base_space = B3, defining_classes = Dict("w" => w), completeness_check = false)
-Construction over concrete base may lead to singularity enhancement. Consider computing singular_loci. However, this may take time!
-
-Global Tate model over a concrete base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)
-
-julia> is_partially_resolved(t)
-false
-
-julia> t2 = blow_up(t, ["x", "y", "x1"]; coordinate_name = "e1")
-Partially resolved global Tate model over a concrete base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)
-
-julia> is_partially_resolved(t2)
-true
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
verify_euler_characteristic_from_hodge_numbersMethod
verify_euler_characteristic_from_hodge_numbers(m::AbstractFTheoryModel; check::Bool = true)

Verify if the Euler characteristic, as computed from integrating the 4-th Chern class, agrees with the results obtained from using the alternating sum of the Hodge numbers. If so, this method returns true. However, should information be missing, (e.g. some Hodge numbers), or the dimension of the F-theory model differ form 4, then this method raises an error.

julia> qsm_model = literature_model(arxiv_id = "1903.00009", model_parameters = Dict("k" => 4))
-Hypersurface model over a concrete base
-
-julia> verify_euler_characteristic_from_hodge_numbers(qsm_model, check = false)
-true
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source

Methods for all (or most) F-theory models

blow_upMethod
blow_up(m::AbstractFTheoryModel, ideal_gens::Vector{String}; coordinate_name::String = "e")

Resolve an F-theory model by blowing up a locus in the ambient space.

Examples

julia> B3 = projective_space(NormalToricVariety, 3)
-Normal toric variety
-
-julia> w = torusinvariant_prime_divisors(B3)[1]
-Torus-invariant, prime divisor on a normal toric variety
-
-julia> t = literature_model(arxiv_id = "1109.3454", equation = "3.1", base_space = B3, defining_classes = Dict("w" => w), completeness_check = false)
-Construction over concrete base may lead to singularity enhancement. Consider computing singular_loci. However, this may take time!
-
-Global Tate model over a concrete base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)
-
-julia> blow_up(t, ["x", "y", "x1"]; coordinate_name = "e1")
-Partially resolved global Tate model over a concrete base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)

Here is an example for a Weierstrass model.

Examples

julia> B2 = projective_space(NormalToricVariety, 2)
-Normal toric variety
-
-julia> b = torusinvariant_prime_divisors(B2)[1]
-Torus-invariant, prime divisor on a normal toric variety
-
-julia> w = literature_model(arxiv_id = "1208.2695", equation = "B.19", base_space = B2, defining_classes = Dict("b" => b), completeness_check = false)
-Construction over concrete base may lead to singularity enhancement. Consider computing singular_loci. However, this may take time!
-
-Weierstrass model over a concrete base -- U(1) Weierstrass model based on arXiv paper 1208.2695 Eq. (B.19)
-
-julia> blow_up(w, ["x", "y", "x1"]; coordinate_name = "e1")
-Partially resolved Weierstrass model over a concrete base -- U(1) Weierstrass model based on arXiv paper 1208.2695 Eq. (B.19)
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
blow_upMethod
blow_up(m::AbstractFTheoryModel, I::MPolyIdeal; coordinate_name::String = "e")

Resolve an F-theory model by blowing up a locus in the ambient space.

Examples

julia> B3 = projective_space(NormalToricVariety, 3)
-Normal toric variety
-
-julia> w = torusinvariant_prime_divisors(B3)[1]
-Torus-invariant, prime divisor on a normal toric variety
-
-julia> t = literature_model(arxiv_id = "1109.3454", equation = "3.1", base_space = B3, defining_classes = Dict("w" => w), completeness_check = false)
-Construction over concrete base may lead to singularity enhancement. Consider computing singular_loci. However, this may take time!
-
-Global Tate model over a concrete base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)
-
-julia> x1, x2, x3, x4, x, y, z = gens(cox_ring(ambient_space(t)))
-7-element Vector{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}:
- x1
- x2
- x3
- x4
- x
- y
- z
-
-julia> blow_up(t, ideal([x, y, x1]); coordinate_name = "e1")
-Partially resolved global Tate model over a concrete base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
blow_upMethod
blow_up(m::AbstractFTheoryModel, I::AbsIdealSheaf; coordinate_name::String = "e")

Resolve an F-theory model by blowing up a locus in the ambient space. For this method, the blowup center is encoded by an ideal sheaf.

Examples

julia> B3 = projective_space(NormalToricVariety, 3)
-Normal toric variety
-
-julia> w = torusinvariant_prime_divisors(B3)[1]
-Torus-invariant, prime divisor on a normal toric variety
-
-julia> t = literature_model(arxiv_id = "1109.3454", equation = "3.1", base_space = B3, defining_classes = Dict("w" => w), completeness_check = false)
-Construction over concrete base may lead to singularity enhancement. Consider computing singular_loci. However, this may take time!
-
-Global Tate model over a concrete base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)
-
-julia> x1, x2, x3, x4, x, y, z = gens(cox_ring(ambient_space(t)))
-7-element Vector{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}:
- x1
- x2
- x3
- x4
- x
- y
- z
-
-julia> blowup_center = ideal_sheaf(ambient_space(t), ideal([x, y, x1]))
-Sheaf of ideals
-  on normal, simplicial toric variety
-with restrictions
-   1: Ideal (x_5_1, x_4_1, x_1_1)
-   2: Ideal (1)
-   3: Ideal (x_5_3, x_4_3, x_1_3)
-   4: Ideal (x_5_4, x_4_4, x_1_4)
-   5: Ideal (1)
-   6: Ideal (1)
-   7: Ideal (1)
-   8: Ideal (1)
-   9: Ideal (1)
-  10: Ideal (1)
-  11: Ideal (1)
-  12: Ideal (1)
-
-julia> blow_up(t, blowup_center; coordinate_name = "e1")
-Partially resolved global Tate model over a concrete base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
tuneMethod
tune(m::AbstractFTheoryModel, p::MPolyRingElem; completeness_check::Bool = true)

Tune an F-theory model by replacing the hypersurface equation by a custom (polynomial) equation. The latter can be any type of polynomial: a Tate polynomial, a Weierstrass polynomial or a general polynomial. We do not conduct checks to tell which type the provided polynomial is. Consequently, this tuning will always return a hypersurface model.

Note that there is less functionality for hypersurface models than for Weierstrass or Tate models. For instance, singular_loci can (currently) not be computed for hypersurface models.

Examples

julia> B3 = projective_space(NormalToricVariety, 3)
-Normal toric variety
-
-julia> w = torusinvariant_prime_divisors(B3)[1]
-Torus-invariant, prime divisor on a normal toric variety
-
-julia> t = literature_model(arxiv_id = "1109.3454", equation = "3.1", base_space = B3, defining_classes = Dict("w" => w), completeness_check = false)
-Construction over concrete base may lead to singularity enhancement. Consider computing singular_loci. However, this may take time!
-
-Global Tate model over a concrete base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)
-
-julia> x1, x2, x3, x4, x, y, z = gens(parent(tate_polynomial(t)))
-7-element Vector{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}:
- x1
- x2
- x3
- x4
- x
- y
- z
-
-julia> new_tate_polynomial = x^3 - y^2 - x * y * z * x4^4
--x4^4*x*y*z + x^3 - y^2
-
-julia> tuned_t = tune(t, new_tate_polynomial)
-Hypersurface model over a concrete base
-
-julia> hypersurface_equation(tuned_t) == new_tate_polynomial
-true
-
-julia> base_space(tuned_t) == base_space(t)
-true
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
put_over_concrete_baseMethod
put_over_concrete_base(m::AbstractFTheoryModel, concrete_data::Dict{String, <:Any}; completeness_check::Bool = true)

Put an F-theory model defined over a family of spaces over a concrete base.

Currently, this functionality is limited to Tate and Weierstrass models.

Examples

julia> t = literature_model(arxiv_id = "1109.3454", equation = "3.1", completeness_check = false)
-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> B3 = projective_space(NormalToricVariety, 3)
-Normal toric variety
-
-julia> w_bundle = toric_line_bundle(torusinvariant_prime_divisors(B3)[1])
-Toric line bundle on a normal toric variety
-
-julia> kbar = anticanonical_bundle(B3)
-Toric line bundle on a normal toric variety
-
-julia> w = generic_section(w_bundle);
-
-julia> a21 = generic_section(kbar^2 * w_bundle^(-1));
-
-julia> a32 = generic_section(kbar^3 * w_bundle^(-2));
-
-julia> a43 = generic_section(kbar^4 * w_bundle^(-3));
-
-julia> t2 = put_over_concrete_base(t, Dict("base" => B3, "w" => w, "a21" => a21, "a32" => a32, "a43" => a43), completeness_check = false)
-Global Tate model over a concrete base
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
diff --git a/previews/PR4245/Experimental/FTheoryTools/hypersurface/index.html b/previews/PR4245/Experimental/FTheoryTools/hypersurface/index.html deleted file mode 100644 index a0a70c144c0c..000000000000 --- a/previews/PR4245/Experimental/FTheoryTools/hypersurface/index.html +++ /dev/null @@ -1,126 +0,0 @@ - -Hypersurface models · Oscar.jl

Hypersurface models

Introduction

A hypersurface model describes a particular form of an elliptic fibration. We make the following assumptions:

  • The generic fiber is a hypersurface in a 2-dimensional toric fiber ambient space $F$.
  • The first two (homogeneous) coordinates in the coordinate ring 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 [KM-POPR15] for more details.

Our tools are most powerful if the base space $B$ is a toric variety. Then, based on the above 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.

Certainly, one often wishes to extend beyond this setting:

  • Oftentimes, a special hypersurface equation is chosen. In the toric setting above, this will

be a polynomial in the Cox ring of the toric ambient space. Since said ambient space, and therefore also its Cox ring, are computed in the cause of the above construction, we do not support one constructor, which immediately accepts a special hypersurface equation. Rather, in this case, the user must first use one of the general constructors described in the next section. Subsequently, the tune function, described in the methods section below, can be employed.

  • Bases other than toric spaces matter. Often, the F-theory literature will not even assume

one particular base space but rather an entire family of base spaces. We extend our machinery to these cases, but such more general settings are typically significantly more limited than the toric setting. This limitation originates from the nature of the matter – the more general the geometry, the less is known.

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. For this, please use our tune function, described in the methods section below.]

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. Here is how we can construct a hypersurface model in OSCAR:

hypersurface_modelMethod
function hypersurface_model(base::NormalToricVariety, fiber_ambient_space::NormalToricVariety, fiber_twist_divisor_classes::Vector{ToricDivisorClass}, p::MPolyRingElem; 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> b = projective_space(NormalToricVariety, 2)
-Normal toric variety
-
-julia> fiber_ambient_space = weighted_projective_space(NormalToricVariety, [2,3,1])
-Normal toric variety
-
-julia> set_coordinate_names(fiber_ambient_space, ["x", "y", "z"])
-
-julia> D1 = 2 * anticanonical_divisor_class(b)
-Divisor class on a normal toric variety
-
-julia> D2 = 3 * anticanonical_divisor_class(b)
-Divisor class on a normal toric variety
-
-julia> D3 = trivial_divisor_class(b)
-Divisor class on a normal toric variety
-
-julia> new_gens = string.(vcat(gens(cox_ring(b)), gens(cox_ring(fiber_ambient_space))))
-6-element Vector{String}:
- "x1"
- "x2"
- "x3"
- "x"
- "y"
- "z"
-
-julia> ambient_ring, (x1, x2, x3, x, y, z) = polynomial_ring(QQ, new_gens, cached=false)
-(Multivariate polynomial ring in 6 variables over QQ, QQMPolyRingElem[x1, x2, x3, x, y, z])
-
-julia> p = x^3 - y^2 + x1^12 * x * z^4 + x2^18 * z^6 + 13 * x3^3*x*y*z
-x1^12*x*z^4 + x2^18*z^6 + 13*x3^3*x*y*z + x^3 - y^2
-
-julia> h = hypersurface_model(b, fiber_ambient_space, [D1, D2, D3], p; completeness_check = false)
-Hypersurface model over a concrete base
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source

For convenience, it also possible to provide the hypersurface polynomial p as a string.

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, fiber_twist_divisor_classes::Vector{Vector{Int64}}, p::MPolyRingElem)

This method constructs a hypersurface model over a base space that is not fully specified. In the background, we construct a family of spaces to represent the base space. This method requires the following information:

  1. The names of the homogeneous coordinates of the coordinate ring of the generic member

of the family of bsae spaces.

  1. The grading of the coordinate ring of the generic member of the family of base spaces.
  2. The weights telling us how the fiber ambient space coordinates transform under the base.
  3. The dimension of the generic member of the family of base spaces.
  4. The fiber ambient space.
  5. 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 coordinate ring of the generic member of the family of base space, unless the user already provides this grading. Our convention is that the first row of the grading matrix 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> D3 = [0,0]
-2-element Vector{Int64}:
- 0
- 0
- 
-julia> d = 3
-3
-
-julia> fiber_ambient_space = weighted_projective_space(NormalToricVariety, [2,3,1])
-Normal toric variety
-
-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, D3], p)
-Assuming that the first row of the given grading is the grading under Kbar
-
-Hypersurface model over a not fully specified base
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source

For convenience, the fibertwistdivisor_classes can also be provided as ZZMatrix.

Attributes

Basic attributes

All hypersurface models come with a hypersurface equation:

hypersurface_equationMethod
hypersurface_equation(h::HypersurfaceModel)

Return the hypersurface equation.

julia> B2 = projective_space(NormalToricVariety, 2)
-Normal toric variety
-
-julia> b = torusinvariant_prime_divisors(B2)[1]
-Torus-invariant, prime divisor on a normal toric variety
-
-julia> h = literature_model(arxiv_id = "1208.2695", equation = "B.5", base_space = B2, defining_classes = Dict("b" => b))
-Construction over concrete base may lead to singularity enhancement. Consider computing singular_loci. However, this may take time!
-
-Hypersurface model over a concrete base
-
-julia> hypersurface_equation(h);
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source

Note that this equation is a polynomial in the coordinate ring of a suitable ambient space. This ambient space is computed by our constructors. Consequently, the coordinate ring, in which the hypersurface equation is an element, is only available after the model has been constructed.

Some hypersurface models parametrize the hypersurface equation with sections of line bundles of the base space. One can obtain those sections and their explicit polynomial expressions over the base with explicit_model_sections. The parametrization of the hypersurface equation by these sections is found as follows:

hypersurface_equation_parametrizationMethod
hypersurface_equation_parametrization(h::HypersurfaceModel)

Return the parametrization of the hypersurface equation by the model sections.

julia> h = literature_model(arxiv_id = "1208.2695", equation = "B.5")
-Assuming that the first row of the given grading is the grading under Kbar
-
-Hypersurface model over a not fully specified base
-
-julia> explicit_model_sections(h)
-Dict{String, MPolyRingElem} with 5 entries:
-  "c2" => c2
-  "c1" => c1
-  "c3" => c3
-  "b"  => b
-  "c0" => c0
-
-julia> hypersurface_equation_parametrization(h)
-b*w*v^2 - c0*u^4 - c1*u^3*v - c2*u^2*v^2 - c3*u*v^3 + w^2
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source

To specify a custom value for the hypersurface equation, first use one of the above constructors. Once completed, employ the tune function described in the methods section to set the hypersurface equation to your desired value.

The base space can be obtained with base_space, the ambient space with ambient_space and the fiber ambient space with fiber_ambient_space. Recall that is_base_space_fully_specified will tell if the model has been constructed over a concrete space (in which case the function returns true) or a family of spaces (returning false).

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> B2 = projective_space(NormalToricVariety, 2)
-Normal toric variety
-
-julia> b = torusinvariant_prime_divisors(B2)[1]
-Torus-invariant, prime divisor on a normal toric variety
-
-julia> h = literature_model(arxiv_id = "1208.2695", equation = "B.5", base_space = B2, defining_classes = Dict("b" => b))
-Construction over concrete base may lead to singularity enhancement. Consider computing singular_loci. However, this may take time!
-
-Hypersurface model over a concrete base
-
-julia> calabi_yau_hypersurface(h)
-Closed subvariety of a normal toric variety
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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 former is known.

julia> t = literature_model(14)
-Assuming that the first row of the given grading is the grading under Kbar
-
-Hypersurface model over a not fully specified base
-
-julia> weierstrass_model(t)
-Assuming that the first row of the given grading is the grading under Kbar
-
-Weierstrass model over a not fully specified base -- F-theory weierstrass model dual to hypersurface model with fiber ambient space F_1 based on arXiv paper 1408.4808 Eq. (3.4)
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source

Methods

Tuning

Tuning is possible with the tune function, cf. Functionality for all F-theory models.

diff --git a/previews/PR4245/Experimental/FTheoryTools/introduction/index.html b/previews/PR4245/Experimental/FTheoryTools/introduction/index.html deleted file mode 100644 index 0ea54d8bbf03..000000000000 --- a/previews/PR4245/Experimental/FTheoryTools/introduction/index.html +++ /dev/null @@ -1,2 +0,0 @@ - -Welcome to FTheoryTools · Oscar.jl

Welcome to FTheoryTools

Goal

We aim to automate numerous recurring and, at least in part, tedious computations in F-Theory model building, as detailed extensively in [Wei18]. The primary focus of our software is on (complex) elliptic fibrations with singularities. Those singularities hold significant importance. In essence, the absence of these singularities implies that the geometry encodes trivial or uninteresting physics. Therefore, the smooth case is typically not explored.

A substantial amount of information about the physics is encoded in the geometry of this singular fibration. To some extent it is clear what geometric quantities are to be considered, to some extent this is an open question. Regardless, computing quantities of interest, such as intersection theory and Chern classes, on singular spaces is challenging. However, it is possible to link the physics encoded by the singular geometry to the physics encoded by related smooth geometries. Consequently, almost all F-Theory studies begin by computing a smooting-out, i.e. a resolution, of the singular geometry in question.

In order to easily link the physics on the singular geometry to the physics of one of its resolution, the resolution in question must be crepant, i.e. must preserve the Calabi-Yau condition. However, this restriction to crepant resolutions introduces additional challenges:

  1. A crepant resolution cannot resolve all singularities, meaning certain singularities may persist. This is an area of interest in recent F-Theory investigations.
  2. The existence of a crepant resolution is not guaranteed.
  3. Exploring whether different resolutions provide insights into different aspects of the singular geometry poses further questions. However, just as it is unclear whether a single crepant resolution is known, there is currently no way to confirm that all crepant resolutions have been identified.

FTheoryTools may not (yet) answer these profound and fundamental questions. Instead, the goal of this suite of computer tools is to streamline and simplify the crepant singularity resolution process as much as possible, as well as the subsequent extraction of geometric features of the resolved space.

With FTheoryTools, you can create elliptic fibrations using one of the following models:

  • Weierstrass model,
  • Global Tate model,
  • Hypersurface model.

In each case, the base space can be a family of spaces (as used in the literature when an explicit base is not specified) or a toric space. We anticipate an extension to schemes as bases. The dimension of those bases is not limited to $1$, $2$, or $3$, but of course includes those cases important to the physics.

We also offer a database of models frequently studied in the literature. For those models we use the term 'literature_models.' In essence, you should be able to create a model described in a paper at the click of a button. We anticipate that this feature will greatly simplify future research in F-Theory.

Status

We anticipate the following workflow:

User Input:

  • Create your desired F-Theory model by using one of the methods described above.
  • Choose a resolved phase/crepant resolution.
  • Select generating sections for $\operatorname{U}(1)$ symmetries.

Output:

  • (Crepantly) resolved geometry.
  • Singular loci in suitable codimension (e.g., $1$, $2$, and $3$ if the base space has dimension $3$).
  • Fiber diagrams of the resolved fiber over the originally singular loci, including intersections of $\operatorname{U}(1)$-sections.
  • Gauge group.
  • Topological data (e.g., Euler number).

Currently, our primary focus is on the Elephant in the room, that is the crepant resolution. While already functional for numerous setups, especially literature models, it is far from complete. At this point, the largest functionality exists for toric cases, with ongoing work to extend those toric resolution techniques to families of spaces and schemes.

We are also actively expanding our database of supported literature models. At this point, amongst others, our database includes models from the following papers:

  • The Tate Form on Steroids: Resolution and Higher Codimension Fibers [LS13],
  • F-Theory on all Toric Hypersurface Fibrations and its Higgs Branches [KM-POPR15],
  • Quadrillion F-Theory Compactifications with the Exact Chiral Spectrum of the Standard Model [CHLLT19].

Consequently, we are already covering infinite families of models (e.g., with $SU(k)$ gauge group, where $k \geq 1$). Still, the total number of papers in our database is at this point limited to about $6$. This is to be extended a lot.

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č and Mohab Safey El Din. Martin Bies and Mikelis Mikelsons appreciate support by the TU-Nachwuchsring. The work of Andrew Turner is supported by DOE (HEP) Award DE-SC001352.

diff --git a/previews/PR4245/Experimental/FTheoryTools/literature/index.html b/previews/PR4245/Experimental/FTheoryTools/literature/index.html deleted file mode 100644 index af1831fefb26..000000000000 --- a/previews/PR4245/Experimental/FTheoryTools/literature/index.html +++ /dev/null @@ -1,486 +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. [Wei18] 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 = ambient_space(tm)
-A family of spaces of dimension d = 5
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source

More generally, we support literature constructions.

literature_modelMethod
literature_model(; doi::String="", arxiv_id::String="", version::String="", equation::String="", model_parameters::Dict{String,<:Any} = Dict{String,Any}(), base_space::FTheorySpace = affine_space(NormalToricVariety, 0), model_sections::Dict{String, <:Any} = Dict{String,Any}(), defining_classes::Dict{String, <:Any} = Dict{String,Any}(), completeness_check::Bool = true)

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 parameters can be provided using the optional argument model_parameters, which should be a dictionary such as Dict("k" => 5).

Further, some literature models require the specification of one or more divisor classes that define the model. This information can be provided using the optional argument defining_classes, which should be a dictionary such as Dict("w" => w), where w is a divisor, such as that provided by torusinvariant_prime_divisors.

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)
-A family of spaces of dimension d = 5
-
-julia> coordinate_ring(v)
-Multivariate polynomial ring in 8 variables w, a1, a21, a32, ..., z
-  over rational field

It is also possible to construct a literature model over a particular base. Currently, this feature is only supported for toric base spaces.

julia> B3 = projective_space(NormalToricVariety, 3)
-Normal toric variety
-
-julia> w = torusinvariant_prime_divisors(B3)[1]
-Torus-invariant, prime divisor on a normal toric variety
-
-julia> t2 = literature_model(arxiv_id = "1109.3454", equation = "3.1", base_space = B3, defining_classes = Dict("w" => w), completeness_check = false)
-Construction over concrete base may lead to singularity enhancement. Consider computing singular_loci. However, this may take time!
-
-Global Tate model over a concrete base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)
-
-julia> length(singular_loci(t2))
-2

Of course, this is also possible for Weierstrass models.

julia> B2 = projective_space(NormalToricVariety, 2)
-Normal toric variety
-
-julia> b = torusinvariant_prime_divisors(B2)[1]
-Torus-invariant, prime divisor on a normal toric variety
-
-julia> w = literature_model(arxiv_id = "1208.2695", equation = "B.19", base_space = B2, defining_classes = Dict("b" => b), completeness_check = false)
-Construction over concrete base may lead to singularity enhancement. Consider computing singular_loci. However, this may take time!
-
-Weierstrass model over a concrete base -- U(1) Weierstrass model based on arXiv paper 1208.2695 Eq. (B.19)
-
-julia> length(singular_loci(w))
-1

For convenience, we also support a simplified constructor. Instead of the meta data of the article, this constructor accepts an integer, which specifies the position of this model in our database.

julia> B2 = projective_space(NormalToricVariety, 2)
-Normal toric variety
-
-julia> b = torusinvariant_prime_divisors(B2)[1]
-Torus-invariant, prime divisor on a normal toric variety
-
-julia> w = literature_model(3, base_space = B2, defining_classes = Dict("b" => b), completeness_check = false)
-Construction over concrete base may lead to singularity enhancement. Consider computing singular_loci. However, this may take time!
-
-Weierstrass model over a concrete base -- U(1) Weierstrass model based on arXiv paper 1208.2695 Eq. (B.19)
-
-julia> length(singular_loci(w))
-1

Similarly, also hypersurface models are supported:

julia> h = literature_model(arxiv_id = "1208.2695", equation = "B.5")
-Assuming that the first row of the given grading is the grading under Kbar
-
-Hypersurface model over a not fully specified base
-
-julia> explicit_model_sections(h)
-Dict{String, MPolyRingElem} with 5 entries:
-  "c2" => c2
-  "c1" => c1
-  "c3" => c3
-  "b"  => b
-  "c0" => c0
-
-julia> B2 = projective_space(NormalToricVariety, 2)
-Normal toric variety
-
-julia> b = torusinvariant_prime_divisors(B2)[1]
-Torus-invariant, prime divisor on a normal toric variety
-
-julia> h2 = literature_model(arxiv_id = "1208.2695", equation = "B.5", base_space = B2, defining_classes = Dict("b" => b))
-Construction over concrete base may lead to singularity enhancement. Consider computing singular_loci. However, this may take time!
-
-Hypersurface model over a concrete base
-
-julia> hypersurface_equation_parametrization(h2)
-b*w*v^2 - c0*u^4 - c1*u^3*v - c2*u^2*v^2 - c3*u*v^3 + w^2

In principle, we can even create the model with the largest number of F-theory vacua. This happens by executing the line h = literature_model(arxiv_id = "1511.03209"). However, this line will currently run for a long time on a normal personal computer (likely about half an hour or even more), due to the massive complexity of computing the Tate sections of this global Tate model.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source

Attributes

For literature models, we provide the following attributes referencing meta data:

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"
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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"
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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"
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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"
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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"
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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"
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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"
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
associated_literature_modelsMethod
associated_literature_models(m::AbstractFTheoryModel)

Return a list of the unique identifiers of any associated_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 associated_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(11) Tate model with parameter values (k = 5) based on arXiv paper 1212.2949 Eq. (3.2)
-
-julia> associated_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"
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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{QQMPolyRingElem}}:
- [0, 0, 1]
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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"
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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"
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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"
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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"
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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"
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
journal_nameMethod
journal_name(m::AbstractFTheoryModel)

Return the journal_name of the published paper in which the given model was introduced. If no journal_name 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_name(m)
-"Nucl. Phys. B"
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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"
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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"
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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"
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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"
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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"
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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(11) 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
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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"
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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)"
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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"
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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"
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
birational_literature_modelsMethod
birational_literature_models(m::AbstractFTheoryModel)

Return a list of the unique identifiers of birational_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 birational_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> birational_literature_models(m)
-1-element Vector{String}:
- "1507_05954-1"
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source

Such meta data can be modified with setters. For instance, there is a function set_description(m::AbstractFTheoryModel, description::String), which takes the model in question as the first argument and the desired description - provided as string - as the second argument. Such a setter function exists for all of the above. If appropriate, we also offer a method that adds a new value. For instance, we have a function add_paper_buzzword(m::AbstractFTheoryModel, addition::String).

In addition, the following attributes are available to access advanced model information:

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"]]
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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{QQMPolyRingElem}}}}:
- [[[0, 0, 1], [0, 0, 1], [0, 1], [0, 1], [0, 1], [a32, -a43]]]
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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{QQMPolyRingElem}}}:
- [[1, 1, 0], [1, 1, w], [1, 1], [1, 1], [1, 1], [1, 1]]
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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"]]
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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{QQMPolyRingElem}}}}:
- [[[0, 0, 1], [0, 0, 1], [0, 0, 1], [0, 0, 1], [0, 0, 1], [a32, -a43]]]
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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{QQMPolyRingElem}}}:
- [[1, 1, 0], [1, 1, w], [1, 1, w], [1, 1, w], [1, 1, w], [1, 1]]
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source

One can 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_name(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_birational_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),
  • has_zero_section_coordinates(m::AbstractFTheoryModel),
  • has_gauge_algebra(m::AbstractFTheoryModel),
  • has_global_gauge_quotients(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
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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.

julia> B3 = projective_space(NormalToricVariety, 3)
-Normal toric variety
-
-julia> w = torusinvariant_prime_divisors(B3)[1]
-Torus-invariant, prime divisor on a normal toric variety
-
-julia> t = literature_model(arxiv_id = "1109.3454", equation = "3.1", base_space = B3, defining_classes = Dict("w" => w), completeness_check = false)
-Construction over concrete base may lead to singularity enhancement. Consider computing singular_loci. However, this may take time!
-
-Global Tate model over a concrete base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)
-
-julia> t2 = resolve(t, 1)
-Partially resolved global Tate model over a concrete base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)
-
-julia> cox_ring(ambient_space(t2))
-Multivariate polynomial ring in 12 variables over QQ graded by
-  x1 -> [1 0 0 0 0 0 0]
-  x2 -> [0 1 0 0 0 0 0]
-  x3 -> [0 1 0 0 0 0 0]
-  x4 -> [0 1 0 0 0 0 0]
-  x -> [0 0 1 0 0 0 0]
-  y -> [0 0 0 1 0 0 0]
-  z -> [0 0 0 0 1 0 0]
-  e1 -> [0 0 0 0 0 1 0]
-  e4 -> [0 0 0 0 0 0 1]
-  e2 -> [-1 -3 -1 1 -1 -1 0]
-  e3 -> [0 4 1 -1 1 0 -1]
-  s -> [2 6 -1 0 2 1 1]
-
-julia> w2 = 2 * torusinvariant_prime_divisors(B3)[1]
-Torus-invariant, non-prime divisor on a normal toric variety
-
-julia> t3 = literature_model(arxiv_id = "1109.3454", equation = "3.1", base_space = B3, defining_classes = Dict("w" => w2), completeness_check = false)
-Construction over concrete base may lead to singularity enhancement. Consider computing singular_loci. However, this may take time!
-
-Global Tate model over a concrete base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)
-
-julia> t4 = resolve(t3, 1)
-Partially resolved global Tate model over a concrete base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source

The Quadrillion F-Theory Standard Models

A yet more special instance of literature models are the Quadrillion F-theory Standard Models (F-theory QSMs) [CHLLT19]. Those hypersurface models come in 708 different families.

The base geometry of an F-theory QSM is obtained from triangulating one of 708 reflexive 3-dimensional polytopes. The models, whose bases are obtained from triangulations of the same polytope form a family. The following information on the polytope in question and its triangulations is available within our database:

verticesMethod
vertices(m::AbstractFTheoryModel)

This method returns the vertices of the polytope the the base of the F-theory QSM is build from. Note that those vertices are normalized according to the Polymake standard to rational numbers.

julia> qsm_model = literature_model(arxiv_id = "1903.00009", model_parameters = Dict("k" => 4))
-Hypersurface model over a concrete base
-
-julia> vertices(qsm_model)
-4-element Vector{Vector{QQFieldElem}}:
- [-1, -1, -1]
- [1, -1//2, -1//2]
- [-1, 2, -1]
- [-1, -1, 5]
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
polytope_indexMethod
polytope_index(m::AbstractFTheoryModel)

Of the 3-dimensional reflexive polytope that the base of this F-theory model is build from, this method returns the index within the Kreuzer-Skarke list.

julia> qsm_model = literature_model(arxiv_id = "1903.00009", model_parameters = Dict("k" => 4))
-Hypersurface model over a concrete base
-
-julia> polytope_index(qsm_model)
-4
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
has_quick_triangulationMethod
has_quick_triangulation(m::AbstractFTheoryModel)

For a 3-dimensional reflexive polytope in the Kreuzer-Skarke list, the list of full (sometimes also called fine), regular, star triangulations can be extremely large. Consequently, one may wonder if the triangulations can be enumerated in a somewhat reasonable time (say 5 minutes on a personal computer). This method tries to provide an answer to this. It returns true if one should expect a timly response to the atttempt to enumerate all (full, regular, star) triangulations. Otherwise, this method returns false.

julia> qsm_model = literature_model(arxiv_id = "1903.00009", model_parameters = Dict("k" => 4))
-Hypersurface model over a concrete base
-
-julia> has_quick_triangulation(qsm_model)
-true
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
max_lattice_pts_in_facetMethod
max_lattice_pts_in_facet(m::AbstractFTheoryModel)

In order to enumerate the number of full, regular, star triangulations of a 3-dimensional reflexive polytope, it is possible to first find the corresponding triangulations of all facets of the polytope [HT17]. A first indication for the complexity of this triangulation task is the maximum number of lattice points in a facet of the polytope in question. This method returns this maximal number of lattice points.

julia> qsm_model = literature_model(arxiv_id = "1903.00009", model_parameters = Dict("k" => 4))
-Hypersurface model over a concrete base
-
-julia> max_lattice_pts_in_facet(qsm_model)
-16
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
estimated_number_of_triangulationsMethod
estimated_number_of_triangulations(m::AbstractFTheoryModel)

This method returns an estimate for the number of full, regular, star triangulations of the 3-dimensional reflexive polytope, those triangulations define the possible base spaces of the F-theory QSM in question.

julia> qsm_model = literature_model(arxiv_id = "1903.00009", model_parameters = Dict("k" => 4))
-Hypersurface model over a concrete base
-
-julia> estimated_number_of_triangulations(qsm_model)
-212533333333
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source

Beyond the polytope and its triangulations, a number of other integers are of key importance. The following are supported in our database.

kbar3Method
kbar3(m::AbstractFTheoryModel)

Let Kbar denote the anticanonical class of the 3-dimensional base space of the F-theory QSM. Of ample importance is the triple intersection number of Kbar, i.e. Kbar * Kbar * Kbar. This method returns this intersection number.

julia> qsm_model = literature_model(arxiv_id = "1903.00009", model_parameters = Dict("k" => 4))
-Hypersurface model over a concrete base
-
-julia> kbar3(qsm_model)
-6
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
hodge_h11Method
hodge_h11(m::AbstractFTheoryModel)

This methods return the Hodge number h11 of the elliptically fibered 4-fold that defined the F-theory QSM in question.

julia> qsm_model = literature_model(arxiv_id = "1903.00009", model_parameters = Dict("k" => 4))
-Hypersurface model over a concrete base
-
-julia> hodge_h11(qsm_model)
-31
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
hodge_h12Method
hodge_h12(m::AbstractFTheoryModel)

This methods return the Hodge number h12 of the elliptically fibered 4-fold that defined the F-theory QSM in question.

julia> qsm_model = literature_model(arxiv_id = "1903.00009", model_parameters = Dict("k" => 4))
-Hypersurface model over a concrete base
-
-julia> hodge_h12(qsm_model)
-10
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
hodge_h13Method
hodge_h13(m::AbstractFTheoryModel)

This methods return the Hodge number h13 of the elliptically fibered 4-fold that defined the F-theory QSM in question.

julia> qsm_model = literature_model(arxiv_id = "1903.00009", model_parameters = Dict("k" => 4))
-Hypersurface model over a concrete base
-
-julia> hodge_h13(qsm_model)
-34
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
hodge_h22Method
hodge_h22(m::AbstractFTheoryModel)

This methods return the Hodge number h22 of the elliptically fibered 4-fold that defined the F-theory QSM in question.

julia> qsm_model = literature_model(arxiv_id = "1903.00009", model_parameters = Dict("k" => 4))
-Hypersurface model over a concrete base
-
-julia> hodge_h22(qsm_model)
-284
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source

More recently, a research program estimated the exact massless spectra of the F-theory QSMs (cf. [Bie24]). These studies require yet more information about the F-theory QSM geometries, which are supported by our database.

First, recall that (currently), the base of an F-theory QSM is a 3-dimensional toric variety B3. Let s in H^0(B3, Kbar_B3), then V(s) is a K3-surface. Moreover, let xi be the coordinates of the Cox ring of B3. Then V(xi) is a divisor in B3. Consequently, Ci = V(xi) cap V(s) is a divisor in the K3-surface V(s). For the root bundle counting program, these curves Ci are of ample importance (cf. [Bie24]). We support the following information on these curves:

genera_of_ci_curvesMethod
genera_of_ci_curves(m::AbstractFTheoryModel)

This methods return the genera of the Ci curves. Recall that Ci = V(xi, s), where xi is a homogeneous coordinate of the 3-dimensional toric base space B3 of the QSM hypersurface model in question, and s is a generic section of the anticanonical bundle of B3. Consequently, we may use the coordinates xi as labels for the curves Ci.

julia> qsm_model = literature_model(arxiv_id = "1903.00009", model_parameters = Dict("k" => 4))
-Hypersurface model over a concrete base
-
-julia> my_key = collect(keys(genera_of_ci_curves(qsm_model)))[1]
-x7
-
-julia> genera_of_ci_curves(qsm_model)[my_key]
-0
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
degrees_of_kbar_restrictions_to_ci_curvesMethod
degrees_of_kbar_restrictions_to_ci_curves(m::AbstractFTheoryModel)

The anticanonical divisor of the 3-dimensional toric base space B3 of the QSM hypersurface model in question can be restricted to the Ci curves. The result of this operation is a line bundle. This method returns the degree of this line bundle for every Ci curve.

julia> qsm_model = literature_model(arxiv_id = "1903.00009", model_parameters = Dict("k" => 4))
-Hypersurface model over a concrete base
-
-julia> my_key = collect(keys(degrees_of_kbar_restrictions_to_ci_curves(qsm_model)))[1]
-x7
-
-julia> degrees_of_kbar_restrictions_to_ci_curves(qsm_model)[my_key]
-0
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
topological_intersection_numbers_among_ci_curvesMethod
topological_intersection_numbers_among_ci_curves(m::AbstractFTheoryModel)

The topological intersection numbers among Ci curves are also of ample importance. This method returns those intersection numbers in the form of a matrix.

julia> qsm_model = literature_model(arxiv_id = "1903.00009", model_parameters = Dict("k" => 4))
-Hypersurface model over a concrete base
-
-julia> n_rows(topological_intersection_numbers_among_ci_curves(qsm_model))
-29
-
-julia> n_columns(topological_intersection_numbers_among_ci_curves(qsm_model))
-29
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
indices_of_trivial_ci_curvesMethod
indices_of_trivial_ci_curves(m::AbstractFTheoryModel)

Some of the Ci curves are trivial, in that V(xi, s) is the empty set. This method returns the vector of all indices of trivial Ci curves. That is, should V(x23, s) be the empty set, then 23 will be included in the returned list.

julia> qsm_model = literature_model(arxiv_id = "1903.00009", model_parameters = Dict("k" => 4))
-Hypersurface model over a concrete base
-
-julia> indices_of_trivial_ci_curves(qsm_model)
-10-element Vector{Int64}:
- 23
- 22
- 18
- 19
- 20
- 26
- 10
- 11
- 12
- 15
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
topological_intersection_numbers_among_nontrivial_ci_curvesMethod
topological_intersection_numbers_among_nontrivial_ci_curves(m::AbstractFTheoryModel)

The topological intersection numbers among the non-trivial Ci curves are used frequently. This method returns those intersection numbers in the form of a matrix.

julia> qsm_model = literature_model(arxiv_id = "1903.00009", model_parameters = Dict("k" => 4))
-Hypersurface model over a concrete base
-
-julia> n_rows(topological_intersection_numbers_among_nontrivial_ci_curves(qsm_model))
-19
-
-julia> n_columns(topological_intersection_numbers_among_nontrivial_ci_curves(qsm_model))
-19
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source

The collection of the Ci-curves form a nodal curve. To every nodal curve one can associate a (dual) graph. In this graph, every irreducible component of the nodal curve becomes a node/vertex of the dual graph, and every nodal singularity of the nodal curve turns into an edge of the dual graph. In the case at hand, this is rather simple.

The Ci-curves turn into the irreducible components of the nodel curve. Certainly, we only need to focus on the non-trivial Ci-curves. A non-trivial Ci-curve can split into multiple irreducible components. This is taken into acccount when the nodes/vertices of the dual graph are constructed.

The topological intersection numbers among the Ci-curves (or rather, their irreducible components) tells us how many nodal singularities link the Ci-curves (or rather, their irreducible components) in question. Hence, if the topological intersection numbers is zero, there is no edge between the corresponding nodes. Otherwise, if the topological intersection number is positive - say n -, then there are exactly n edges between the nodes in question.

The following functions access/create the so-obtained dual graph:

dual_graphMethod
dual_graph(m::AbstractFTheoryModel)

This method returns the dual graph of the QSM model in question. Note that no labels are (currently) attached to the vertices/nodes or edges. To understand/read this graph correctly, please use the methods listed below.

julia> qsm_model = literature_model(arxiv_id = "1903.00009", model_parameters = Dict("k" => 4))
-Hypersurface model over a concrete base
-
-julia> dual_graph(qsm_model)
-Undirected graph with 21 nodes and the following edges:
-(5, 1)(6, 5)(7, 6)(8, 7)(9, 4)(9, 8)(10, 1)(11, 4)(12, 3)(12, 10)(13, 3)(13, 11)(14, 1)(15, 4)(16, 3)(17, 3)(18, 2)(18, 14)(19, 2)(19, 15)(20, 2)(20, 16)(21, 2)(21, 17)
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
components_of_dual_graphMethod
components_of_dual_graph(m::AbstractFTheoryModel)

This method returns a vector with labels for each node/vertex of the dual graph of the QSM model in question. Those labels allow to understand the geometric origin of the node/vertex.

Specifically, recall that those nodes are associated to the Ci-curves, which are in turn given by Ci = V(xi, s). xi is a homogenous coordinate of the 3-dimensional toric base space B3 of the QSM in question, and s is a generic section of the anticanonical bundle of B3.

Only non-trivial Ci = V(xi, s) correspond to vertices/nodes of the dual graph.

If Ci = V(xi, s) is irreducible and corresponds to the k-th component, then the label "Ci" appears at position k of the vector returned by this method. However, if Ci = V(xi, s) is reducible, then we introduce the labels Ci-0, Ci-1, Ci-2 etc. for those irreducible components of Ci. If Ci-0 corresponds to the k-th components of the dual graph, then the label "Ci-0" appears at position k of the vector returned by this method.

julia> qsm_model = literature_model(arxiv_id = "1903.00009", model_parameters = Dict("k" => 4))
-Hypersurface model over a concrete base
-
-julia> components_of_dual_graph(qsm_model)
-21-element Vector{String}:
- "C0"
- "C1"
- "C2"
- "C3"
- "C4"
- "C5"
- "C6"
- "C7"
- "C8"
- "C9"
- ⋮
- "C16"
- "C17"
- "C21"
- "C24-0"
- "C24-1"
- "C25"
- "C27"
- "C28-0"
- "C28-1"
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
degrees_of_kbar_restrictions_to_components_of_dual_graphMethod
degrees_of_kbar_restrictions_to_components_of_dual_graph(m::AbstractFTheoryModel)

The anticanonical bundle of the toric 3-dimensional base space of the F-theory QSM in question can be restricted to the (geometric counterparts of the) nodes/vertices of the dual graph. The result is a line bundle for each node/vertex. This method returns a vector with the degrees of these line bundles.

julia> qsm_model = literature_model(arxiv_id = "1903.00009", model_parameters = Dict("k" => 4))
-Hypersurface model over a concrete base
-
-julia> degrees_of_kbar_restrictions_to_components_of_dual_graph(qsm_model)["C28-1"]
-0
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
genera_of_components_of_dual_graphMethod
genera_of_components_of_dual_graph(m::AbstractFTheoryModel)

This methods returns a vector with the genera of the (geometric counterparts of the) nodes/vertices of the dual graph.

julia> qsm_model = literature_model(arxiv_id = "1903.00009", model_parameters = Dict("k" => 4))
-Hypersurface model over a concrete base
-
-julia> genera_of_components_of_dual_graph(qsm_model)["C28-1"]
-0
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source

The dual graph is essential in counting root bundles (cf. [BCL21]). It turns out, that one can simplify this graph so that the computations at hand can be conducted on a simpler graph instead. The following functionality exists to access this simplified dual graph.

simplified_dual_graphMethod
simplified_dual_graph(m::AbstractFTheoryModel)

This method returns the simplified dual graph of the QSM model in question. Note that no labels are (currently) attached to the vertices/nodes or edges. To understand/read this graph correctly, please use the methods listed below.

julia> qsm_model = literature_model(arxiv_id = "1903.00009", model_parameters = Dict("k" => 4))
-Hypersurface model over a concrete base
-
-julia> simplified_dual_graph(qsm_model)
-Undirected graph with 4 nodes and the following edges:
-(2, 1)(3, 1)(3, 2)(4, 1)(4, 2)(4, 3)
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
components_of_simplified_dual_graphMethod
components_of_simplified_dual_graph(m::AbstractFTheoryModel)

This method returns a vector with labels for each node/vertex of the simplified dual graph. Otherwise, works identical to components_of_dual_graph(m::AbstractFTheoryModel).

julia> qsm_model = literature_model(arxiv_id = "1903.00009", model_parameters = Dict("k" => 4))
-Hypersurface model over a concrete base
-
-julia> components_of_simplified_dual_graph(qsm_model)
-4-element Vector{String}:
- "C0"
- "C1"
- "C2"
- "C3"
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
degrees_of_kbar_restrictions_to_components_of_simplified_dual_graphMethod
degrees_of_kbar_restrictions_to_components_of_simplified_dual_graph(m::AbstractFTheoryModel)

Same as degrees_of_kbar_restrictions_to_components_of_dual_graph(m::AbstractFTheoryModel), but for the simplified dual graph.

julia> qsm_model = literature_model(arxiv_id = "1903.00009", model_parameters = Dict("k" => 4))
-Hypersurface model over a concrete base
-
-julia> degrees_of_kbar_restrictions_to_components_of_simplified_dual_graph(qsm_model)["C2"]
-2
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
genera_of_components_of_simplified_dual_graphMethod
genera_of_components_of_simplified_dual_graph(m::AbstractFTheoryModel)

This methods returns a vector with the genera of the (geometric counterparts of the) nodes/vertices of the dual graph.

julia> qsm_model = literature_model(arxiv_id = "1903.00009", model_parameters = Dict("k" => 4))
-Hypersurface model over a concrete base
-
-julia> genera_of_components_of_simplified_dual_graph(qsm_model)["C2"]
-0
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
diff --git a/previews/PR4245/Experimental/FTheoryTools/tate/index.html b/previews/PR4245/Experimental/FTheoryTools/tate/index.html deleted file mode 100644 index 53d7f9a4c6df..000000000000 --- a/previews/PR4245/Experimental/FTheoryTools/tate/index.html +++ /dev/null @@ -1,213 +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 [Wei10]–-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::NormalToricVariety; 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
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
global_tate_modelMethod
global_tate_model(base::NormalToricVariety, ais::Vector{T}; completeness_check::Bool = true) where {T<:MPolyRingElem}

This method operates analogously to global_tate_model(base::NormalToricVarietyType). 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 = generic_section(anticanonical_bundle(base));
-
-julia> a2 = generic_section(anticanonical_bundle(base)^2);
-
-julia> a3 = generic_section(anticanonical_bundle(base)^3);
-
-julia> a4 = generic_section(anticanonical_bundle(base)^4);
-
-julia> a6 = generic_section(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
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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 serves as coordinate ring for the family of base spaces. 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 code 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
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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)
-w*a21
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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)
-w^2*a32
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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)
-w^3*a43
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
tate_polynomialMethod
tate_polynomial(t::GlobalTateModel)

Return the Tate polynomial of the global Tate model.

For convenience and uniformity with (general) hypersurface models, we also support the method hypersurface_equation to access the Tate polynomial.

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)
-w^3*a43*x*z^4 - w^2*a32*y*z^3 + w*a21*x^2*z^2 - a1*x*y*z + x^3 - y^2
-
-julia> tate_polynomial(t) == hypersurface_equation(t)
-true
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
tate_ideal_sheafMethod
tate_ideal_sheaf(t::GlobalTateModel)

Return the Tate ideal sheaf of the global Tate model.

julia> B3 = projective_space(NormalToricVariety, 3)
-Normal toric variety
-
-julia> w = 2 * torusinvariant_prime_divisors(B3)[1]
-Torus-invariant, non-prime divisor on a normal toric variety
-
-julia> t = literature_model(arxiv_id = "1109.3454", equation = "3.1", base_space = B3, defining_classes = Dict("w" => w), completeness_check = false)
-Construction over concrete base may lead to singularity enhancement. Consider computing singular_loci. However, this may take time!
-
-Global Tate model over a concrete base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)
-
-julia> tate_ideal_sheaf(t)
-Sheaf of ideals
-  on normal, simplicial toric variety
-with restrictions
-   1: Ideal with 1 generator
-   2: Ideal with 1 generator
-   3: Ideal with 1 generator
-   4: Ideal with 1 generator
-   5: Ideal with 3 generators
-   6: Ideal with 3 generators
-   7: Ideal with 3 generators
-   8: Ideal with 3 generators
-   9: Ideal with 4 generators
-  10: Ideal with 4 generators
-  11: Ideal with 4 generators
-  12: Ideal with 4 generators
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source

The base space can be obtained with base_space, the ambient space with ambient_space and the fiber ambient space with fiber_ambient_space. Recall that is_base_space_fully_specified will tell if the model has been constructed over a concrete space (in which case the function returns true) or a family of spaces (returning false).

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 = global_tate_model(sample_toric_variety(); completeness_check = false)
-Global Tate model over a concrete base
-
-julia> calabi_yau_hypersurface(t)
-Closed subvariety of a normal toric variety
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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 -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source

Note that for applications in F-theory, singular elliptic fibrations are key (cf. [Wei18] 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);
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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 [CLS11], $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 [KMSS11]. 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")
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source

Methods

Blowup

We can blow up a global Tate model with the blow_up function. The resulting model will thereafter be partially resolved. No checks are currently implemented to test if a model is completely resolved. However, is_partially_resolved will return true if a blowup has been applied to the model in question.

Tuning

Often, one wishes to tune an existing model, e.g. in an attempt to engineer a larger gauge group. We support the following functionality:

tuneMethod
tune(t::GlobalTateModel, input_sections::Dict{String, <:Any}; completeness_check::Bool = true)

Tune a Tate model by fixing a special choice for the model sections. Note that it is in particular possible to set a section to zero. We anticipate that people might want to be able to come back from this by assigning a non-trivial value to a section that was previously tuned to zero. This is why we keep such trivial sections and do not delete them, say from explicit_model_sections or classes_of_model_sections.

Examples

julia> B3 = projective_space(NormalToricVariety, 3)
-Normal toric variety
-
-julia> w = torusinvariant_prime_divisors(B3)[1]
-Torus-invariant, prime divisor on a normal toric variety
-
-julia> t = literature_model(arxiv_id = "1109.3454", equation = "3.1", base_space = B3, defining_classes = Dict("w" => w), completeness_check = false)
-Construction over concrete base may lead to singularity enhancement. Consider computing singular_loci. However, this may take time!
-
-Global Tate model over a concrete base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)
-
-julia> x1, x2, x3, x4 = gens(cox_ring(base_space(t)))
-4-element Vector{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}:
- x1
- x2
- x3
- x4
-
-julia> my_choice = Dict("a1" => x1^4, "a2" => x1^8, "w" => x2 - x3)
-Dict{String, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}} with 3 entries:
-  "w"  => x2 - x3
-  "a2" => x1^8
-  "a1" => x1^4
-
-julia> tuned_t = tune(t, my_choice)
-Global Tate model over a concrete base
-
-julia> tate_section_a1(tuned_t) == x1^4
-true
-
-julia> x1, x2, x3, x4 = gens(cox_ring(base_space(tuned_t)))
-4-element Vector{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}:
- x1
- x2
- x3
- x4
-
-julia> my_choice2 = Dict("a1" => x1^4, "a2" => zero(parent(x1)), "w" => x2 - x3)
-Dict{String, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}} with 3 entries:
-  "w"  => x2 - x3
-  "a2" => 0
-  "a1" => x1^4
-
-julia> tuned_t2 = tune(tuned_t, my_choice2)
-Global Tate model over a concrete base
-
-julia> is_zero(explicit_model_sections(tuned_t2)["a2"])
-true
-
-julia> x1, x2, x3, x4 = gens(cox_ring(base_space(tuned_t2)))
-4-element Vector{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}:
- x1
- x2
- x3
- x4
-
-julia> my_choice3 = Dict("a1" => x1^4, "a2" => x1^8, "w" => x2 - x3)
-Dict{String, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}} with 3 entries:
-  "w"  => x2 - x3
-  "a2" => x1^8
-  "a1" => x1^4
-
-julia> tuned_t3 = tune(tuned_t2, my_choice3)
-Global Tate model over a concrete base
-
-julia> is_zero(explicit_model_sections(tuned_t3)["a2"])
-false
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source

See also the tune function described in Functionality for all F-theory models.

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. ```

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
diff --git a/previews/PR4245/Experimental/FTheoryTools/weierstrass/index.html b/previews/PR4245/Experimental/FTheoryTools/weierstrass/index.html deleted file mode 100644 index 11277527d0d2..000000000000 --- a/previews/PR4245/Experimental/FTheoryTools/weierstrass/index.html +++ /dev/null @@ -1,152 +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 [Wei18] 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::NormalToricVariety; 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
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
weierstrass_modelMethod
weierstrass_model(base::NormalToricVariety, f::MPolyRingElem, g::MPolyRingElem; completeness_check::Bool = true)

This method operates analogously to weierstrass_model(base::NormalToricVarietyType). 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 = generic_section(anticanonical_bundle(base)^4);
-
-julia> g = generic_section(anticanonical_bundle(base)^6);
-
-julia> w = weierstrass_model(base, f, g; completeness_check = false)
-Weierstrass model over a concrete base
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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 serves as the coordinate ring of a family of base spaces. 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
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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. [Wei18] 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
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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);
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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);
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
weierstrass_polynomialMethod
weierstrass_polynomial(w::WeierstrassModel)

Return the Weierstrass polynomial of the Weierstrass model.

For convenience and uniformity with (general) hypersurface models, we also support the method hypersurface_equation to access the Weierstrass polynomial.

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);
-
-julia> weierstrass_polynomial(w) == hypersurface_equation(w)
-true
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
weierstrass_ideal_sheafMethod
weierstrass_ideal_sheaf(w::WeierstrassModel)

Return the Weierstrass ideal sheaf of the Weierstrass model.

julia> B3 = projective_space(NormalToricVariety, 3)
-Normal toric variety
-
-julia> w = 2 * torusinvariant_prime_divisors(B3)[1]
-Torus-invariant, non-prime divisor on a normal toric variety
-
-julia> t = literature_model(arxiv_id = "1109.3454", equation = "3.1", base_space = B3, defining_classes = Dict("w" => w), completeness_check = false)
-Construction over concrete base may lead to singularity enhancement. Consider computing singular_loci. However, this may take time!
-
-Global Tate model over a concrete base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)
-
-julia> w = weierstrass_model(t)
-Weierstrass model over a concrete base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)
-
-julia> weierstrass_ideal_sheaf(w)
-Sheaf of ideals
-  on normal, simplicial toric variety
-with restrictions
-   1: Ideal with 1 generator
-   2: Ideal with 1 generator
-   3: Ideal with 1 generator
-   4: Ideal with 1 generator
-   5: Ideal with 2 generators
-   6: Ideal with 2 generators
-   7: Ideal with 2 generators
-   8: Ideal with 2 generators
-   9: Ideal with 5 generators
-  10: Ideal with 5 generators
-  11: Ideal with 5 generators
-  12: Ideal with 5 generators
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source

The base space can be obtained with base_space, the ambient space with ambient_space and the fiber ambient space with fiber_ambient_space. Recall that is_base_space_fully_specified will tell if the model has been constructed over a concrete space (in which case the function returns true) or a family of spaces (returning false).

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 = weierstrass_model(sample_toric_variety(); completeness_check = false)
-Weierstrass model over a concrete base
-
-julia> calabi_yau_hypersurface(w)
-Closed subvariety of a normal toric variety
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source

Note that for applications in F-theory, singular elliptic fibrations are key (cf. [Wei18] 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);
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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 [CLS11], $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
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source

Methods

Blowup

We can blow up a Weierstrass model with the blow_up function. The resulting model will thereafter be partially resolved. No checks are currently implemented to test if a model is completely resolved. However, is_partially_resolved will return true if a blowup has been applied to the model in question.

Tuning

Often, one wishes to tune an existing model, e.g. in an attempt to engineer a larger gauge group. We support the following functionality:

tuneMethod
function tune(w::WeierstrassModel, input_sections::Dict{String, <:Any}; completeness_check::Bool = true)

Tune a Weierstrass model by fixing a special choice for the model sections. Note that it is in particular possible to set a section to zero. We anticipate that people might want to be able to come back from this by assigning a non-trivial value to a section that was previously tuned to zero. This is why we keep such trivial sections and do not delete them, say from explicit_model_sections or classes_of_model_sections.

Examples

julia> B2 = projective_space(NormalToricVariety, 2)
-Normal toric variety
-
-julia> b = torusinvariant_prime_divisors(B2)[1]
-Torus-invariant, prime divisor on a normal toric variety
-
-julia> w = literature_model(arxiv_id = "1208.2695", equation = "B.19", base_space = B2, defining_classes = Dict("b" => b), completeness_check = false)
-Construction over concrete base may lead to singularity enhancement. Consider computing singular_loci. However, this may take time!
-
-Weierstrass model over a concrete base -- U(1) Weierstrass model based on arXiv paper 1208.2695 Eq. (B.19)
-
-julia> x1, x2, x3 = gens(cox_ring(base_space(w)))
-3-element Vector{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}:
- x1
- x2
- x3
-
-julia> my_choice = Dict("f" => x1^12, "b" => x2, "c2" => x1^6)
-Dict{String, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}} with 3 entries:
-  "c2" => x1^6
-  "f"  => x1^12
-  "b"  => x2
-
-julia> tuned_w = tune(w, my_choice)
-Weierstrass model over a concrete base
-
-julia> weierstrass_section_f(tuned_w) == my_choice["f"]
-true
-
-julia> x1, x2, x3 = gens(cox_ring(base_space(tuned_w)))
-3-element Vector{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}:
- x1
- x2
- x3
-
-julia> my_choice2 = Dict("f" => x1^12, "b" => x2, "c2" => zero(parent(x1)))
-Dict{String, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}} with 3 entries:
-  "c2" => 0
-  "f"  => x1^12
-  "b"  => x2
-
-julia> tuned_w2 = tune(tuned_w, my_choice2)
-Weierstrass model over a concrete base
-
-julia> is_zero(explicit_model_sections(tuned_w2)["c2"])
-true
-
-julia> x1, x2, x3 = gens(cox_ring(base_space(tuned_w2)))
-3-element Vector{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}:
- x1
- x2
- x3
-
-julia> my_choice3 = Dict("f" => x1^12, "b" => x2, "c2" => x1^6)
-Dict{String, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}} with 3 entries:
-  "c2" => x1^6
-  "f"  => x1^12
-  "b"  => x2
-
-julia> tuned_w3 = tune(tuned_w2, my_choice3)
-Weierstrass model over a concrete base
-
-julia> is_zero(explicit_model_sections(tuned_w3)["c2"])
-false
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source

See also the tune function described in Functionality for all F-theory models.

diff --git a/previews/PR4245/Experimental/GroebnerWalk/introduction/index.html b/previews/PR4245/Experimental/GroebnerWalk/introduction/index.html deleted file mode 100644 index 737914092174..000000000000 --- a/previews/PR4245/Experimental/GroebnerWalk/introduction/index.html +++ /dev/null @@ -1,41 +0,0 @@ - -Usage · Oscar.jl

Usage

The Gröbner walk is an approach to reduce the computational complexity of Gröbner basis computations as proposed by [AGK97]. These incarnations of the Gröbner walk refer to a family of algorithms that perform a reverse local search on the cones of the Gröbner fan. Then, a Gröbner basis is calculated for each encountered cone while reusing the generators obtained from the previous cone.

The implemented algorithms may be accessed using the following function.

groebner_walkFunction
groebner_walk(
-  I::MPolyIdeal, 
-  target::MonomialOrdering = lex(base_ring(I)),
-  start::MonomialOrdering = default_ordering(base_ring(I));
-  perturbation_degree = ngens(base_ring(I)),
-  algorithm::Symbol = :standard
-)

Compute a reduced Groebner basis w.r.t. to the monomial ordering target by converting it from a Groebner basis with respect to the ordering start using the Groebner Walk.

Arguments

  • I::MPolyIdeal: ideal one wants to compute a Groebner basis for.
  • target::MonomialOrdering=:lex: monomial ordering one wants to compute a Groebner basis for.
  • start::MonomialOrdering=:degrevlex: monomial ordering to begin the conversion.
  • perturbationDegree::Int=2: the perturbation degree for the perturbed Walk.
  • algorithm::Symbol=:standard: strategy of the Groebner Walk. One can choose between:
    • standard: Standard Walk [CLO05],
    • generic: Generic Walk [FJLT07],
    • perturbed: Perturbed Walk [AGK96].

Examples

julia> R,(x,y) = polynomial_ring(QQ, [:x,:y]);
-
-julia> I = ideal([y^4+ x^3-x^2+x,x^4]);
-
-julia> groebner_walk(I, lex(R))
-Gröbner basis with elements
-  1 -> x + y^12 - y^8 + y^4
-  2 -> y^16
-with respect to the ordering
-  lex([x, y])
-
-julia> groebner_walk(I, lex(R); algorithm=:generic)
-Gröbner basis with elements
-  1 -> y^16
-  2 -> x + y^12 - y^8 + y^4
-with respect to the ordering
-  lex([x, y])
-
-julia> set_verbosity_level(:groebner_walk, 1);
-
-julia> groebner_walk(I, lex(R))
-Results for standard_walk
-Crossed Cones in: 
-ZZRingElem[1, 1]
-ZZRingElem[4, 3]
-ZZRingElem[4, 1]
-ZZRingElem[12, 1]
-Cones crossed: 4
-Gröbner basis with elements
-  1 -> x + y^12 - y^8 + y^4
-  2 -> y^16
-with respect to the ordering
-  lex([x, y])
-
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
diff --git a/previews/PR4245/Experimental/GroebnerWalk/special-ideals/index.html b/previews/PR4245/Experimental/GroebnerWalk/special-ideals/index.html deleted file mode 100644 index 28663b36720a..000000000000 --- a/previews/PR4245/Experimental/GroebnerWalk/special-ideals/index.html +++ /dev/null @@ -1,2 +0,0 @@ - -Special ideals used for benchmarking · Oscar.jl

Special ideals used for benchmarking

We bundle a couple of special ideals useful for benchmarking of the Gröbner walk.

newell_patchFunction
newell_patch(k::Union{QQField, QQBarFieldElem}, n::Int=1)

Let $n$ be an integer between 1 and 32. Returns the ideal corresponding to the implicitization of the $n$-th bi-cubic patch describing the Newell's teapot as a parametric surface.

The specific generators for each patch have been taken from [Tra04].

source
newell_patchFunction
newell_patch(k::Field, n::Int=1)

Let $n$ be an integer between 1 and 32. Returns the ideal corresponding to the implicitization of the $n$-th bi-cubic patch describing the Newell's teapot as a parametric surface.

The specific generators for each patch have been taken from [Tra04].

For fields $k\neq\mathbb{Q},\bar{\mathbb{Q}}$, this gives a variant of the ideal with integer coefficients.

source
newell_patch_with_orderingsFunction
newell_patch_with_orderings(k::Field, n::Int=1)

Let $n$ be an integer between 1 and 32. Returns the ideal corresponding to the implicitization of the $n$-th bi-cubic patch describing the Newell's teapot as a parametric surface. Additionally returns suitable start and target orderings, e.g. for use with the Gröbner walk.

The specific generators for each patch have been taken from [Tra04].

For fields $k\neq\mathbb{Q},\bar{\mathbb{Q}}$, this gives a variant of the ideal with integer coefficients.

source
diff --git a/previews/PR4245/Experimental/IntersectionTheory/AbstractBundles/index.html b/previews/PR4245/Experimental/IntersectionTheory/AbstractBundles/index.html deleted file mode 100644 index 81ce05820eee..000000000000 --- a/previews/PR4245/Experimental/IntersectionTheory/AbstractBundles/index.html +++ /dev/null @@ -1,176 +0,0 @@ - -Abstract Bundles · Oscar.jl

Abstract Bundles

Constructors

abstract_bundleMethod
abstract_bundle(X::AbstractVariety, ch::Union{MPolyDecRingElem, MPolyQuoRingElem})
-abstract_bundle(X::AbstractVariety, r::RingElement, c::Union{MPolyDecRingElem, MPolyQuoRingElem})

Return an abstract vector bundle on X by specifying its Chern character. Equivalently, specify its rank and total Chern class.

Examples

We show two ways of constructing the Horrocks-Mumford bundle F [HM73]. First, we create F as the cohomology bundle of its Beilinson monad

\[0 \rightarrow \mathcal O_{\mathbb P^4} ^5(2)\rightarrow \Lambda^2 T^*_{\mathbb P^4}(5) -\rightarrow \mathcal O_{\mathbb P^4}^5(3)\rightarrow 0.\]

Then, we show the constructor above at work.

julia> P4 = abstract_projective_space(4)
-AbstractVariety of dim 4
-
-julia> A = 5*OO(P4, 2)
-AbstractBundle of rank 5 on AbstractVariety of dim 4
-
-julia> B = 2*exterior_power(cotangent_bundle(P4), 2)*OO(P4, 5)
-AbstractBundle of rank 12 on AbstractVariety of dim 4
-
-julia> C = 5*OO(P4, 3)
-AbstractBundle of rank 5 on AbstractVariety of dim 4
-
-julia> F = B-A-C
-AbstractBundle of rank 2 on AbstractVariety of dim 4
-
-julia> total_chern_class(F)
-10*h^2 + 5*h + 1
-
-julia> h = gens(P4)[1]
-h
-
-julia> F == abstract_bundle(P4, 2, 10*h^2 + 5*h + 1)
-true
-
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source

Underlying Data of an Abstract Bundle

parentMethod
 parent(F::AbstractBundle)

Return the underlying abstract variety of F.

Examples

julia> G = abstract_grassmannian(3,5)
-AbstractVariety of dim 6
-
-julia> Q = tautological_bundles(G)[2]
-AbstractBundle of rank 2 on AbstractVariety of dim 6
-
-julia> parent(Q) == G
-true
-
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
rankMethod
 rank(F::AbstractBundle)

Return the rank of F.

Examples

julia> G = abstract_grassmannian(3,5)
-AbstractVariety of dim 6
-
-julia> Q = tautological_bundles(G)[2]
-AbstractBundle of rank 2 on AbstractVariety of dim 6
-
-julia> rank(symmetric_power(Q,3))
-4
-
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
chern_characterMethod
chern_character(F::AbstractBundle)

Return the Chern character of F.

Examples

julia> G = abstract_grassmannian(3,5)
-AbstractVariety of dim 6
-
-julia> Q = tautological_bundles(G)[2]
-AbstractBundle of rank 2 on AbstractVariety of dim 6
-
-julia> chern_character(Q)
--1//2*c[1]^2 + 1//6*c[1]*c[2] - 1//24*c[1]*c[3] - c[1] + c[2] - 1//3*c[3] + 2
-
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
total_chern_classMethod
total_chern_class(F::AbstractBundle)

Return the total Chern class of F.

Examples

julia> G = abstract_grassmannian(3,5)
-AbstractVariety of dim 6
-
-julia> Q = tautological_bundles(G)[2]
-AbstractBundle of rank 2 on AbstractVariety of dim 6
-
-julia> total_chern_class(Q)
-c[1]^2 - c[1] - c[2] + 1
-
-julia> chern_class(Q, 1)
--c[1]
-
-julia> chern_class(Q, 2)
-c[1]^2 - c[2]
-
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source

Further Data Associated to an Abstract Bundle

chern_classMethod
chern_class(F::AbstractBundle, k::Int)

Return the k-th Chern class of F.

Examples

julia> T, (d,) = polynomial_ring(QQ, [:d])
-(Multivariate polynomial ring in 1 variable over QQ, QQMPolyRingElem[d])
-
-julia> QT = fraction_field(T)
-Fraction field
-  of multivariate polynomial ring in 1 variable over QQ
-
-julia> P4 = abstract_projective_space(4, base = QT)
-AbstractVariety of dim 4
-
-julia> h = gens(P4)[1]
-h
-
-julia> F = abstract_bundle(P4, 2, 10*h^2 + 5*h + 1) # Horrocks-Mumford bundle
-AbstractBundle of rank 2 on AbstractVariety of dim 4
-
-julia> chern_class(F*OO(P4, d), 1)
-(2*d + 5)*h
-
-julia> chern_class(F*OO(P4, d), 2)
-(d^2 + 5*d + 10)*h^2
-
-julia> chern_class(F*OO(P4, -3), 1)
--h
-
-julia> chern_class(F*OO(P4, -3), 2)
-4*h^2
-
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
top_chern_classMethod
top_chern_class(F::AbstractBundle)

Return the top Chern class of F.

Examples

julia> P4 = abstract_projective_space(4)
-AbstractVariety of dim 4
-
-julia> h = gens(P4)[1]
-h
-
-julia> F = abstract_bundle(P4, 2, 10*h^2 + 5*h + 1)
-AbstractBundle of rank 2 on AbstractVariety of dim 4
-
-julia> top_chern_class(F)
-10*h^2
-
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
total_segre_classMethod
total_segre_class(F::AbstractBundle)

Return the total Segre class of F.

Examples

julia> G = abstract_grassmannian(3,5)
-AbstractVariety of dim 6
-
-julia> Q = tautological_bundles(G)[2]
-AbstractBundle of rank 2 on AbstractVariety of dim 6
-
-julia> C = total_chern_class(Q)
-c[1]^2 - c[1] - c[2] + 1
-
-julia> S = total_segre_class(Q)
-c[1] + c[2] + c[3] + 1
-
-julia> C*S
-1
-
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
segre_classMethod
segre_class(F::AbstractBundle, k::Int)

Return the k-th Segre class of F.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
todd_classMethod
todd_class(F::AbstractBundle)

Return the Todd class of F.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
total_pontryagin_classMethod
total_pontryagin_class(F::AbstractBundle)

Return the total Pontryagin class of F.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
pontryagin_classMethod
pontryagin_class(F::AbstractBundle, k::Int)

Return the k-th Pontryagin class of F.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
euler_characteristicMethod
euler_characteristic(F::AbstractBundle)
-euler_pairing(F::AbstractBundle, G::AbstractBundle)

Return the holomorphic Euler characteristic $\chi(F)$ and the Euler pairing $\chi(F,G)$, respectively.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
hilbert_polynomialMethod
hilbert_polynomial(F::AbstractBundle)

If an abstract vector bundle F on an abstract variety with a specified hyperplane class is given, return the corresponding Hilbert polynomial of F.

Examples

julia> P2 = abstract_projective_space(2)
-AbstractVariety of dim 2
-
-julia> hilbert_polynomial(OO(P2))
-1//2*t^2 + 3//2*t + 1
-
-julia> euler_characteristic(OO(P2))
-1
-
-julia> euler_characteristic(OO(P2, 1))
-3
-
-julia> euler_characteristic(OO(P2, 2))
-6
-
-julia> euler_characteristic(OO(P2, 3))
-10
-
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source

Operations on Abstract Bundles

-Method
-(F::AbstractBundle)
-*(n::RingElement, F::AbstractBundle)
-+(F::AbstractBundle, G::AbstractBundle)
--(F::AbstractBundle, G::AbstractBundle)
-*(F::AbstractBundle, G::AbstractBundle)

Return -F, the sum F $+ \dots +$ F of n copies of F, F $+$ G, F $-$ G, and the tensor product of F and G, respectively.

Examples

julia> P3 = abstract_projective_space(3)
-AbstractVariety of dim 3
-
-julia> 4*OO(P3, 1) - OO(P3) == tangent_bundle(P3) # Euler sequence
-true
-
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
dualMethod
dual(F::AbstractBundle)

Return the dual bundle of F.

Examples

julia> P4 = abstract_projective_space(4)
-AbstractVariety of dim 4
-
-julia> h = gens(P4)[1]
-h
-
-julia> F = abstract_bundle(P4, 2, 10*h^2 + 5*h + 1) # Horrocks-Mumford bundle
-AbstractBundle of rank 2 on AbstractVariety of dim 4
-
-julia> c1 = chern_class(F, 1)
-5*h
-
-julia> Fd = dual(F)
-AbstractBundle of rank 2 on AbstractVariety of dim 4
-
-julia> chern_class(Fd, 1)
--5*h
-
-julia> F == Fd*OO(P4, 5) # self-duality up to twist
-true
-
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
detMethod
det(F::AbstractBundle)

Return the determinant bundle of F.

Examples

julia> P3 = abstract_projective_space(3)
-AbstractVariety of dim 3
-
-julia> T = tangent_bundle(P3)
-AbstractBundle of rank 3 on AbstractVariety of dim 3
-
-julia> chern_class(T, 1)
-4*h
-
-julia> det(T) == OO(P3, 4)
-true
-
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
exterior_powerMethod
exterior_power(F::AbstractBundle, k::Int)

Return the k-th exterior power of F.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
symmetric_powerMethod
symmetric_power(F::AbstractBundle, k::Int)
-symmetric_power(F::AbstractBundle, k::RingElement)

Return the k-th symmetric power of F. Here, k can contain parameters.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
diff --git a/previews/PR4245/Experimental/IntersectionTheory/AbstractVarieties/index.html b/previews/PR4245/Experimental/IntersectionTheory/AbstractVarieties/index.html deleted file mode 100644 index 1967734b57a4..000000000000 --- a/previews/PR4245/Experimental/IntersectionTheory/AbstractVarieties/index.html +++ /dev/null @@ -1,554 +0,0 @@ - -Abstract Varieties · Oscar.jl

Abstract Varieties

Types

AbsVariety <: Variety

Constructors

abstract_varietyMethod
 abstract_variety(n::Int, A::Union{MPolyDecRing, MPolyQuoRing{<:MPolyDecRingElem}})

Return an abstract variety of dimension n with Chow ring A.

Examples

julia> R, (h,) = graded_polynomial_ring(QQ, [:h])
-(Graded multivariate polynomial ring in 1 variable over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[h])
-
-julia> A, _ = quo(R, ideal(R, [h^3]))
-(Quotient of multivariate polynomial ring by ideal (h^3), Map: R -> A)
-
-julia> P2 = abstract_variety(2, A)
-AbstractVariety of dim 2
Note

The example above shows one way of setting up a version of the abstract projective plane. A more convenient way is to use the built-in command abstract_projective_space which implements additional data such as the tangent bundle:

julia> P2 = abstract_projective_space(2)
-AbstractVariety of dim 2
-
-julia> TP2 = tangent_bundle(P2)
-AbstractBundle of rank 2 on AbstractVariety of dim 2
-
-julia> chern_character(TP2)
-3//2*h^2 + 3*h + 2
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
abstract_pointMethod
abstract_point()

Return an abstract variety consisting of a point.

Examples

julia> p = abstract_point()
-AbstractVariety of dim 0
-
-julia> chow_ring(p)
-Quotient
-  of multivariate polynomial ring in 1 variable over QQ graded by
-    p -> [1]
-  by ideal (p)
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source

Specialized Constructors

abstract_projective_spaceMethod
abstract_projective_space(n::Int; base::Ring = QQ, symbol::String = "h")

Return the abstract projective space of lines in an n+1-dimensional vector space.

Examples

julia> P3 = abstract_projective_space(3)
-AbstractVariety of dim 3
-
-julia> chow_ring(P3)
-Quotient
-  of multivariate polynomial ring in 1 variable over QQ graded by
-    h -> [1]
-  by ideal (h^4)
julia> T, (s,t) = polynomial_ring(QQ, [:s, :t])
-(Multivariate polynomial ring in 2 variables over QQ, QQMPolyRingElem[s, t])
-
-julia> QT = fraction_field(T)
-Fraction field
-  of multivariate polynomial ring in 2 variables over QQ
-
-julia> P3 = abstract_projective_space(3, base = QT)
-AbstractVariety of dim 3
-
-julia> chow_ring(P3)
-Quotient
-  of multivariate polynomial ring in 1 variable over QT graded by
-    h -> [1]
-  by ideal (h^4)
-
-julia> TB = tangent_bundle(P3)
-AbstractBundle of rank 3 on AbstractVariety of dim 3
-
-julia> CTB = cotangent_bundle(P3)
-AbstractBundle of rank 3 on AbstractVariety of dim 3
-
-julia> chern_character((s*TB)*(t*CTB))
--4*s*t*h^2 + 9*s*t
-
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
abstract_grassmannianMethod
abstract_grassmannian(k::Int, n::Int; base::Ring = QQ, symbol::String = "c")

Return the abstract Grassmannian $\mathrm{G}(k, n)$ of k-dimensional subspaces of an n-dimensional vector space.

Examples

julia> G = abstract_grassmannian(2,4)
-AbstractVariety of dim 4
-
-julia> CR = chow_ring(G)
-Quotient
-  of multivariate polynomial ring in 2 variables over QQ graded by
-    c[1] -> [1]
-    c[2] -> [2]
-  by ideal (-c[1]^3 + 2*c[1]*c[2], c[1]^4 - 3*c[1]^2*c[2] + c[2]^2)
-
-julia> S = tautological_bundles(G)[1]
-AbstractBundle of rank 2 on AbstractVariety of dim 4
-
-julia> V = [chern_class(S, i) for i = 1:2]
-2-element Vector{MPolyQuoRingElem{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}}:
- c[1]
- c[2]
-
-julia> is_regular_sequence(gens(modulus(CR)))
-true
-
-julia> Q = tautological_bundles(G)[2]
-AbstractBundle of rank 2 on AbstractVariety of dim 4
-
-julia> tangent_bundle(G) == dual(S)*Q
-true
-
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
abstract_flag_varietyMethod
abstract_flag_variety(dims::Int...; base::Ring = QQ, symbol::String = "c")
-abstract_flag_variety(dims::Vector{Int}; base::Ring = QQ, symbol::String = "c")

Given integers, say, $d_1, \dots, d_{k}, n$ with $0 < d_1 < \dots < d_{k} < n$ or a vector of such integers, return the abstract flag variety $\mathrm{F}(d_1, \dots, d_{k}; n)$ of nested sequences of subspaces of dimensions $d_1, \dots, d_{k}$ of an $n$-dimensional vector space.

Examples

julia> F = abstract_flag_variety(1,3,4)
-AbstractVariety of dim 5
-
-julia> chow_ring(F)
-Quotient
-  of multivariate polynomial ring in 4 variables over QQ graded by
-    c[1, 1] -> [1]
-    c[2, 1] -> [1]
-    c[2, 2] -> [2]
-    c[3, 1] -> [1]
-  by ideal with 4 generators
-
-julia> modulus(chow_ring(F))
-Ideal generated by
-  -c[1, 1]*c[2, 2]*c[3, 1]
-  -c[1, 1]*c[2, 1]*c[3, 1] - c[1, 1]*c[2, 2] - c[2, 2]*c[3, 1]
-  -c[1, 1]*c[2, 1] - c[1, 1]*c[3, 1] - c[2, 1]*c[3, 1] - c[2, 2]
-  -c[1, 1] - c[2, 1] - c[3, 1]
-
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source

New Varieties From Given Varieties/Bundles

complete_intersectionMethod
complete_intersection(X::AbstractVariety, degs::Int...)
-complete_intersection(X::AbstractVariety, degs::Vector{Int})

Return the complete intersection in X of general hypersurfaces with the given degrees.

Examples

julia> P3 = abstract_projective_space(3)
-AbstractVariety of dim 3
-
-julia> CI = complete_intersection(P3, 2, 2)
-AbstractVariety of dim 1
-
-julia> dim(CI)
-1
-
-julia> degree(CI)
-4
-
-julia> chow_ring(CI)
-Quotient
-  of multivariate polynomial ring in 1 variable over QQ graded by
-    h -> [1]
-  by ideal (h^2)
-
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
abstract_projective_bundleMethod
abstract_projective_bundle(F::AbstractBundle; symbol::String = "z")

Return the projective bundle of 1-dimensional subspaces in the fibers of F.

Examples

julia> P2 = abstract_projective_space(2)
-AbstractVariety of dim 2
-
-julia> T = tangent_bundle(P2)
-AbstractBundle of rank 2 on AbstractVariety of dim 2
-
-julia> PT = abstract_projective_bundle(T)
-AbstractVariety of dim 3
-
-julia> chow_ring(PT)
-Quotient
-  of multivariate polynomial ring in 2 variables over QQ graded by
-    z -> [1]
-    h -> [1]
-  by ideal (h^3, z^2 + 3*z*h + 3*h^2)
-
-julia> [chern_class(T, i) for i = 1:2]
-2-element Vector{MPolyQuoRingElem{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}}:
- 3*h
- 3*h^2
-
-julia> gens(PT)[1]
-z
-
-julia> gens(PT)[1] == hyperplane_class(PT)
-true
-
julia> G = abstract_grassmannian(3, 5)
-AbstractVariety of dim 6
-
-julia> USBd = dual(tautological_bundles(G)[1])
-AbstractBundle of rank 3 on AbstractVariety of dim 6
-
-julia> F = symmetric_power(USBd, 2)
-AbstractBundle of rank 6 on AbstractVariety of dim 6
-
-julia> PF = abstract_projective_bundle(F)
-AbstractVariety of dim 11
-
-julia> A = symmetric_power(USBd, 5) - symmetric_power(USBd, 3)*OO(PF, -1)
-AbstractBundle of rank 11 on AbstractVariety of dim 11
-
-julia> integral(top_chern_class(A))
-609250
-
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
abstract_hirzebruch_surfaceMethod
abstract_hirzebruch_surface(n::Int)

Return the n-th Hirzebruch surface.

Note

Recall that the n-th Hirzebruch surface is the projective bundle associated to the bundle $\mathcal O_{\mathbb P_1} \oplus O_{\mathbb P_1(-n)}$.

Examples

julia> H2 =  abstract_hirzebruch_surface(2)
-AbstractVariety of dim 2
-
-julia> chow_ring(H2)
-Quotient
-  of multivariate polynomial ring in 2 variables over QQ graded by
-    z -> [1]
-    h -> [1]
-  by ideal (h^2, z^2 - 2*z*h)
-
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
abstract_flag_bundleMethod
abstract_flag_bundle(F::AbstractBundle, dims::Int...; symbol::String = "c")
-abstract_flag_bundle(F::AbstractBundle, dims::Vector{Int}; symbol::String = "c")

Given integers, say, $d_1, \dots, d_{k}, n$ with $0 < d_1 < \dots < d_{k} < n$ or a vector of such integers, and given an abstract bundle $F$ of rank $n$, return the abstract flag bundle of nested sequences of subspaces of dimensions $d_1, \dots, d_{k}$ in the fibers of $F$.

Note

Entering the number $n$ can be omitted since this number can be recovered as the rank of $F$.

Examples

julia> P = abstract_projective_space(4)
-AbstractVariety of dim 4
-
-julia> F = exterior_power(cotangent_bundle(P),  3)*OO(P,3)
-AbstractBundle of rank 4 on AbstractVariety of dim 4
-
-julia> FB = abstract_flag_bundle(F, 1, 3)
-AbstractVariety of dim 9
-
-julia> CR = chow_ring(FB)
-Quotient
-  of multivariate polynomial ring in 5 variables over QQ graded by
-    c[1, 1] -> [1]
-    c[2, 1] -> [1]
-    c[2, 2] -> [2]
-    c[3, 1] -> [1]
-    h -> [1]
-  by ideal with 5 generators
-
-julia> modulus(CR)
-Ideal generated by
-  h^5
-  -c[1, 1]*c[2, 2]*c[3, 1] + h^4
-  -c[1, 1]*c[2, 1]*c[3, 1] - c[1, 1]*c[2, 2] - c[2, 2]*c[3, 1] - 2*h^3
-  -c[1, 1]*c[2, 1] - c[1, 1]*c[3, 1] - c[2, 1]*c[3, 1] - c[2, 2] + 4*h^2
-  -c[1, 1] - c[2, 1] - c[3, 1] - 3*h
-
-julia> FB.bundles
-3-element Vector{AbstractBundle}:
- AbstractBundle of rank 1 on AbstractVariety of dim 9
- AbstractBundle of rank 2 on AbstractVariety of dim 9
- AbstractBundle of rank 1 on AbstractVariety of dim 9
-
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
zero_locus_sectionMethod
zero_locus_section(F::AbstractBundle; class::Bool = false)

Return the zero locus of a general section of F.

Use the argument class = true to only compute the class of the zero locus (same as top_chern_class(F)).

Examples

julia> P2 = abstract_projective_space(2)
-AbstractVariety of dim 2
-
-julia> C = zero_locus_section(OO(P2, 3)) # a plane cubic curve
-AbstractVariety of dim 1
-
-julia> dim(C)
-1
-
-julia> degree(C)
-3
-
julia> P3 = abstract_projective_space(3)
-AbstractVariety of dim 3
-
-julia> C = zero_locus_section(OO(P3, 2) + OO(P3, 2)) # a complete intersection
-AbstractVariety of dim 1
-
-julia> dim(C)
-1
-
-julia> degree(C)
-4
-
julia> P4 = abstract_projective_space(4)
-AbstractVariety of dim 4
-
-julia> h = gens(P4)[1]
-h
-
-julia> F = abstract_bundle(P4, 2, 10*h^2 + 5*h + 1) # Horrocks-Mumford bundle
-AbstractBundle of rank 2 on AbstractVariety of dim 4
-
-julia> A = zero_locus_section(F) # abelian surface
-AbstractVariety of dim 2
-
-julia> dim(A)
-2
-
-julia> degree(A)
-10
-
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
degeneracy_locusMethod
degeneracy_locus(F::AbstractBundle, G::AbstractBundle, k::Int; class::Bool=false)

Return the k-th degeneracy locus of a general map from F to G.

Use the argument class = true to only compute the class of the degeneracy locus (Porteous' formula).

Examples

julia> P4 = abstract_projective_space(4)
-AbstractVariety of dim 4
-
-julia> F = 3*OO(P4, -1)
-AbstractBundle of rank 3 on AbstractVariety of dim 4
-
-julia> G = cotangent_bundle(P4)*OO(P4,1)
-AbstractBundle of rank 4 on AbstractVariety of dim 4
-
-julia> CZ = degeneracy_locus(F, G, 2, class = true) # only class of degeneracy locus
-4*h^2
-
-julia> CZ == chern_class(G-F, 2) # Porteous' formula
-true
-
-julia> Z = degeneracy_locus(F, G, 2) # Veronese surface in P4
-AbstractVariety of dim 2
-
-julia> degree(Z)
-4
-
julia> P = abstract_projective_space(4, symbol = "H")
-AbstractVariety of dim 4
-
-julia> F = exterior_power(cotangent_bundle(P), 3)*OO(P,3)
-AbstractBundle of rank 4 on AbstractVariety of dim 4
-
-julia> G = OO(P, 1)+4*OO(P)
-AbstractBundle of rank 5 on AbstractVariety of dim 4
-
-julia> Z = degeneracy_locus(F, G, 3) # rational surface in P4
-AbstractVariety of dim 2
-
-julia> K = canonical_class(Z)
-z - H
-
-julia> integral(K^2)
--7
-
-julia> H = hyperplane_class(Z)
-H
-
-julia> integral(H^2) # degree of surface
-8
-
-julia> A = K+H
-z
-
-julia> integral(A^2) # degree of first adjoint surface which is a Del Pezzo surface in P5
-5
-
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
Note

Products and blowups are described elsewhere.

Underlying Data of an Abstract Variety

An abstract variety is made up from (a selection of) the data discussed here:

dimMethod
 dim(X::AbstractVariety)

Return the dimension of X.

Examples

julia> P2 = abstract_projective_space(2)
-AbstractVariety of dim 2
-
-julia> P3 = abstract_projective_space(3)
-AbstractVariety of dim 3
-
-julia> dim(P2*P3)
-5
-
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
chow_ringMethod
chow_ring(X::AbstractVariety)

Return the Chow ring of the abstract variety X.

Examples

julia> P2 = abstract_projective_space(2)
-AbstractVariety of dim 2
-
-julia> P3 = abstract_projective_space(3, symbol = "H")
-AbstractVariety of dim 3
-
-julia> chow_ring(P2*P3)
-Quotient
-  of multivariate polynomial ring in 2 variables over QQ graded by
-    h -> [1]
-    H -> [1]
-  by ideal (h^3, H^4)
-
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
baseMethod
base(X::AbstractVariety)

Return the coefficient ring of the polynomial ring underlying the Chow ring of X.

Examples

julia> P2 = abstract_projective_space(2)
-AbstractVariety of dim 2
-
-julia> chow_ring(P2)
-Quotient
-  of multivariate polynomial ring in 1 variable over QQ graded by
-    h -> [1]
-  by ideal (h^3)
-
-julia> base(P2)
-Rational field
-
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
point_classMethod
point_class(X::AbstractVariety)

Return the point class of X.

Examples

julia> P2 = abstract_projective_space(2)
-AbstractVariety of dim 2
-
-julia> P3 = abstract_projective_space(3, symbol = "H")
-AbstractVariety of dim 3
-
-julia> p = point_class(P2*P3)
-h^2*H^3
-
-julia> degree(p)
-[5]
-
-julia> integral(p)
-1
-
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
tangent_bundleMethod
tangent_bundle(X::AbstractVariety)

Return the tangent bundle of X.

Examples

julia> G = abstract_grassmannian(2,5)
-AbstractVariety of dim 6
-
-julia> TG = tangent_bundle(G)
-AbstractBundle of rank 6 on AbstractVariety of dim 6
-
-julia> chern_character(TG)
--5//6*c[1]^3 + 5//24*c[1]^2*c[2] + 3//2*c[1]^2 + 5//2*c[1]*c[2] - 5*c[1] + 7//72*c[2]^3 - 25//24*c[2]^2 - c[2] + 6
-
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
hyperplane_classMethod
hyperplane_class(X::AbstractVariety)

If defined, return the class of a hyperplane section of X.

Note

Speaking of a hyperplane class of X means that we have a specific embedding of X into projective space in mind. For Grassmanians, for example, this embedding is the Plücker embedding. For the product of two abstract varieties with given hyperplane classes, it is the Segre embedding.

Examples

julia> G = abstract_grassmannian(2, 5)
-AbstractVariety of dim 6
-
-julia> hyperplane_class(G)
--c[1]
-
-julia> degree(G) == integral(hyperplane_class(G)^dim(G)) == 5
-true
-
julia> P1s = abstract_projective_space(1, symbol = "s")
-AbstractVariety of dim 1
-
-julia> P1t = abstract_projective_space(1, symbol = "t")
-AbstractVariety of dim 1
-
-julia> P = P1s*P1t
-AbstractVariety of dim 2
-
-julia> H = hyperplane_class(P)
-s + t
-
-julia> integral(H^dim(P))
-2
-
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
tautological_bundlesMethod
tautological_bundles(X::AbstractVariety)

Return the tautological_bundles of X (if applicable).

Examples

julia> P2 = abstract_projective_space(2)
-AbstractVariety of dim 2
-
-julia> TB = tautological_bundles(P2)
-2-element Vector{AbstractBundle}:
- AbstractBundle of rank 1 on AbstractVariety of dim 2
- AbstractBundle of rank 2 on AbstractVariety of dim 2
-
-julia> TB[1] == OO(P2, -1)
-true
-
-julia> TB[2] == tangent_bundle(P2)*OO(P2, -1)
-true
-
julia> G = abstract_grassmannian(3, 5)
-AbstractVariety of dim 6
-
-julia> tautological_bundles(G)
-2-element Vector{AbstractBundle}:
- AbstractBundle of rank 3 on AbstractVariety of dim 6
- AbstractBundle of rank 2 on AbstractVariety of dim 6
-
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
structure_mapMethod
structure_map(X::AbstractVariety)

Return the structure map of X.

Examples

julia> P2 = abstract_projective_space(2)
-AbstractVariety of dim 2
-
-julia> structure_map(P2)
-AbstractVarietyMap from AbstractVariety of dim 2 to AbstractVariety of dim 0
-
-julia> T = tangent_bundle(P2)
-AbstractBundle of rank 2 on AbstractVariety of dim 2
-
-julia> E = abstract_projective_bundle(T, symbol = "H")
-AbstractVariety of dim 3
-
-julia> chow_ring(E)
-Quotient
-  of multivariate polynomial ring in 2 variables over QQ graded by
-    H -> [1]
-    h -> [1]
-  by ideal (h^3, H^2 + 3*H*h + 3*h^2)
-
-julia> structure_map(E)
-AbstractVarietyMap from AbstractVariety of dim 3 to AbstractVariety of dim 2
-
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source

Further Data Associated to an Abstract Variety

trivial_line_bundleMethod
trivial_line_bundle(X::AbstractVariety)

Return the trivial line bundle $\mathcal O_X$ on X. Alternatively, use OO instead of trivial_line_bundle.

Examples

julia> P2 = abstract_projective_space(2)
-AbstractVariety of dim 2
-
-julia> OX = trivial_line_bundle(P2)
-AbstractBundle of rank 1 on AbstractVariety of dim 2
-
-julia> chern_character(OX)
-1
-
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
line_bundleMethod
line_bundle(X::AbstractVariety, n::RingElement)
-line_bundle(X::AbstractVariety, D::MPolyDecRingElem)

Return the line bundle $\mathcal O_X(n)$ on X if X has been given a hyperplane class, or a line bundle $\mathcal O_X(D)$ with first Chern class $D$. Alternatively, use OO instead of line_bundle.

Examples

julia> P2 = abstract_projective_space(2)
-AbstractVariety of dim 2
-
-julia> tautological_bundles(P2)[1] == OO(P2, -1)
-true
-
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
cotangent_bundleMethod
cotangent_bundle(X::AbstractVariety)

Return the cotangent bundle of X.

Examples

julia> P2 = abstract_projective_space(2)
-AbstractVariety of dim 2
-
-julia> cotangent_bundle(P2) == dual(tangent_bundle(P2)) 
-true
-
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
canonical_classMethod
canonical_class(X::AbstractVariety)

Return the canonical class of X.

Examples

julia> P2 = abstract_projective_space(2)
-AbstractVariety of dim 2
-
-julia> canonical_class(P2) == chern_class(cotangent_bundle(P2), 1)
-true
-
-julia> canonical_class(P2) 
--3*h
-
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
canonical_bundleMethod
canonical_bundle(X::AbstractVariety)

Return the canonical bundle of X.

julia> P2 = abstract_projective_space(2)
-AbstractVariety of dim 2
-
-julia> canonical_bundle(P2) == det(cotangent_bundle(P2))
-true
-
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
degreeMethod
degree(X::AbstractVariety)

If X has been given a hyperplane class, return the corresponding degree of X.

Examples

julia> G = abstract_grassmannian(2,5)
-AbstractVariety of dim 6
-
-julia> degree(G)
-5
-
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
hilbert_polynomialMethod
hilbert_polynomial(X::AbstractVariety)

If X has been given a hyperplane class, return the corresponding Hilbert polynomial of X.

Examples

julia> P2 = abstract_projective_space(2)
-AbstractVariety of dim 2
-
-julia> hilbert_polynomial(P2) == hilbert_polynomial(OO(P2))
-true
-
-julia> hilbert_polynomial(P2)
-1//2*t^2 + 3//2*t + 1
-
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
basisMethod
basis(X::AbstractVariety)

If K = base(X), return a K-basis of the Chow ring of X.

Note

The basis elements are ordered by increasing degree (geometrically, by increasing codimension).

Examples

julia> G = abstract_grassmannian(2,4)
-AbstractVariety of dim 4
-
-julia> chow_ring(G)
-Quotient
-  of multivariate polynomial ring in 2 variables over QQ graded by
-    c[1] -> [1]
-    c[2] -> [2]
-  by ideal (-c[1]^3 + 2*c[1]*c[2], c[1]^4 - 3*c[1]^2*c[2] + c[2]^2)
-
-julia> basis(G)
-5-element Vector{Vector{MPolyQuoRingElem}}:
- [1]
- [c[1]]
- [c[2], c[1]^2]
- [c[1]*c[2]]
- [c[2]^2]
-
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
intersection_matrixMethod
intersection_matrix(X::AbstractVariety)

If b = vcat(basis(X)...), return matrix([integral(bi*bj) for bi in b, bj in b]).

intersection_matrix(a::Vector, b::Vector)

Return matrix([integral(ai*bj) for ai in a, bj in b]).

intersection_matrix(a::Vector)

As above, with b = a.

Examples

julia> G = abstract_grassmannian(2,4)
-AbstractVariety of dim 4
-
-julia> basis(G)
-5-element Vector{Vector{MPolyQuoRingElem}}:
- [1]
- [c[1]]
- [c[2], c[1]^2]
- [c[1]*c[2]]
- [c[2]^2]
-
-julia> b = vcat(basis(G)...)
-6-element Vector{MPolyQuoRingElem}:
- 1
- c[1]
- c[2]
- c[1]^2
- c[1]*c[2]
- c[2]^2
-
-julia> intersection_matrix(G)
-[0   0   0   0   0   1]
-[0   0   0   0   1   0]
-[0   0   1   1   0   0]
-[0   0   1   2   0   0]
-[0   1   0   0   0   0]
-[1   0   0   0   0   0]
-
-julia> integral(b[4]*b[4])
-2
-
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
dual_basisMethod
dual_basis(X::AbstractVariety)

If K = base(X), return a K-basis for the Chow ring of X which is dual to basis(X) with respect to the K-bilinear form defined by intersection_matrix(X).

Note

The basis elements are ordered by decreasing degree (geometrically, by decreasing codimension).

Examples

julia> G = abstract_grassmannian(2,4)
-AbstractVariety of dim 4
-
-julia> b = basis(G)
-5-element Vector{Vector{MPolyQuoRingElem}}:
- [1]
- [c[1]]
- [c[2], c[1]^2]
- [c[1]*c[2]]
- [c[2]^2]
-
-julia> intersection_matrix(G)
-[0   0   0   0   0   1]
-[0   0   0   0   1   0]
-[0   0   1   1   0   0]
-[0   0   1   2   0   0]
-[0   1   0   0   0   0]
-[1   0   0   0   0   0]
-
-julia> bd = dual_basis(G)
-5-element Vector{Vector{MPolyQuoRingElem{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}}}:
- [c[2]^2]
- [c[1]*c[2]]
- [-c[1]^2 + 2*c[2], c[1]^2 - c[2]]
- [c[1]]
- [1]
-
-julia> integral(b[3][2]*b[3][2])
-2
-
-julia> integral(b[3][2]*bd[3][2])
-1
-
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
Note

If X is of type AbstractVariety, entering total_chern_class(X) returns the total Chern class of the tangent bundle of X. Similarly for entering euler(X), chern_class(X, k), todd_class(X), total_pontryagin_class(X), pontryagin_class(X, k)

Operations on Abstract Varieties

productMethod
product(X::AbstractVariety, Y::AbstractVariety)

Return the product $X\times Y$. Alternatively, use *.

Note

If both X and Y have a hyperplane class, $X\times Y$ will be endowed with the hyperplane class corresponding to the Segre embedding.

julia> P2 = abstract_projective_space(2);
-
-julia> P3 = abstract_projective_space(3, symbol = "H");
-
-julia> P2xP3 = P2*P3
-AbstractVariety of dim 5
-
-julia> chow_ring(P2xP3)
-Quotient
-  of multivariate polynomial ring in 2 variables over QQ graded by
-    h -> [1]
-    H -> [1]
-  by ideal (h^3, H^4)
-
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
Note

Blowups are described in their own section.

Integrate Chow Ring Elements

integral(x::MPolyDecRingElem)

Given an element x of the Chow ring of an abstract variety X, say, return the integral of x.

Note

If X has a (unique) point class, the integral will be a number (that is, a QQFieldElem or a function field element). Otherwise, the highests degree part of $x$ is returned (geometrically, this is the 0-dimensional part of $x$).

Examples
julia> G = abstract_grassmannian(2, 4)
-AbstractVariety of dim 4
-
-julia> Q = tautological_bundles(G)[2]
-AbstractBundle of rank 2 on AbstractVariety of dim 4
-
-julia> E = symmetric_power(Q, 3)
-AbstractBundle of rank 4 on AbstractVariety of dim 4
-
-julia> integral(top_chern_class(E))
-27
-
diff --git a/previews/PR4245/Experimental/IntersectionTheory/AbstractVarietyMaps/index.html b/previews/PR4245/Experimental/IntersectionTheory/AbstractVarietyMaps/index.html deleted file mode 100644 index 8b3e2a8b133d..000000000000 --- a/previews/PR4245/Experimental/IntersectionTheory/AbstractVarietyMaps/index.html +++ /dev/null @@ -1,75 +0,0 @@ - -Abstract Variety Maps · Oscar.jl

Abstract Variety Maps

Constructors

homFunction
hom(X::AbstractVariety, Y::AbstractVariety, fˣ::Vector, fₓ = nothing; inclusion::Bool = false, symbol::String = "x")

Return an abstract variety map X $\rightarrow$ Y by specifying the pullbacks of the generators of the Chow ring of Y.

Note

The corresponding pushforward can be automatically computed in certain cases.

In case of an inclusion $i:X\hookrightarrow Y$ where the class of X is not present in the Chow ring of Y, use the argument inclusion = true. Then, a copy of Y will be created, with extra classes added so that one can pushforward all classes on X.

Examples

julia> P2xP2 = abstract_projective_space(2, symbol = "k")*abstract_projective_space(2, symbol = "l")
-AbstractVariety of dim 4
-
-julia> P8 = abstract_projective_space(8)
-AbstractVariety of dim 8
-
-julia> k, l = gens(P2xP2)
-2-element Vector{MPolyQuoRingElem{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}}:
- k
- l
-
-julia> Se = hom(P2xP2, P8, [k+l]) # Segre embedding
-AbstractVarietyMap from AbstractVariety of dim 4 to AbstractVariety of dim 8
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source

Underlying Data of an Abstract Variety Map

An abstract variety map is made up from (a selection of) the data discussed here:

domainMethod
 domain(f::AbstractVarietyMap)

Return the domain of f.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
codomainMethod
 codomain(f::AbstractVarietyMap)

Return the codomain of f.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
dimMethod
dim(f::AbstractVarietyMap)

Return the relative dimension of f, that is, return dim(domain(f)) - dim(codomain(f)).

Examples

julia> P2 = abstract_projective_space(2)
-AbstractVariety of dim 2
-
-julia> P5 = abstract_projective_space(5, symbol = "H")
-AbstractVariety of dim 5
-
-julia> h = gens(P2)[1]
-h
-
-julia> i = hom(P2, P5, [2*h])
-AbstractVarietyMap from AbstractVariety of dim 2 to AbstractVariety of dim 5
-
-julia> dim(i)
--3
-
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
pullbackMethod
pullback(f::AbstractVarietyMap, y::MPolyDecRingElem)

Return the pullback of y via f.

Examples

julia> P2 = abstract_projective_space(2)
-AbstractVariety of dim 2
-
-julia> P5 = abstract_projective_space(5, symbol = "H")
-AbstractVariety of dim 5
-
-julia> h = gens(P2)[1]
-h
-
-julia> H = gens(P5)[1]
-H
-
-julia> i = hom(P2, P5, [2*h])
-AbstractVarietyMap from AbstractVariety of dim 2 to AbstractVariety of dim 5
-
-julia> pullback(i, H)
-2*h
-
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
pushforwardMethod
pushforward(f::AbstractVarietyMap, x::MPolyDecRingElem)

Return the pushforward of x via f.

Examples

julia> P2 = abstract_projective_space(2)
-AbstractVariety of dim 2
-
-julia> P5 = abstract_projective_space(5, symbol = "H")
-AbstractVariety of dim 5
-
-julia> h = gens(P2)[1]
-h
-
-julia> i = hom(P2, P5, [2*h])
-AbstractVarietyMap from AbstractVariety of dim 2 to AbstractVariety of dim 5
-
-julia> pushforward(i, h)
-2*H^4
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
tangent_bundleMethod
tangent_bundle(f::AbstractVarietyMap)

Return the relative tangent bundle of f.

Examples

julia> P2 = abstract_projective_space(2)
-AbstractVariety of dim 2
-
-julia> T = tangent_bundle(P2)
-AbstractBundle of rank 2 on AbstractVariety of dim 2
-
-julia> PT = abstract_projective_bundle(T)
-AbstractVariety of dim 3
-
-julia> pi = structure_map(PT)
-AbstractVarietyMap from AbstractVariety of dim 3 to AbstractVariety of dim 2
-
-julia> PBT = pullback(pi, T)
-AbstractBundle of rank 2 on AbstractVariety of dim 3
-
-julia> PBT*OO(PT, 1) - OO(PT) == tangent_bundle(pi) # relative Euler sequence
-true
-
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source

Further Data Associated to an Abstract Variety Map

cotangent_bundleMethod
cotangent_bundle(f::AbstractVarietyMap)

Return the relative cotangent bundle of f.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
todd_classMethod
todd_class(f::AbstractVarietyMap)

Return the Todd class of the relative tangent bundle of f.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source

Operations on Abstract Variety Maps

composeMethod
compose(f::AbstractVarietyMap, g::AbstractVarietyMap)

Given abstract variety maps f : X $\to$ Y and g : Y $\to$ Z, say, return their composition.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
diff --git a/previews/PR4245/Experimental/IntersectionTheory/BlowUps/index.html b/previews/PR4245/Experimental/IntersectionTheory/BlowUps/index.html deleted file mode 100644 index bc9fce4c5014..000000000000 --- a/previews/PR4245/Experimental/IntersectionTheory/BlowUps/index.html +++ /dev/null @@ -1,156 +0,0 @@ - -Blowups · Oscar.jl

Blowups

present_finite_extension_ringMethod
  present_finite_extension_ring(F::Oscar.AffAlgHom)

Given a finite homomorphism F $:$ A $\rightarrow$ B of algebras of type <: Union{MPolyRing, MPolyQuoRing} over a field, return a presentation

\[A^r \rightarrow A^s\rightarrow B \rightarrow 0\]

of B as an A-module.

More precisely, return a tuple (gs, PM, sect), say, where

  • gs is a vector of polynomials representing generators for B as an A-module,
  • PM is an r $\times$ s-matrix of polynomials defining the map $A^r \rightarrow A^s$, and
  • sect is a function which gives rise to a section of the augmentation map $ A^s\rightarrow B$.
Note

The finiteness condition on F is checked by the function.

Note

The function is implemented so that the last element of gs is one(B).

Examples

julia> RA, (h,) = polynomial_ring(QQ, [:h]);
-
-julia> A, _ = quo(RA, ideal(RA, [h^9]));
-
-julia> RB, (k, l) = polynomial_ring(QQ, [:k, :l]);
-
-julia> B, _ = quo(RB, ideal(RB, [k^3, l^3]));
-
-julia> F = hom(A, B, [k+l])
-Ring homomorphism
-  from quotient of multivariate polynomial ring by ideal (h^9)
-  to quotient of multivariate polynomial ring by ideal (k^3, l^3)
-defined by
-  h -> k + l
-
-julia> gs, PM, sect = present_finite_extension_ring(F);
-
-julia> gs
-3-element Vector{QQMPolyRingElem}:
- l^2
- l
- 1
-
-julia> PM
-3×3 Matrix{QQMPolyRingElem}:
- h^3     0       0
- -3*h^2  h^3     0
- 3*h     -3*h^2  h^3
-
-julia> sect(k*l)
-3-element Vector{QQMPolyRingElem}:
- -1
- h
- 0
-
julia> R, (x, y, z) = polynomial_ring(QQ, [:x, :y, :z]);
-
-julia> I = ideal(R, [z^2-y^2*(y+1)]);
-
-julia> A, _ = quo(R, I);
-
-julia> B, (s,t) =  polynomial_ring(QQ, [:s, :t]);
-
-julia> F = hom(A,B, [s, t^2-1, t*(t^2-1)])
-Ring homomorphism
-  from quotient of multivariate polynomial ring by ideal (-y^3 - y^2 + z^2)
-  to multivariate polynomial ring in 2 variables over QQ
-defined by
-  x -> s
-  y -> t^2 - 1
-  z -> t^3 - t
-
-julia> gs, PM, sect = present_finite_extension_ring(F);
-
-julia> gs
-2-element Vector{QQMPolyRingElem}:
- t
- 1
-
-julia> PM
-2×2 Matrix{QQMPolyRingElem}:
- y   -z
- -z  y^2 + y
-
-julia> sect(t)
-2-element Vector{QQMPolyRingElem}:
- 1
- 0
-
-julia> sect(one(B))
-2-element Vector{QQMPolyRingElem}:
- 0
- 1
-
-julia> sect(s)
-2-element Vector{QQMPolyRingElem}:
- 0
- x
-
julia> A, (a, b, c) = polynomial_ring(QQ, [:a, :b, :c]);
-
-julia> R, (x, y, z) = polynomial_ring(QQ, [:x, :y, :z]);
-
-julia> I = ideal(R, [x*y]);
-
-julia> B, _ = quo(R, I);
-
-julia> (x, y, z) = gens(B);
-
-julia> F = hom(A, B, [x^2+z, y^2-1, z^3])
-Ring homomorphism
-  from multivariate polynomial ring in 3 variables over QQ
-  to quotient of multivariate polynomial ring by ideal (x*y)
-defined by
-  a -> x^2 + z
-  b -> y^2 - 1
-  c -> z^3
-
-julia> gs, PM, sect = present_finite_extension_ring(F);
-
-julia> gs
-2-element Vector{QQMPolyRingElem}:
- y
- 1
-
-julia> PM
-2×2 Matrix{QQMPolyRingElem}:
- a^3 - c  0
- 0        a^3*b + a^3 - b*c - c
-
-julia> sect(y)
-2-element Vector{QQMPolyRingElem}:
- 1
- 0
-
-julia> sect(one(B))
-2-element Vector{QQMPolyRingElem}:
- 0
- 1
-
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
blowupMethod
  blowup(i::AbstractVarietyMap; symbol::String="e")

Given an inclusion i$ : $ X $\rightarrow$ Y, say, return the blowup of Y along X.

More precisely, return a tuple (Bl, E, j), say, where

  • Bl, an abstract variety, is the blowup,
  • E, an abstract variety, is the exceptional divisor, and
  • j, a map of abstract varieties, is the inclusion of E into Bl.
Note

The resulting maps Bl $\rightarrow$ Y and E $\rightarrow$ X are obtained entering structure_map(Bl) and structure_map(E), respectively.

Examples

julia> P2 = abstract_projective_space(2)
-AbstractVariety of dim 2
-
-julia> P5 = abstract_projective_space(5, symbol = "H")
-AbstractVariety of dim 5
-
-julia> h = gens(P2)[1]
-h
-
-julia> H = gens(P5)[1]
-H
-
-julia> i = hom(P2, P5, [2*h])
-AbstractVarietyMap from AbstractVariety of dim 2 to AbstractVariety of dim 5
-
-julia> Bl, E, j = blowup(i)
-(AbstractVariety of dim 5, AbstractVariety of dim 4, AbstractVarietyMap from AbstractVariety of dim 4 to AbstractVariety of dim 5)
-
-julia> e, HBl = gens(chow_ring(Bl))
-2-element Vector{MPolyQuoRingElem{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}}:
- e
- H
-
-julia> integral((6*HBl-2*e)^5)
-3264
-
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
blowup_pointsMethod
function blowup_points(X::AbstractVariety, n::Int; symbol::String = "e")

Return the blowup of X at n points.

Examples

julia> P2 = abstract_projective_space(2)
-AbstractVariety of dim 2
-
-julia> Bl = blowup_points(P2, 1)
-AbstractVariety of dim 2
-
-julia> chow_ring(Bl)
-Quotient
-  of multivariate polynomial ring in 2 variables over QQ graded by
-    e -> [1]
-    h -> [1]
-  by ideal (e*h, e^2 + h^2)
-
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
diff --git a/previews/PR4245/Experimental/IntersectionTheory/BottFormulas/index.html b/previews/PR4245/Experimental/IntersectionTheory/BottFormulas/index.html deleted file mode 100644 index c60f10cae3ca..000000000000 --- a/previews/PR4245/Experimental/IntersectionTheory/BottFormulas/index.html +++ /dev/null @@ -1,2 +0,0 @@ - -Bott Formulas · Oscar.jl
diff --git a/previews/PR4245/Experimental/IntersectionTheory/examples/index.html b/previews/PR4245/Experimental/IntersectionTheory/examples/index.html deleted file mode 100644 index 6aafdab23719..000000000000 --- a/previews/PR4245/Experimental/IntersectionTheory/examples/index.html +++ /dev/null @@ -1,78 +0,0 @@ - -Illustrating Examples From Enumerative Geometry · Oscar.jl

Illustrating Examples From Enumerative Geometry

How Many Lines in $\mathbb P^3$ Meet Four General Lines in $\mathbb P^3$?

julia> G = abstract_grassmannian(2,4)
-AbstractVariety of dim 4
-
-julia> s1 = schubert_class(G, 1)
--c[1]
-
-julia> integral(s1^4)
-2
-

How Many Conics in $\mathbb P^3$ Meet Eight General Lines in $\mathbb P^3$?

julia> G = abstract_grassmannian(3, 4)
-AbstractVariety of dim 3
-
-julia> USBd = dual(tautological_bundles(G)[1])
-AbstractBundle of rank 3 on AbstractVariety of dim 3
-
-julia> F = symmetric_power(USBd, 2)
-AbstractBundle of rank 6 on AbstractVariety of dim 3
-
-julia> PF = abstract_projective_bundle(F) # the parameter space of conics in P3
-AbstractVariety of dim 8
-
-julia> UQB = tautological_bundles(G)[2]
-AbstractBundle of rank 1 on AbstractVariety of dim 3
-
-julia> p = pullback(structure_map(PF), chern_class(UQB, 1))
--c[1]
-
-julia> Z = dual(tautological_bundles(PF)[1])
-AbstractBundle of rank 1 on AbstractVariety of dim 8
-
-julia> z = chern_class(Z, 1)
-z
-
-julia> integral((2*p + z)^8)
-92
-

Steiner's Problem: How Many Conics are Tangent to 5 General Conics in $\mathbb P^2$?

julia> P2 = abstract_projective_space(2)
-AbstractVariety of dim 2
-
-julia> P5 = abstract_projective_space(5, symbol = "H")
-AbstractVariety of dim 5
-
-julia> h = gens(P2)[1]
-h
-
-julia> H = gens(P5)[1]
-H
-
-julia> i = hom(P2, P5, [2*h])
-AbstractVarietyMap from AbstractVariety of dim 2 to AbstractVariety of dim 5
-
-julia> Bl, E, j = blowup(i)
-(AbstractVariety of dim 5, AbstractVariety of dim 4, AbstractVarietyMap from AbstractVariety of dim 4 to AbstractVariety of dim 5)
-
-julia> e, HBl = gens(chow_ring(Bl))
-2-element Vector{MPolyQuoRingElem{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}}:
- e
- H
-
-julia> integral((6*HBl-2*e)^5)
-3264
-

How Many Conics lie on the General Quintic Hypersurface in $\mathbb P^4$?

julia> G = abstract_grassmannian(3, 5)
-AbstractVariety of dim 6
-
-julia> USBd = dual(tautological_bundles(G)[1])
-AbstractBundle of rank 3 on AbstractVariety of dim 6
-
-julia> F = symmetric_power(USBd, 2)
-AbstractBundle of rank 6 on AbstractVariety of dim 6
-
-julia> PF = abstract_projective_bundle(F) # the parameter space of conics in P3
-AbstractVariety of dim 11
-
-julia> A = symmetric_power(USBd, 5) - symmetric_power(USBd, 3)*OO(PF, -1)
-AbstractBundle of rank 11 on AbstractVariety of dim 11
-
-julia> integral(top_chern_class(A))
-609250
-
diff --git a/previews/PR4245/Experimental/IntersectionTheory/intro/index.html b/previews/PR4245/Experimental/IntersectionTheory/intro/index.html deleted file mode 100644 index 7c60980ac6bc..000000000000 --- a/previews/PR4245/Experimental/IntersectionTheory/intro/index.html +++ /dev/null @@ -1,2 +0,0 @@ - -Introduction · Oscar.jl

Introduction

In this chapter, we

  • introduce OSCAR tools which support computations in intersection theory, and
  • give examples which illustrate how intersection theory is used to solve problems from enumerative geometry.
Note

Making use of OSCAR, a first version of what we present here was written by Jeiao Song as a julia package. This package was "heavily inspired by the Macaulay2 package Schubert2 and the Sage library Chow. Some functionalities from [the Sage library] Schubert3 are also implemented."

Note

Schubert2 was written by Daniel R. Grayson, Michael E. Stillman, Stein A. Strømme, David Eisenbud, and Charley Crissman while Chow is due to Manfred Lehn and Christoph Sorger. Schubert3 as well as the Singular library schubert.lib were written by Dang Tuan Hiep. The basis for all this work, including ours, is the Maple package Schubert written by Sheldon Katz and Stein A. Strømme.

Throughout the chapter, the varieties we consider are smooth projective varieties over the complex numbers.

Note

The Chow ring of a variety X is the group of cycles of X modulo an equivalence relation, together with the intersection pairing which defines the multiplication of the ring. Here, in contrast to most textbooks, we consider numerical equivalence classes of cycles rather than rational equivalence classes.

Our approach is abstract in the sense that we do not work with concrete varieties; that is, our varieties are not given by equations. Instead, we represent a variety by specifying its dimension together with its Chow ring and, possibly, further data. We refer to such such a collection of data as an abstract variety, and to results obtained from manipulating the data as results which apply to all (smooth projective complex) varieties sharing the data.

Of particular interest is the tangent bundle of a variety (recall that the Todd class of the tangent bundle enters the Hirzebruch-Riemann-Roch formula). As with any other vector bundle, the tangent bundle is represented as a collection of data referred to as an abstract vector bundle. The main data here is the Chern character polynomial of the vector bundle.

In the same spirit, we introduce abstract variety maps. Their key ingredient is the pullback morphism between the Chow rings.

General textbooks offering details on theory and algorithms include:

For computations in the Chow rings of abstract flag bundles see

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/PR4245/Experimental/IntersectionTheory/schubert/index.html b/previews/PR4245/Experimental/IntersectionTheory/schubert/index.html deleted file mode 100644 index cb07eb516d33..000000000000 --- a/previews/PR4245/Experimental/IntersectionTheory/schubert/index.html +++ /dev/null @@ -1,76 +0,0 @@ - -Schubert Calculus · Oscar.jl

Schubert Calculus

To recall the definition of Schubert cycles on a Grassmannian $\mathrm{G}(k,n)$, we think of $\mathrm{G}(k, n)$ as the Grassmannian $\mathrm{G}(k, W)$ of $k$-dimensional subspaces of an $n$-dimensional $K$-vector space $W$.

A flag in $W$ is a strictly increasing sequence of linear subspaces

\[\{0\} \subset W_1 \subset \dots \subset W_{n-1} \subset W_n = W, \; \text{ with }\; \dim(W_i) = i.\]

Let such a flag $\mathcal{W}$ be given. For any sequence $a = (a_1, \ldots, a_k)$ of integers with $n-k \geq a_1 \geq \ldots \geq a_k \geq 0$, we define the Schubert cycle $\Sigma_a(\mathcal{W})$ by setting

\[\Sigma_a(\mathcal{W}):= \{ V \in \mathrm{G}(k, W)\mid \dim(W_{n-k+i-a_i} \cap V) \geq i, i = 1, \ldots, k \} \,.\]

Then we have:

  • The Schubert cycle $\Sigma_a(\mathcal{W})$ is an irreducible subvariety of $\mathrm{G}(k, W)$ of codimension $|a| = \sum a_i$.
  • Its cycle class $[\Sigma_a(\mathcal{W})]$ does not depend on the choice of the flag.

We define the Schubert class of $a = (a_1, \ldots, a_k)$ to be the cycle class

\[\sigma_a := [\Sigma_a(\mathcal{W})] \,.\]

The number of Schubert classes on the Grassmannian $\mathrm{G}(k, n)$ is equal to $\binom{n}{k}$.

Instead of $\sigma_a$, we write $\sigma_{a_1,\ldots,a_s}$ whenever $a = (a_1, \ldots, a_s, 0, \ldots, 0)$, and $\sigma_{p^i}$ whenever $a = (p, \ldots, p, 0, \ldots, 0) \in \mathbb Z^i \times \{0\}^{k-i}$.

The classes $\sigma_{1^i}$, $i = 1, \ldots, k$, and $\sigma_i$, $i = 1, \ldots, n-k$, are called special Schubert classes. They are closely related to the Chern classes of the tautological vector bundles on $\mathrm{G}(k, W)$. Recall:

  • The tautological subbundle on $\mathrm{G}(k, W)$ is the vector bundle of rank $k$ whose fiber at $V \in \mathrm{G}(k, W)$ is the subspace $V \subset W$.
  • The tautological quotient bundle on $\mathrm{G}(k, W)$ is the vector bundle of rank $(n-k)$ whose fiber at $V \in \mathrm{G}(k, W)$ is the quotient vector space $W/V$.

We denote these vector bundles by $S$ and $Q$, respectively.

The Chern classes of $S$ and $Q$ are

\[c_i(S) = (-1)^i \sigma_{1^i} \; \text{ for } \; i = 1, \ldots, k\]

and

\[c_i(Q) = \sigma_i \; \text{ for }\; i = 1, \ldots, n-k,\]

respectively.

All Schubert classes form a $K$-vector space basis of the Chow ring of $\mathrm{G}(k,n)$. The Chern classes of $S$ (the special Schubert classes $\sigma_{1^i}$, $i=1, \ldots, k$) form a minimal set of generators for the Chow ring of $\mathrm{G}(k,n)$ as a $K$-algebra. See [EH16] for the relations on these generators.

schubert_classMethod
schubert_class(G::AbstractVariety, λ::Int...)
-schubert_class(G::AbstractVariety, λ::Vector{Int})
-schubert_class(G::AbstractVariety, λ::Partition)

Return the Schubert class $\sigma_\lambda$ on a (relative) Grassmannian G.

Examples

julia> G = abstract_grassmannian(2,4)
-AbstractVariety of dim 4
-
-julia> s0 = schubert_class(G, 0)
-1
-
-julia> s1 = schubert_class(G, 1)
--c[1]
-
-julia> s2 = schubert_class(G, 2)
-c[1]^2 - c[2]
-
-julia> s11 = schubert_class(G, [1, 1])
-c[2]
-
-julia> s21 = schubert_class(G, [2, 1])
--c[1]*c[2]
-
-julia> s22 = schubert_class(G, [2, 2])
-c[2]^2
-
-julia> s1*s1 == s2+s11
-true
-
-julia> s1*s2 == s1*s11 == s21
-true
-
-julia> s1*s21 == s2*s2 == s22
-true
-
julia> G = abstract_grassmannian(2,5)
-AbstractVariety of dim 6
-
-julia> s3 = schubert_class(G, 5-2)
--c[1]^3 + 2*c[1]*c[2]
-
-julia> s3^2 == point_class(G)
-true
-
-julia> Q = tautological_bundles(G)[2]
-AbstractBundle of rank 3 on AbstractVariety of dim 6
-
-julia> chern_class(Q, 3)
--c[1]^3 + 2*c[1]*c[2]
-
julia> G = abstract_grassmannian(2,4)
-AbstractVariety of dim 4
-
-julia> s1 = schubert_class(G, 1)
--c[1]
-
-julia> s1 == schubert_class(G, [1, 0])
-true
-
-julia> integral(s1^4)
-2
-
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
schubert_classesMethod
schubert_classes(G::AbstractVariety, m::Int)

Return all Schubert classes in codimension m on a (relative) Grassmannian G.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
schubert_classesMethod
schubert_classes(G::AbstractVariety)

Return all Schubert classes on a (relative) Grassmannian G.

Examples

julia> G = abstract_grassmannian(2,4)
-AbstractVariety of dim 4
-
-julia> schubert_classes(G)
-5-element Vector{Vector{MPolyQuoRingElem{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}}}:
- [1]
- [-c[1]]
- [c[1]^2 - c[2], c[2]]
- [-c[1]*c[2]]
- [c[2]^2]
-
-julia> basis(G)
-5-element Vector{Vector{MPolyQuoRingElem}}:
- [1]
- [c[1]]
- [c[2], c[1]^2]
- [c[1]*c[2]]
- [c[2]^2]
- 
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
diff --git a/previews/PR4245/Experimental/LieAlgebras/cartan_matrix/index.html b/previews/PR4245/Experimental/LieAlgebras/cartan_matrix/index.html deleted file mode 100644 index 2594647e48d6..000000000000 --- a/previews/PR4245/Experimental/LieAlgebras/cartan_matrix/index.html +++ /dev/null @@ -1,31 +0,0 @@ - -Cartan Matrices · Oscar.jl

Cartan Matrices

cartan_matrixMethod
cartan_matrix(fam::Symbol, rk::Int) -> ZZMatrix

Return the Cartan matrix of finite type, where fam is the family ($A$, $B$, $C$, $D$, $E$, $F$ $G$) and rk is the rank of the associated the root system; for $B$ and $C$ the rank has to be at least 2, for $D$ at least 4. The convention is $(a_{ij}) = (\langle \alpha_i^\vee, \alpha_j \rangle)$ for simple roots $\alpha_i$.

Example

julia> cartan_matrix(:B, 2)
-[ 2   -1]
-[-2    2]
-
-julia> cartan_matrix(:C, 2)
-[ 2   -2]
-[-1    2]
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
cartan_matrixMethod
cartan_matrix(type::Tuple{Symbol,Int}...) -> ZZMatrix

Return a block diagonal matrix of indecomposable Cartan matrices as defined by type. For allowed values see cartan_matrix(fam::Symbol, rk::Int).

Example

julia> cartan_matrix((:A, 2), (:B, 2))
-[ 2   -1    0    0]
-[-1    2    0    0]
-[ 0    0    2   -1]
-[ 0    0   -2    2]
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
is_cartan_matrixMethod
is_cartan_matrix(mat::ZZMatrix; generalized::Bool=true) -> Bool

Checks if mat is a generalized Cartan matrix. The keyword argument generalized can be set to false to restrict this to Cartan matrices of finite type.

Example

julia> is_cartan_matrix(ZZ[2 -2; -2 2])
-true
-
-julia> is_cartan_matrix(ZZ[2 -2; -2 2]; generalized=false)
-false
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
cartan_symmetrizerMethod
cartan_symmetrizer(gcm::ZZMatrix; check::Bool=true) -> Vector{ZZRingElem}

Return a vector $d$ of coprime integers such that $(d_i a_{ij})_{ij}$ is a symmetric matrix, where $a_{ij}$ are the entries of the Cartan matrix gcm. The keyword argument check can be set to false to skip verification whether gcm is indeed a generalized Cartan matrix.

Example

julia> cartan_symmetrizer(cartan_matrix(:B, 2))
-2-element Vector{ZZRingElem}:
- 2
- 1
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
cartan_bilinear_formMethod
cartan_bilinear_form(gcm::ZZMatrix; check::Bool=true) -> ZZMatrix

Return the matrix of the symmetric bilinear form associated to the Cartan matrix from cartan_symmetrizer. The keyword argument check can be set to false to skip verification whether gcm is indeed a generalized Cartan matrix.

Example

julia> cartan_bilinear_form(cartan_matrix(:B, 2))
-[ 4   -2]
-[-2    2]
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
cartan_typeMethod
cartan_type(gcm::ZZMatrix; check::Bool=true) -> Vector{Tuple{Symbol, Int}}

Return the Cartan type of a Cartan matrix gcm (currently only Cartan matrices of finite type are supported). This function is left inverse to cartan_matrix, i.e. in the case of isomorphic types (e.g. $B_2$ and $C_2$) the ordering of the roots does matter (see the example below). The keyword argument check can be set to false to skip verification whether gcm is indeed a Cartan matrix of finite type.

The order of returned components is, in general, not unique and might change between versions. If this function is called with the output of cartan_matrix(type), it will keep the order of type.

Example

julia> cartan_type(ZZ[2 -1; -2 2])
-1-element Vector{Tuple{Symbol, Int64}}:
- (:B, 2)
-
-julia> cartan_type(ZZ[2 -2; -1 2])
-1-element Vector{Tuple{Symbol, Int64}}:
- (:C, 2)
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
cartan_type_with_orderingMethod
cartan_type_with_ordering(gcm::ZZMatrix; check::Bool=true) -> Vector{Tuple{Symbol, Int}}, Vector{Int}

Return the Cartan type of a Cartan matrix gcm together with a vector indicating a canonical ordering of the roots in the Dynkin diagram (currently only Cartan matrices of finite type are supported). The keyword argument check can be set to false to skip verification whether gcm is indeed a Cartan matrix of finite type.

The order of returned components and the ordering is, in general, not unique and might change between versions. If this function is called with the output of cartan_matrix(type), it will keep the order of type and the returned ordering will be the identity.

Example

julia> cartan_type_with_ordering(cartan_matrix(:E, 6))
-([(:E, 6)], [1, 2, 3, 4, 5, 6])
-
-julia> cartan_type_with_ordering(ZZ[2 0 -1 0; 0 2 0 -2; -2 0 2 0; 0 -1 0 2])
-([(:B, 2), (:C, 2)], [1, 3, 2, 4])
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
diff --git a/previews/PR4245/Experimental/LieAlgebras/ideals_and_subalgebras/index.html b/previews/PR4245/Experimental/LieAlgebras/ideals_and_subalgebras/index.html deleted file mode 100644 index ba2ccf59b6ae..000000000000 --- a/previews/PR4245/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.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
basisMethod
basis(I::LieAlgebraIdeal) -> Vector{LieAlgebraElem}

Return the basis of the ideal I.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
basisMethod
basis(I::LieAlgebraIdeal, i::Int) -> LieAlgebraElem

Return the i-th basis element of the ideal I.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
inMethod
in(x::LieAlgebraElem{C}, I::LieAlgebraIdeal{C}) -> Bool

Return true if x is in the ideal I, false otherwise.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
bracketMethod
bracket(I1::LieAlgebraIdeal, I2::LieAlgebraIdeal) -> LieAlgebraIdeal

Return $[I_1,I_2]$.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
centralizerMethod
centralizer(L::LieAlgebra, I::LieAlgebraIdeal) -> LieSubalgebra

Return the centralizer of I in L, i.e. $\{x \in L \mid [x, I] = 0\}$.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source

Lie subalgebras

dimMethod
dim(S::LieSubalgebra) -> Int

Return the dimension of the Lie subalgebra S.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
basisMethod
basis(S::LieSubalgebra{C}) -> Vector{LieAlgebraElem{C}}

Return a basis of the Lie subalgebra S.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
basisMethod
basis(S::LieSubalgebra{C}, i::Int) -> LieAlgebraElem{C}

Return the i-th basis element of the Lie subalgebra S.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
inMethod
in(x::LieAlgebraElem{C}, S::LieSubalgebra{C}) -> Bool

Return true if x is in the Lie subalgebra S, false otherwise.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
bracketMethod
bracket(S1::LieSubalgebra, S2::LieSubalgebra) -> LieAlgebraIdeal

Return $[S_1, S_2]$.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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\}$.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
centralizerMethod
centralizer(L::LieAlgebra, S::LieSubalgebra) -> LieSubalgebra

Return the centralizer of S in L, i.e. $\{x \in L \mid [x, S] = 0\}$.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
is_self_normalizingMethod
is_self_normalizing(S::LieSubalgebra) -> Bool

Return true if S is self-normalizing, i.e. if its normalizer is S.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
idealMethod
ideal(L::LieAlgebra, gen::LieAlgebraElem) -> LieAlgebraIdeal

Return the smallest ideal of L containing gen.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
idealMethod
ideal(L::LieAlgebra) -> LieAlgebraIdeal

Return L as an ideal of itself.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
subMethod
sub(L::LieAlgebra, gen::LieAlgebraElem) -> LieSubalgebra

Return the smallest Lie subalgebra of L containing gen.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
subMethod
sub(L::LieAlgebra) -> LieSubalgebra

Return L as a Lie subalgebra of itself.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source

Conversions

lie_algebraMethod
lie_algebra(S::LieSubalgebra) -> LieAlgebra

Return S as a Lie algebra LS, together with an embedding LS -> L, where L is the Lie algebra where S lives in.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
lie_algebraMethod
lie_algebra(I::LieAlgebraIdeal) -> LieAlgebra

Return I as a Lie algebra LI, together with an embedding LI -> L, where L is the Lie algebra where I lives in.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
subMethod
sub(L::LieAlgebra, I::LieAlgebraIdeal) -> LieSubalgebra

Return I as a subalgebra of L.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
diff --git a/previews/PR4245/Experimental/LieAlgebras/introduction/index.html b/previews/PR4245/Experimental/LieAlgebras/introduction/index.html deleted file mode 100644 index 2c28d3890503..000000000000 --- a/previews/PR4245/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 [Hum72].

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/PR4245/Experimental/LieAlgebras/lie_algebra_homs/index.html b/previews/PR4245/Experimental/LieAlgebras/lie_algebra_homs/index.html deleted file mode 100644 index b16f47e74326..000000000000 --- a/previews/PR4245/Experimental/LieAlgebras/lie_algebra_homs/index.html +++ /dev/null @@ -1,45 +0,0 @@ - -Lie algebra homomorphisms · Oscar.jl

Lie algebra homomorphisms

Homomorphisms of Lie algebras in Oscar are represented by the type LieAlgebraHom.

Constructors

Lie algebra homomorphisms $h: L_1 \to L_2$ are constructed by providing either the images of the basis elements of $L_1$ or a $\dim L_1 \times \dim L_2$ matrix.

homMethod
hom(L1::LieAlgebra, L2::LieAlgebra, imgs::Vector{<:LieAlgebraElem}; check::Bool=true) -> LieAlgebraHom

Construct the homomorphism from L1 to L2 by sending the i-th basis element of L1 to imgs[i] and extending linearly. All elements of imgs must lie in L2.

By setting check=false, the linear map is not checked to be compatible with the Lie bracket.

Examples

julia> L1 = special_linear_lie_algebra(QQ, 2);
-
-julia> L2 = special_linear_lie_algebra(QQ, 3);
-
-julia> h = hom(L1, L2, [basis(L2, 1), basis(L2, 4), basis(L2, 7)]) # embed sl_2 into sl_3
-Lie algebra morphism
-  from special linear Lie algebra of degree 2 over QQ
-  to special linear Lie algebra of degree 3 over QQ
-  
-julia> [(x, h(x)) for x in basis(L1)]
-3-element Vector{Tuple{LinearLieAlgebraElem{QQFieldElem}, LinearLieAlgebraElem{QQFieldElem}}}:
- (e_1_2, e_1_2)
- (f_1_2, f_1_2)
- (h_1, h_1)
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
homMethod
hom(L1::LieAlgebra, L2::LieAlgebra, mat::MatElem; check::Bool=true) -> LieAlgebraHom

Construct the homomorphism from L1 to L2 by acting with the matrix mat from the right on the coefficient vector w.r.t. the basis of L1. mat must be a matrix of size dim(L1) \times dim(L2) over coefficient_ring(L2).

By setting check=false, the linear map is not checked to be compatible with the Lie bracket.

Examples

julia> L1 = special_linear_lie_algebra(QQ, 2);
-
-julia> L2 = general_linear_lie_algebra(QQ, 2);
-
-julia> h = hom(L1, L2, matrix(QQ, [0 1 0 0; 0 0 1 0; 1 0 0 -1]))
-Lie algebra morphism
-  from special linear Lie algebra of degree 2 over QQ
-  to general linear Lie algebra of degree 2 over QQ
-
-julia> [(x, h(x)) for x in basis(L1)]
-3-element Vector{Tuple{LinearLieAlgebraElem{QQFieldElem}, LinearLieAlgebraElem{QQFieldElem}}}:
- (e_1_2, x_1_2)
- (f_1_2, x_2_1)
- (h_1, x_1_1 - x_2_2)
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
identity_mapMethod
identity_map(L::LieAlgebra) -> LieAlgebraHom

Construct the identity map on L.

Examples

julia> L = special_linear_lie_algebra(QQ, 3)
-Special linear Lie algebra of degree 3
-  of dimension 8
-over rational field
-
-julia> identity_map(L)
-Lie algebra morphism
-  from special linear Lie algebra of degree 3 over QQ
-  to special linear Lie algebra of degree 3 over QQ
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
zero_mapMethod
zero_map(L1::LieAlgebra, L2::LieAlgebra) -> LieAlgebraHom
-zero_map(L::LieAlgebra) -> LieAlgebraHom

Construct the zero map from L1 to L2 or from L to L.

Examples

julia> L = special_linear_lie_algebra(QQ, 3)
-Special linear Lie algebra of degree 3
-  of dimension 8
-over rational field
-
-julia> zero_map(L)
-Lie algebra morphism
-  from special linear Lie algebra of degree 3 over QQ
-  to special linear Lie algebra of degree 3 over QQ
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source

Functions

The following functions are available for LieAlgebraHoms:

Basic properties

For a homomorphism $h: L_1 \to L_2$, domain(h) and codomain(h) return $L_1$ and $L_2$ respectively.

matrixMethod
matrix(R::Ring, arr::AbstractMatrix{T}) where {T}

Constructs the matrix over $R$ with entries as in arr.

source
matrix(R::Ring, r::Int, c::Int, arr::AbstractVector{T}) where {T}

Constructs the $r \times c$ matrix over $R$, where the entries are taken row-wise from arr.

source

Image

imageMethod
image(h::LieAlgebraHom, x::LieAlgebraElem) -> LieAlgebraElem

Return the image of x under h.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
imageMethod
image(h::LieAlgebraHom) -> LieSubalgebra

Return the image of h as a Lie subalgebra of the codomain.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
imageMethod
image(h::LieAlgebraHom, I::LieAlgebraIdeal) -> LieSubalgebra

Return the image of I under h as a Lie subalgebra of the codomain.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
imageMethod
image(h::LieAlgebraHom, S::LieSubalgebra) -> LieSubalgebra

Return the image of S under h as a Lie subalgebra of the codomain.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source

Kernel

kernelMethod
kernel(h::LieAlgebraHom) -> LieAlgebraIdeal

Return the kernel of h as an ideal of the domain.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source

Composition

composeMethod
compose(f::LieAlgebraHom, g::LieAlgebraHom) -> LieAlgebraHom

Return the composition of f and g, i.e. the homomorphism h such that h(x) = g(f(x)) for all x in the domain of f. The codomain of f must be identical to the domain of g.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source

Inverses

is_isomorphismMethod
is_isomorphism(h::LieAlgebraHom) -> Bool

Return true if h is an isomorphism. This function tries to invert the transformation matrix of h and caches the result. The inverse isomorphism can be cheaply accessed via inv(h) after calling this function.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
invMethod
inv(h::LieAlgebraHom) -> LieAlgebraHom

Return the inverse of h. Requires h to be an isomorphism.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
diff --git a/previews/PR4245/Experimental/LieAlgebras/lie_algebras/index.html b/previews/PR4245/Experimental/LieAlgebras/lie_algebras/index.html deleted file mode 100644 index 9223414f483a..000000000000 --- a/previews/PR4245/Experimental/LieAlgebras/lie_algebras/index.html +++ /dev/null @@ -1,159 +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.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
iszeroMethod
iszero(x::LieAlgebraElem{C}) -> Bool

Check whether the Lie algebra element x is zero.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
dimMethod
dim(L::LieAlgebra) -> Int

Return the dimension of the Lie algebra L.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
basisMethod
basis(L::LieAlgebra{C}) -> Vector{LieAlgebraElem{C}}

Return a basis of the Lie algebra L.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
basisMethod
basis(L::LieAlgebra{C}, i::Int) -> LieAlgebraElem{C}

Return the i-th basis element of the Lie algebra L.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
coefficientsMethod
coefficients(x::LieAlgebraElem{C}) -> Vector{C}

Return the coefficients of x with respect to basis(::LieAlgebra).

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
coeffMethod
coeff(x::LieAlgebraElem{C}, i::Int) -> C

Return the i-th coefficient of x with respect to basis(::LieAlgebra).

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
getindexMethod
getindex(x::LieAlgebraElem{C}, i::Int) -> C

Return the i-th coefficient of x with respect to basis(::LieAlgebra).

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
symbolsMethod
symbols(L::LieAlgebra{C}) -> Vector{Symbol}

Return the symbols used for printing basis elements of the Lie algebra L.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
characteristicMethod
characteristic(L::LieAlgebra) -> Int

Return the characteristic of the coefficient ring of the Lie algebra L.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source

Special functions for LinearLieAlgebras

coerce_to_lie_algebra_elemMethod
coerce_to_lie_algebra_elem(L::LinearLieAlgebra{C}, x::MatElem{C}) -> LinearLieAlgebraElem{C}

Return the element of L whose matrix representation corresponds to x. If no such element exists, an error is thrown.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
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.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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
source
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  ⋅  ⋅  ⋅
source

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)$).

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$.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
is_nilpotentMethod
is_nilpotent(L::LieAlgebra) -> Bool

Return true if L is nilpotent, i.e. the lower central series of L terminates in $0$.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
is_perfectMethod
is_perfect(L::LieAlgebra) -> Bool

Return true if L is perfect, i.e. $[L, L] = L$.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
is_solvableMethod
is_solvable(L::LieAlgebra) -> Bool

Return true if L is solvable, i.e. the derived series of L terminates in $0$.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source

More functions

centerMethod
center(L::LieAlgebra) -> LieAlgebraIdeal

Return the center of L, i.e. $\{x \in L \mid [x, L] = 0\}$

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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\}$.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
centralizerMethod
centralizer(L::LieAlgebra, x::LieAlgebraElem) -> LieSubalgebra

Return the centralizer of x in L, i.e. $\{y \in L \mid [x, y] = 0\}$.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
derived_algebraMethod
derived_algebra(L::LieAlgebra) -> LieAlgebraIdeal

Return the derived algebra of L, i.e. $[L, L]$.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
derived_seriesMethod
derived_series(L::LieAlgebra) -> Vector{LieAlgebraIdeal}

Return the derived series of L, i.e. the sequence of ideals $L^{(0)} = L$, $L^{(i + 1)} = [L^{(i)}, L^{(i)}]$.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
lower_central_seriesMethod
lower_central_series(L::LieAlgebra) -> Vector{LieAlgebraIdeal}

Return the lower central series of L, i.e. the sequence of ideals $L^{(0)} = L$, $L^{(i + 1)} = [L, L^{(i)}]$.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source

Lie algebra constructors

lie_algebraFunction
lie_algebra(gapL::GapObj, s::Vector{<:VarName}) -> 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.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
lie_algebra(R::Field, struct_consts::Matrix{sparse_row_type(R)}, s::Vector{<:VarName}; check::Bool) -> AbstractLieAlgebra{elem_type(R)}

Construct the Lie algebra over the field 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.
  • check: If true, check that the structure constants are anti-symmetric and satisfy the Jacobi identity. This is true by default.
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
lie_algebra(R::Field, struct_consts::Array{elem_type(R),3}, s::Vector{<:VarName}; check::Bool) -> AbstractLieAlgebra{elem_type(R)}

Construct the Lie algebra over the field 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.
  • 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
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
lie_algebra(R::Field, rs::RootSystem) -> AbstractLieAlgebra{elem_type(R)}

Construct a simple Lie algebra over the field R with the root system rs. The internally used basis of this Lie algebra is the Chevalley basis.

The experienced user may supply a boolean vector of length n_positive_roots(rs) - n_simple_roots(rs) via the kwarg extraspecial_pair_signs::Vector{Bool} to specify the concrete Lie algebra to be constructed. If $(\alpha,\beta)$ is the extraspecial pair for the non-simple root root(rs, i), then $\varepsilon_{\alpha,\beta} = 1$ iff extraspecial_pair_signs[i - n_simple_roots(rs)] = true. For the used notation and the definition of extraspecial pairs, see [CMT04].

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
lie_algebra(R::Field, fam::Symbol, rk::Int) -> AbstractLieAlgebra{elem_type(R)}

Construct a simple Lie algebra over the field R with Dynkin type given by fam and rk. See cartan_matrix(fam::Symbol, rk::Int) for allowed combinations. The internally used basis of this Lie algebra is the Chevalley basis.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
lie_algebra(R::Field, n::Int, basis::Vector{<:MatElem{elem_type(R)}}, s::Vector{<:VarName}; check::Bool=true) -> LinearLieAlgebra{elem_type(R)}

Construct the Lie algebra over the field 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 (this is currently not checked). Setting check=false disables these checks (once they are in place).

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
lie_algebra(S::LieSubalgebra) -> LieAlgebra

Return S as a Lie algebra LS, together with an embedding LS -> L, where L is the Lie algebra where S lives in.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
lie_algebra(I::LieAlgebraIdeal) -> LieAlgebra

Return I as a Lie algebra LI, together with an embedding LI -> L, where L is the Lie algebra where I lives in.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source

Classical Lie algebras

abelian_lie_algebraMethod
abelian_lie_algebra(R::Field, n::Int) -> LinearLieAlgebra{elem_type(R)}
-abelian_lie_algebra(::Type{LinearLieAlgebra}, R::Field, n::Int) -> LinearLieAlgebra{elem_type(R)}
-abelian_lie_algebra(::Type{AbstractLieAlgebra}, R::Field, n::Int) -> AbstractLieAlgebra{elem_type(R)}

Return the abelian Lie algebra of dimension n over the field R. The first argument can be optionally provided to specify the type of the returned Lie algebra.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
general_linear_lie_algebraMethod
general_linear_lie_algebra(R::Field, n::Int) -> LinearLieAlgebra{elem_type(R)}

Return the general linear Lie algebra $\mathfrak{gl}_n(R)$, i.e., the Lie algebra of all $n \times n$ matrices over the field 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]
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
special_linear_lie_algebraMethod
special_linear_lie_algebra(R::Field, n::Int) -> LinearLieAlgebra{elem_type(R)}

Return the special linear Lie algebra $\mathfrak{sl}_n(R)$, i.e., the Lie algebra of all $n \times n$ matrices over the field R with trace zero.

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]
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
special_orthogonal_lie_algebraFunction
special_orthogonal_lie_algebra(R::Field, n::Int) -> LinearLieAlgebra{elem_type(R)}
-special_orthogonal_lie_algebra(R::Field, n::Int, gram::MatElem) -> LinearLieAlgebra{elem_type(R)}
-special_orthogonal_lie_algebra(R::Field, n::Int, gram::Matrix) -> LinearLieAlgebra{elem_type(R)}

Return the special orthogonal Lie algebra $\mathfrak{so}_n(R)$.

Given a non-degenerate symmetric bilinear form $f$ via its Gram matrix gram, $\mathfrak{so}_n(R)$ is the Lie algebra of all $n \times n$ matrices $x$ over the field R such that $f(xv, w) = -f(v, xw)$ for all $v, w \in R^n$.

If gram is not provided, for $n = 2k$ the form defined by $\begin{matrix} 0 & I_k \\ -I_k & 0 \end{matrix}$ is used, and for $n = 2k + 1$ the form defined by $\begin{matrix} 1 & 0 & 0 \\ 0 & 0 I_k \\ 0 & I_k & 0 \end{matrix}$.

Examples

julia> L1 = special_orthogonal_lie_algebra(QQ, 4)
-Special orthogonal Lie algebra of degree 4
-  of dimension 6
-over rational field
-
-julia> basis(L1)
-6-element Vector{LinearLieAlgebraElem{QQFieldElem}}:
- x_1
- x_2
- x_3
- x_4
- x_5
- x_6
-
-julia> matrix_repr_basis(L1)
-6-element Vector{QQMatrix}:
- [1 0 0 0; 0 0 0 0; 0 0 -1 0; 0 0 0 0]
- [0 1 0 0; 0 0 0 0; 0 0 0 0; 0 0 -1 0]
- [0 0 0 1; 0 0 -1 0; 0 0 0 0; 0 0 0 0]
- [0 0 0 0; 1 0 0 0; 0 0 0 -1; 0 0 0 0]
- [0 0 0 0; 0 1 0 0; 0 0 0 0; 0 0 0 -1]
- [0 0 0 0; 0 0 0 0; 0 1 0 0; -1 0 0 0]
-
-julia> L2 = special_orthogonal_lie_algebra(QQ, 3, identity_matrix(QQ, 3))
-Special orthogonal Lie algebra of degree 3
-  of dimension 3
-over rational field
-
-julia> basis(L2)
-3-element Vector{LinearLieAlgebraElem{QQFieldElem}}:
- x_1
- x_2
- x_3
-
-julia> matrix_repr_basis(L2)
-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]
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
symplectic_lie_algebraFunction
symplectic_lie_algebra(R::Field, n::Int) -> LinearLieAlgebra{elem_type(R)}
-symplectic_lie_algebra(R::Field, n::Int, gram::MatElem) -> LinearLieAlgebra{elem_type(R)}
-symplectic_lie_algebra(R::Field, n::Int, gram::Matrix) -> LinearLieAlgebra{elem_type(R)}

Return the symplectic Lie algebra $\mathfrak{sp}_n(R)$.

Given a non-degenerate skew-symmetric bilinear form $f$ via its Gram matrix gram, $\mathfrak{sp}_n(R)$ is the Lie algebra of all $n \times n$ matrices $x$ over the field R such that $f(xv, w) = -f(v, xw)$ for all $v, w \in R^n$.

If gram is not provided, for $n = 2k$ the form defined by $\begin{matrix} 0 & I_k \\ -I_k & 0 \end{matrix}$ is used. For odd $n$ there is no non-degenerate skew-symmetric bilinear form on $R^n$.

Examples

julia> L = symplectic_lie_algebra(QQ, 4)
-Symplectic Lie algebra of degree 4
-  of dimension 10
-over rational field
-
-julia> basis(L)
-10-element Vector{LinearLieAlgebraElem{QQFieldElem}}:
- x_1
- x_2
- x_3
- x_4
- x_5
- x_6
- x_7
- x_8
- x_9
- x_10
-
-julia> matrix_repr_basis(L)
-10-element Vector{QQMatrix}:
- [1 0 0 0; 0 0 0 0; 0 0 -1 0; 0 0 0 0]
- [0 1 0 0; 0 0 0 0; 0 0 0 0; 0 0 -1 0]
- [0 0 1 0; 0 0 0 0; 0 0 0 0; 0 0 0 0]
- [0 0 0 1; 0 0 1 0; 0 0 0 0; 0 0 0 0]
- [0 0 0 0; 1 0 0 0; 0 0 0 -1; 0 0 0 0]
- [0 0 0 0; 0 1 0 0; 0 0 0 0; 0 0 0 -1]
- [0 0 0 0; 0 0 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 1 0 0; 1 0 0 0]
- [0 0 0 0; 0 0 0 0; 0 0 0 0; 0 1 0 0]
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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/PR4245/Experimental/LieAlgebras/module_homs/index.html b/previews/PR4245/Experimental/LieAlgebras/module_homs/index.html deleted file mode 100644 index 8e800413423d..000000000000 --- a/previews/PR4245/Experimental/LieAlgebras/module_homs/index.html +++ /dev/null @@ -1,55 +0,0 @@ - -Lie algebra module homomorphisms · Oscar.jl

Lie algebra module homomorphisms

Homomorphisms of Lie algebra modules in Oscar are represented by the type LieAlgebraModuleHom.

Constructors

Homomorphisms of modules over the same Lie algebra $h: V_1 \to V_2$ are constructed by providing either the images of the basis elements of $V_1$ or a $\dim V_1 \times \dim V_2$ matrix.

homMethod
hom(V1::LieAlgebraModule, V2::LieAlgebraModule, imgs::Vector{<:LieAlgebraModuleElem}; check::Bool=true) -> LieAlgebraModuleHom

Construct the homomorphism from V1 to V2 by sending the i-th basis element of V1 to imgs[i] and extending linearly. All elements of imgs must lie in V2. Currently, V1 and V2 must be modules over the same Lie algebra.

By setting check=false, the linear map is not checked to be compatible with the module action.

Examples

julia> L = special_linear_lie_algebra(QQ, 2);
-
-julia> V1 = standard_module(L);
-
-julia> V3 = trivial_module(L, 3);
-
-julia> V2 = direct_sum(V1, V3);
-
-julia> h = hom(V1, V2, [V2([v, zero(V3)]) for v in basis(V1)])
-Lie algebra module morphism
-  from standard module of dimension 2 over L
-  to direct sum module of dimension 5 over L
-
-julia> [(v, h(v)) for v in basis(V1)]
-2-element Vector{Tuple{LieAlgebraModuleElem{QQFieldElem, LinearLieAlgebraElem{QQFieldElem}}, LieAlgebraModuleElem{QQFieldElem, LinearLieAlgebraElem{QQFieldElem}}}}:
- (v_1, v_1^(1))
- (v_2, v_2^(1))
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
homMethod
hom(V1::LieAlgebraModule, V2::LieAlgebraModule, mat::MatElem; check::Bool=true) -> LieAlgebraModuleHom

Construct the homomorphism from V1 to V2 by acting with the matrix mat from the right on the coefficient vector w.r.t. the basis of V1. mat must be a matrix of size dim(V1) \times dim(V2) over coefficient_ring(V2). Currently, V1 and V2 must be modules over the same Lie algebra.

By setting check=false, the linear map is not checked to be compatible with the module action.

Examples

julia> L = general_linear_lie_algebra(QQ, 3);
-
-julia> V1 = standard_module(L);
-
-julia> V2 = trivial_module(L);
-
-julia> h = hom(V1, V2, matrix(QQ, 3, 1, [0, 0, 0]))
-Lie algebra module morphism
-  from standard module of dimension 3 over L
-  to abstract Lie algebra module of dimension 1 over L
-
-julia> [(v, h(v)) for v in basis(V1)]
-3-element Vector{Tuple{LieAlgebraModuleElem{QQFieldElem, LinearLieAlgebraElem{QQFieldElem}}, LieAlgebraModuleElem{QQFieldElem, LinearLieAlgebraElem{QQFieldElem}}}}:
- (v_1, 0)
- (v_2, 0)
- (v_3, 0)
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
identity_mapMethod
identity_map(V::LieAlgebraModule) -> LieAlgebraModuleHom

Construct the identity map on V.

Examples

julia> L = special_linear_lie_algebra(QQ, 3);
-
-julia> V = standard_module(L)
-Standard module
-  of dimension 3
-over special linear Lie algebra of degree 3 over QQ
-
-julia> identity_map(V)
-Lie algebra module morphism
-  from standard module of dimension 3 over L
-  to standard module of dimension 3 over L
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
zero_mapMethod
zero_map(V1::LieAlgebraModule, V2::LieAlgebraModule) -> LieAlgebraModuleHom
-zero_map(V::LieAlgebraModule) -> LieAlgebraModuleHom

Construct the zero map from V1 to V2 or from V to V.

Examples

julia> L = special_linear_lie_algebra(QQ, 3);
-
-julia> V = standard_module(L)
-Standard module
-  of dimension 3
-over special linear Lie algebra of degree 3 over QQ
-
-julia> zero_map(V)
-Lie algebra module morphism
-  from standard module of dimension 3 over L
-  to standard module of dimension 3 over L
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source

Functions

The following functions are available for LieAlgebraModuleHoms:

Basic properties

For a homomorphism $h: V_1 \to V_2$, domain(h) and codomain(h) return $V_1$ and $V_2$ respectively.

matrixMethod
matrix(h::LieAlgebraModuleHom) -> MatElem

Return the transformation matrix of h w.r.t. the bases of the domain and codomain.

Note: The matrix operates on the coefficient vectors from the right.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source

Image

imageMethod
image(h::LieAlgebraModuleHom, v::LieAlgebraModuleElem) -> LieAlgebraModuleElem

Return the image of v under h.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source

Composition

composeMethod
compose(f::LieAlgebraModuleHom, g::LieAlgebraModuleHom) -> LieAlgebraModuleHom

Return the composition of f and g, i.e. the homomorphism h such that h(x) = g(f(x)) for all x in the domain of f. The codomain of f must be identical to the domain of g.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source

Inverses

is_isomorphismMethod
is_isomorphism(h::LieAlgebraModuleHom) -> Bool

Return true if h is an isomorphism. This function tries to invert the transformation matrix of h and caches the result. The inverse isomorphism can be cheaply accessed via inv(h) after calling this function.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
invMethod
inv(h::LieAlgebraModuleHom) -> LieAlgebraModuleHom

Return the inverse of h. Requires h to be an isomorphism.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source

Hom constructions

Lie algebra module homomorphisms support + and - if they have the same domain and codomain.

canonical_injectionsMethod
canonical_injections(V::LieAlgebraModule) -> Vector{LieAlgebraModuleHom}

Return the canonical injections from all components into $V$ where $V$ has been constructed as $V_1 \oplus \cdot \oplus V_n$.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
canonical_injectionMethod
canonical_injection(V::LieAlgebraModule, i::Int) -> LieAlgebraModuleHom

Return the canonical injection $V_i \to V$ where $V$ has been constructed as $V_1 \oplus \cdot \oplus V_n$.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
canonical_projectionsMethod
canonical_projections(V::LieAlgebraModule) -> Vector{LieAlgebraModuleHom}

Return the canonical projections from $V$ to all components where $V$ has been constructed as $V_1 \oplus \cdot \oplus V_n$.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
canonical_projectionMethod
canonical_projection(V::LieAlgebraModule, i::Int) -> LieAlgebraModuleHom

Return the canonical projection $V \to V_i$ where $V$ has been constructed as $V_1 \oplus \cdot \oplus V_n$.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
hom_direct_sumMethod
hom_direct_sum(V::LieAlgebraModule{C}, W::LieAlgebraModule{C}, hs::Matrix{<:LieAlgebraModuleHom}) -> LieAlgebraModuleHom
-hom_direct_sum(V::LieAlgebraModule{C}, W::LieAlgebraModule{C}, hs::Vector{<:LieAlgebraModuleHom}) -> LieAlgebraModuleHom

Given modules V and W which are direct sums with r respective s summands, say $M = M_1 \oplus \cdots \oplus M_r$, $N = N_1 \oplus \cdots \oplus N_s$, and given a $r \times s$ matrix hs of homomorphisms $h_{ij} : V_i \to W_j$, return the homomorphism $V \to W$ with $ij$-components $h_{ij}$.

If hs is a vector, then it is interpreted as a diagonal matrix.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
hom_tensorMethod
hom_tensor(V::LieAlgebraModule{C}, W::LieAlgebraModule{C}, hs::Vector{<:LieAlgebraModuleHom}) -> LieAlgebraModuleHom

Given modules V and W which are tensor products with the same number of factors, say $V = V_1 \otimes \cdots \otimes V_r$, $W = W_1 \otimes \cdots \otimes W_r$, and given a vector hs of homomorphisms $a_i : V_i \to W_i$, return $a_1 \otimes \cdots \otimes a_r$.

This works for $r$th tensor powers as well.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
homMethod
hom(V::LieAlgebraModule{C}, W::LieAlgebraModule{C}, h::LieAlgebraModuleHom) -> LieAlgebraModuleHom

Given modules V and W which are exterior/symmetric/tensor powers of the same kind with the same exponent, say, e.g., $V = S^k V'$, $W = S^k W'$, and given a homomorphism $h : V' \to W'$, return $S^k h: V \to W$ (analogous for other types of powers).

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
diff --git a/previews/PR4245/Experimental/LieAlgebras/modules/index.html b/previews/PR4245/Experimental/LieAlgebras/modules/index.html deleted file mode 100644 index 70d62ae2b322..000000000000 --- a/previews/PR4245/Experimental/LieAlgebras/modules/index.html +++ /dev/null @@ -1,123 +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.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
zeroMethod
zero(V::LieAlgebraModule{C}) -> LieAlgebraModuleElem{C}

Return the zero element of the Lie algebra module V.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
iszeroMethod
iszero(v::LieAlgebraModuleElem{C}) -> Bool

Check whether the Lie algebra module element v is zero.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
dimMethod
dim(V::LieAlgebraModule{C}) -> Int

Return the dimension of the Lie algebra module V.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
basisMethod
basis(V::LieAlgebraModule{C}) -> Vector{LieAlgebraModuleElem{C}}

Return a basis of the Lie algebra module V.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
basisMethod
basis(V::LieAlgebraModule{C}, i::Int) -> LieAlgebraModuleElem{C}

Return the i-th basis element of the Lie algebra module V.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
coefficientsMethod
coefficients(v::LieAlgebraModuleElem{C}) -> Vector{C}

Return the coefficients of v with respect to basis(::LieAlgebraModule).

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
coeffMethod
coeff(v::LieAlgebraModuleElem{C}, i::Int) -> C

Return the i-th coefficient of v with respect to basis(::LieAlgebraModule).

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
getindexMethod
getindex(v::LieAlgebraModuleElem{C}, i::Int) -> C

Return the i-th coefficient of v with respect to basis(::LieAlgebraModule).

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
symbolsMethod
symbols(V::LieAlgebraModule{C}) -> Vector{Symbol}

Return the symbols used for printing basis elements of the Lie algebra module V.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source

Module constructors

trivial_moduleFunction
trivial_module(L::LieAlgebra{C}, d=1) -> LieAlgebraModule{C}

Construct the d-dimensional module of the Lie algebra L with trivial action.

Examples

julia> L = special_linear_lie_algebra(QQ, 3);
-
-julia> trivial_module(L)
-Abstract Lie algebra module
-  of dimension 1
-over special linear Lie algebra of degree 3 over QQ
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
standard_moduleMethod
standard_module(L::LinearLieAlgebra{C}; cached::Bool=true) -> 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.

Note

This uses the left action of $L$, and converts that to internally use the equivalent right action.

Examples

julia> L = special_linear_lie_algebra(QQ, 3);
-
-julia> standard_module(L)
-Standard module
-  of dimension 3
-over special linear Lie algebra of degree 3 over QQ
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
dualMethod
dual(V::LieAlgebraModule{C}; cached::Bool=true) -> LieAlgebraModule{C}

Construct the dual module of V.

Examples

julia> L = special_linear_lie_algebra(QQ, 3);
-
-julia> V = exterior_power(standard_module(L), 2)[1]; # some module
-
-julia> dual(V)
-Dual module
-  of dimension 3
-  dual of
-    2nd exterior power of
-      standard module
-over special linear Lie algebra of degree 3 over QQ
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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

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

Examples

julia> L = special_linear_lie_algebra(QQ, 3);
-
-julia> V1 = exterior_power(standard_module(L), 2)[1]; # some module
-
-julia> V2 = symmetric_power(standard_module(L), 3)[1]; # some module
-
-julia> direct_sum(V1, V2)
-Direct sum module
-  of dimension 13
-  direct sum with direct summands
-    2nd exterior power of
-      standard module
-    3rd symmetric power of
-      standard module
-over special linear Lie algebra of degree 3 over QQ
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
tensor_productMethod
tensor_product(Vs::LieAlgebraModule{C}...) -> LieAlgebraModule{C}
-⊗(Vs::LieAlgebraModule{C}...) -> LieAlgebraModule{C}

Given modules $V_1,\dots,V_n$ over the same Lie algebra $L$, construct their tensor product $V_1 \otimes \cdots \otimes V_n$.

Examples

julia> L = special_linear_lie_algebra(QQ, 3);
-
-julia> V1 = exterior_power(standard_module(L), 2)[1]; # some module
-
-julia> V2 = symmetric_power(standard_module(L), 3)[1]; # some module
-
-julia> tensor_product(V1, V2)
-Tensor product module
-  of dimension 30
-  tensor product with tensor factors
-    2nd exterior power of
-      standard module
-    3rd symmetric power of
-      standard module
-over special linear Lie algebra of degree 3 over QQ
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
exterior_powerMethod
exterior_power(V::LieAlgebraModule{C}, k::Int; cached::Bool=true) -> LieAlgebraModule{C}, Map

Construct the k-th exterior power $\bigwedge^k (V)$ of the module V, together with a map that computes the wedge product of k elements of V.

Examples

julia> L = special_linear_lie_algebra(QQ, 2);
-
-julia> V = symmetric_power(standard_module(L), 2)[1]; # some module
-
-julia> E, map = exterior_power(V, 2)
-(Exterior power module of dimension 3 over L, Map: parent of tuples of type Tuple{LieAlgebraModuleElem{QQFieldElem, LinearLieAlgebraElem{QQFieldElem}}, LieAlgebraModuleElem{QQFieldElem, LinearLieAlgebraElem{QQFieldElem}}} -> E)
-
-julia> E
-Exterior power module
-  of dimension 3
-  2nd exterior power of
-    2nd symmetric power of
-      standard module
-over special linear Lie algebra of degree 2 over QQ
-
-julia> basis(E)
-3-element Vector{LieAlgebraModuleElem{QQFieldElem, LinearLieAlgebraElem{QQFieldElem}}}:
- (v_1^2)^(v_1*v_2)
- (v_1^2)^(v_2^2)
- (v_1*v_2)^(v_2^2)
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
symmetric_powerMethod
symmetric_power(V::LieAlgebraModule{C}, k::Int; cached::Bool=true) -> LieAlgebraModule{C}, Map

Construct the k-th symmetric power $S^k (V)$ of the module V, together with a map that computes the product of k elements of V.

Examples

julia> L = special_linear_lie_algebra(QQ, 4);
-
-julia> V = exterior_power(standard_module(L), 3)[1]; # some module
-
-julia> S, map = symmetric_power(V, 2)
-(Symmetric power module of dimension 10 over L, Map: parent of tuples of type Tuple{LieAlgebraModuleElem{QQFieldElem, LinearLieAlgebraElem{QQFieldElem}}, LieAlgebraModuleElem{QQFieldElem, LinearLieAlgebraElem{QQFieldElem}}} -> S)
-
-julia> S
-Symmetric power module
-  of dimension 10
-  2nd symmetric power of
-    3rd exterior power of
-      standard module
-over special linear Lie algebra of degree 4 over QQ
-
-julia> basis(S)
-10-element Vector{LieAlgebraModuleElem{QQFieldElem, LinearLieAlgebraElem{QQFieldElem}}}:
- (v_1^v_2^v_3)^2
- (v_1^v_2^v_3)*(v_1^v_2^v_4)
- (v_1^v_2^v_3)*(v_1^v_3^v_4)
- (v_1^v_2^v_3)*(v_2^v_3^v_4)
- (v_1^v_2^v_4)^2
- (v_1^v_2^v_4)*(v_1^v_3^v_4)
- (v_1^v_2^v_4)*(v_2^v_3^v_4)
- (v_1^v_3^v_4)^2
- (v_1^v_3^v_4)*(v_2^v_3^v_4)
- (v_2^v_3^v_4)^2
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
tensor_powerMethod
tensor_power(V::LieAlgebraModule{C}, k::Int; cached::Bool=true) -> LieAlgebraModule{C}, Map

Construct the k-th tensor power $T^k (V)$ of the module V, together with a map that computes the tensor product of k elements of V.

Examples

julia> L = special_linear_lie_algebra(QQ, 3);
-
-julia> V = exterior_power(standard_module(L), 2)[1]; # some module
-
-julia> T, map = tensor_power(V, 2)
-(Tensor power module of dimension 9 over L, Map: parent of tuples of type Tuple{LieAlgebraModuleElem{QQFieldElem, LinearLieAlgebraElem{QQFieldElem}}, LieAlgebraModuleElem{QQFieldElem, LinearLieAlgebraElem{QQFieldElem}}} -> T)
-
-julia> T
-Tensor power module
-  of dimension 9
-  2nd tensor power of
-    2nd exterior power of
-      standard module
-over special linear Lie algebra of degree 3 over QQ
-
-julia> basis(T)
-9-element Vector{LieAlgebraModuleElem{QQFieldElem, LinearLieAlgebraElem{QQFieldElem}}}:
- (v_1^v_2)(x)(v_1^v_2)
- (v_1^v_2)(x)(v_1^v_3)
- (v_1^v_2)(x)(v_2^v_3)
- (v_1^v_3)(x)(v_1^v_2)
- (v_1^v_3)(x)(v_1^v_3)
- (v_1^v_3)(x)(v_2^v_3)
- (v_2^v_3)(x)(v_1^v_2)
- (v_2^v_3)(x)(v_1^v_3)
- (v_2^v_3)(x)(v_2^v_3)
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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 right 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.
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
abstract_moduleMethod
abstract_module(L::LieAlgebra{C}, dimV::Int, struct_consts::Matrix{sparse_row_type{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.
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
diff --git a/previews/PR4245/Experimental/LinearQuotients/cox_rings/index.html b/previews/PR4245/Experimental/LinearQuotients/cox_rings/index.html deleted file mode 100644 index c12196f87e89..000000000000 --- a/previews/PR4245/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 [AG10], 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$.

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.

Let G = group(L) and let H be the subgroup generated by the pseudo-reflections contained in G. By a theorem of Arzhantsev–Gaifullin [AG10], the Cox ring is graded isomorphic to the invariant ring of the group H[G,G], where [G,G] is the derived subgroup of G. We use ideas from [DK17] 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.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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 [Yam18].

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 [Yam18].

source
diff --git a/previews/PR4245/Experimental/LinearQuotients/introduction/index.html b/previews/PR4245/Experimental/LinearQuotients/introduction/index.html deleted file mode 100644 index a2dc6849ad87..000000000000 --- a/previews/PR4245/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/PR4245/Experimental/LinearQuotients/linear_quotients/index.html b/previews/PR4245/Experimental/LinearQuotients/linear_quotients/index.html deleted file mode 100644 index 00428a43a756..000000000000 --- a/previews/PR4245/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.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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 pseudo-reflections contained in the group $G$, see [Ben93].

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 pseudo-reflections.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source

Singularities

One can study the types of the singularities of a linear quotient as follows.

has_canonical_singularitiesMethod
has_canonical_singularities(L::LinearQuotient)

Return true if L has canonical singularities, false otherwise.

This is checked using the Reid–Tai criterion, see Theorem 3.21 in [Kol13].

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
has_terminal_singularitiesMethod
has_terminal_singularities(L::LinearQuotient)

Return true if L has terminal singularities, false otherwise.

This is checked using the Reid–Tai criterion, see Theorem 3.21 in [Kol13].

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
diff --git a/previews/PR4245/Experimental/MatroidRealizationSpaces/introduction/index.html b/previews/PR4245/Experimental/MatroidRealizationSpaces/introduction/index.html deleted file mode 100644 index b7c72048eb30..000000000000 --- a/previews/PR4245/Experimental/MatroidRealizationSpaces/introduction/index.html +++ /dev/null @@ -1,109 +0,0 @@ - -Matroid Realization Spaces · Oscar.jl

Matroid Realization Spaces

Let $M$ be a matroid of rank $d$ on a ground set $E$ of size $n$. Its realization space $\mathcal{R}(M)$ is an affine scheme that parameterizes all hyperplane arrangements that realize the matroid $M$ (up to the action of $PGL(r)$). We provide functions that determine the affine coordinate ring of $\mathcal{R}(M)$.

is_realizableMethod
is_realizable(M; char::Union{Int,Nothing}=nothing, q::Union{Int,Nothing}=nothing)
  • If char = nothing, then this function determines whether the matroid is realizable over some field.

  • If char == 0, then this function determines whether the matroid is realizable over some field of characteristic 0.

  • If char = p is prime, this function determines whether the matroid is realizable over the finite field $GF(p)$.

  • If char == p and q is a power of p, this function determines whether the matroid is realizable over the finite field $GF(q)$.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
defining_idealMethod
defining_ideal(RS::MatroidRealizationSpace)

The ideal of the matroid realization space RS.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
inequationsMethod
inequations(RS::MatroidRealizationSpace)

Generators of the localizing semigroup of RS. These are the polynomials that need to be nonzero in any realization.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
ambient_ringMethod
ambient_ring(RS::MatroidRealizationSpace)

The polynomial ring containing the ideal defining_ideal(RS) and the polynomials in inequations(RS).

source
realization_spaceMethod
realization_space(
-  M::Matroid;
-  B::Union{GroundsetType,Nothing}=nothing,
-  saturate::Bool=false,
-  simplify::Bool=true,
-  char::Union{Int,Nothing}=nothing,
-  q::Union{Int,Nothing}=nothing,
-  ground_ring::Ring=ZZ
-)::MatroidRealizationSpace

This function returns the data for the coordinate ring of the matroid realization space of the matroid M as a MatroidRealizationSpace. This function has several optional parameters.

  • B is a basis of M that specifies which columns of realization_matrix(M) form an identity matrix. The default is nothing, in which case the basis is chosen for you.

  • saturate determines whether defining_ideal(M) should be saturated with respect to the semigroup generated by inequations(M). The default is false. The saturation can be rather slow for large instances.

  • simplify determines whether a reduced realization space is returned which means that the equations are used to eliminate variables as far as possible. The default is true.

  • char specifies the characteristic of the coefficient ring. The returned realization space is then the space of all realizations over fields of characteristic char. The default is nothing.

  • q is an integer and assumed to be a prime power q=p^k. The returned realization space is then the space of all realizations over the field $GF(p^k)$. The default is nothing.

  • ground_ring is a ring and specifies the groundring over which one wants to consider the realization space, e.g. QQ or GF(p). The groudring ZZ means that we compute the space of realizations over all fields. The default is ZZ.

Examples

julia> M = fano_matroid();
-
-julia> RS = realization_space(M)
-The realization space is
-  [0   1   1   1   1   0   0]
-  [1   0   1   1   0   1   0]
-  [1   0   1   0   1   0   1]
-in the integer ring
-within the vanishing set of the ideal
-2ZZ
-
-julia> realization_space(non_fano_matroid())
-The realization space is
-  [1   1   0   0   1   1   0]
-  [0   1   1   1   1   0   0]
-  [0   1   1   0   0   1   1]
-in the integer ring
-avoiding the zero loci of the polynomials
-RingElem[2]
-
-julia> realization_space(pappus_matroid(), char=0)
-The realization space is
-  [1   0   1   0   x2   x2                 x2^2    1    0]
-  [0   1   1   0    1    1   -x1*x2 + x1 + x2^2    1    1]
-  [0   0   0   1   x2   x1                x1*x2   x1   x2]
-in the multivariate polynomial ring in 2 variables over QQ
-avoiding the zero loci of the polynomials
-RingElem[x1 - x2, x2, x1, x2 - 1, x1 + x2^2 - x2, x1 - 1, x1*x2 - x1 - x2^2]
-
-julia> realization_space(uniform_matroid(3,6))
-The realization space is
-  [1   0   0   1    1    1]
-  [0   1   0   1   x1   x3]
-  [0   0   1   1   x2   x4]
-in the multivariate polynomial ring in 4 variables over ZZ
-avoiding the zero loci of the polynomials
-RingElem[x1*x4 - x2*x3, x2 - x4, x1 - x3, x1*x4 - x1 - x2*x3 + x2 + x3 - x4, x3 - x4, x4 - 1, x3 - 1, x3, x4, x1 - x2, x2 - 1, x1 - 1, x1, x2]
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
realizationMethod
realization(M::Matroid; B::Union{GroundsetType,Nothing} = nothing,
-  saturate::Bool=false,
-  char::Union{Int,Nothing}=nothing, q::Union{Int,Nothing}=nothing
-)::MatroidRealizationSpace

This function tries to find one realization in the matroid realization space of the matroid M. The output is again a MatroidRealizationSpace.

If the matroid is only realizable over an extension of the prime field the extension field is specified as a splitting field of an irreducible polynomial. Every root of this polynomial gives an equivalent realization of the matroid.

This function has several optional parameters. Note that one must input either the characteristic or a specific field of definition for the realization.

  • B is a basis of M that specifies which columns of realization_matrix(M) form the identity matrix. The default is nothing, in which case the basis is chosen for you.

  • char specifies the characteristic of the coefficient ring, and is used to determine if the matroid is realizable over a field of this characteristic. The default is nothing.

  • q is an integer, and when char = p, this input is used to determine whether the matroid is realizable over the finite field $GF(p^{q})$. The default is nothing.

  • reduce determines whether a reduced realization space is returned which means that the equations are used to eliminate variables as far as possible. The default is true.

  • saturate determines whether defining_ideal(M) should be saturated with respect to the semigroup generated by inequations(M). The default is false. This can be rather slow for large instances.

Examples

julia> realization(pappus_matroid(), char=0)
-One realization is given by
-  [1   0   1   0   2   2   4   1   0]
-  [0   1   1   0   1   1   1   1   1]
-  [0   0   0   1   2   3   6   3   2]
-in the rational field
-
-julia> realization(pappus_matroid(), q=4)
-One realization is given by
-  [1   0   1   0   x1 + 1   x1 + 1   x1    1        0]
-  [0   1   1   0        1        1    1    1        1]
-  [0   0   0   1   x1 + 1       x1    1   x1   x1 + 1]
-in the multivariate polynomial ring in 1 variable over GF(2)
-within the vanishing set of the ideal
-Ideal (x1^2 + x1 + 1)
-
-julia> realization(uniform_matroid(3,6), char=5)
-One realization is given by
-  [1   0   0   1   1   1]
-  [0   1   0   1   4   3]
-  [0   0   1   1   3   2]
-in the prime field of characteristic 5
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
realizationMethod
realization(RS::MatroidRealizationSpace)

This function tries to find one realization in the matroid realization RS. The output is again a MatroidRealizationSpace.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source

If $B$ is the polynomial ring ambient_ring(RS), $I$ the ideal defining_ideal(RS), and $U$ the multiplicative semigroup generated by inequations(RS), then the coordinate ring of the realization space $\mathcal{R}(M)$ is isomorphic to $U^{-1}B/I$.

Matroid realization spaces as affine schemes

Every MatroidRealizationSpace is an instance of an affine scheme. For those cases where implementations exist, the entire functionality provided for AbsAffineSchemes applies to matroid realization spaces. For example:

julia> RM = realization_space(pappus_matroid(), ground_ring=QQ)
-The realization space is
-  [1   0   1   0   x2   x2                 x2^2    1    0]
-  [0   1   1   0    1    1   -x1*x2 + x1 + x2^2    1    1]
-  [0   0   0   1   x2   x1                x1*x2   x1   x2]
-in the multivariate polynomial ring in 2 variables over QQ
-avoiding the zero loci of the polynomials
-RingElem[x1 - x2, x2, x1, x2 - 1, x1 + x2^2 - x2, x1 - 1, x1*x2 - x1 - x2^2]
-
-julia> OO(RM)
-Localization
-  of quotient
-    of multivariate polynomial ring in 2 variables x1, x2
-      over rational field
-    by ideal (0)
-  at products of (x1 - x2, x2, x1, x2 - 1, x1 + x2^2 - x2, x1 - 1, x1*x2 - x1 - x2^2)
-
-julia> is_smooth(RM) # Calls the generic routine implemented for schemes
-true
-
-julia> x, y = gens(OO(RM)); I = ideal(OO(RM), [x - 4, y^2 - 8]);
-
-julia> pr = blow_up(RM, I)
-Blowup
-  of scheme over QQ covered with 1 patch
-    1b: [x1, x2]   scheme(0) \ scheme((x1 - x2)*x2*x1*(x2 - 1)*(x1 + x2^2 - x2)*(x1 - 1)*(x1*x2 - x1 - x2^2))
-  in sheaf of ideals with restriction
-    1b: Ideal (x1 - 4, x2^2 - 8)
-with domain
-  scheme over QQ covered with 2 patches
-    1a: [(s1//s0), x1, x2]   scheme(-(s1//s0)*x1 + 4*(s1//s0) + x2^2 - 8) \ scheme((x1 - x2)*x2*x1*(x2 - 1)*(x1 - 1)*(x1 + x2^2 - x2)*(x1*x2 - x1 - x2^2))
-    2a: [(s0//s1), x2]       scheme(0) \ scheme(((s0//s1)*x2^2 - 8*(s0//s1) - x2 + 4)*x2*((s0//s1)*x2^2 - 8*(s0//s1) + 4)*(x2 - 1)*((s0//s1)*x2^2 - 8*(s0//s1) + 3)*((s0//s1)*x2^2 - 8*(s0//s1) + x2^2 - x2 + 4)*((s0//s1)*x2^3 - (s0//s1)*x2^2 - 8*(s0//s1)*x2 + 8*(s0//s1) - x2^2 + 4*x2 - 4))
-and exceptional divisor
-  effective cartier divisor defined by
-    sheaf of ideals with restrictions
-      1a: Ideal (x1 - 4)
-      2a: Ideal (x2^2 - 8)
-      
-julia> first(affine_charts(codomain(pr))) === RM
-true

Note, however, that there are also cases which are not covered. For instance, one realization of the fano_matroid() is $\mathrm{Spec}(\mathbb Z/2 \mathbb Z)$ which is not (yet) supported by the schemes framework.

diff --git a/previews/PR4245/Experimental/OrthogonalDiscriminants/access/index.html b/previews/PR4245/Experimental/OrthogonalDiscriminants/access/index.html deleted file mode 100644 index a624480539fb..000000000000 --- a/previews/PR4245/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,

  • degree, with value a positive integer, meaning entries only for characters whose character field has the given degree over its prime field,

  • 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
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
orthogonal_discriminantsFunction
orthogonal_discriminants(tbl::Oscar.GAPGroupCharacterTable)

Return a vector of strings that describe the orthogonal discriminants of the orthogonal irreducible characters of tbl of even degree.

The length of this vector is the number of irreducible characters of tbl, the $i$-th entry is an empty string if the $i$-th character is not orthogonal or has odd degree, and the $i$-th entry is equal to "?" if the orthogonal discriminant is unknown.

Examples

julia> t = character_table("A6");
-
-julia> println(orthogonal_discriminants(t))
-["", "", "", "1", "1", "", "-1"]
-
-julia> println(orthogonal_discriminants(t % 3))
-["", "", "", "O-", ""]
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
orthogonal_discriminantFunction
orthogonal_discriminant(chi::Oscar.GAPGroupClassFunction)

Return a string that describes the orthogonal discriminant of chi:

  • "?" if the value is unknown,
  • one of "O+", "O-" in positive characteristic,
  • something that can be evaluated with atlas_irrationality in characteristic 0, and
  • "" if `chi is not irreducible, not orthogonal, or has odd degree.

Examples

julia> t = character_table("A6");
-
-julia> orthogonal_discriminant(t[4])
-"1"
-
-julia> t2 = t % 2;
-
-julia> orthogonal_discriminant(t2[4])
-"O+"
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
diff --git a/previews/PR4245/Experimental/OrthogonalDiscriminants/compute/index.html b/previews/PR4245/Experimental/OrthogonalDiscriminants/compute/index.html deleted file mode 100644 index 1609ce9bf035..000000000000 --- a/previews/PR4245/Experimental/OrthogonalDiscriminants/compute/index.html +++ /dev/null @@ -1,43 +0,0 @@ - -Criteria for computing orthogonal discriminants · Oscar.jl

Criteria for computing orthogonal discriminants

Direct methods

od_from_atlas_groupFunction
od_from_atlas_group(chi::GAPGroupClassFunction)

Return (flag, val) where flag is true if the function can compute the orthogonal discriminant of chi. In this case, val is a string that describes the orthogonal discriminant of chi.

Otherwise flag is false and val is "".

The former case happens if chi is absolutely irreducible, has even degree and indicator +, and the Atlas of Group Representations contains a representation affording chi, over the character field of chi or (in odd characteristic) a suitable extension field.

If the characteristic of chi is $2$ then we know no better method than calling orthogonal_sign. Otherwise we try to find an invertible skew-symmetric endomorphism w.r.t. the invariant bilinear form of the representation, with random methods.

julia> t = character_table("A6");
-
-julia> Oscar.OrthogonalDiscriminants.od_from_atlas_group(t[7])
-(true, "-1")
-
-julia> Oscar.OrthogonalDiscriminants.od_from_atlas_group(mod(t, 3)[4])
-(true, "O-")
-
-julia> t = character_table("L2(27)");
-
-julia> Oscar.OrthogonalDiscriminants.od_from_atlas_group(t[4])
-(false, "")
source

Character-theoretical criteria

od_from_orderFunction
od_from_order(chi::GAPGroupClassFunction)

Return (flag, val) where flag is true if the order of the group of chi divides only one of the orders of the two orthogonal groups omega_group(+/-1, d, q), where d is the degree of chi and q is the order of the field of definition of chi.

In this case, val is "O+" or "O-".

julia> t = character_table("L3(2)");
-
-julia> Oscar.OrthogonalDiscriminants.od_from_order(mod(t, 3)[4])
-(true, "O-")
-
-julia> Oscar.OrthogonalDiscriminants.od_from_order(mod(t, 2)[4])
-(false, "")
source
od_from_eigenvaluesFunction
od_from_eigenvalues(chi::GAPGroupClassFunction)

Return (flag, val) where flag is true if there is a conjugacy class on which representing matrices for chi have no eigenvalue $\pm 1$. In this case, if chi is orthogonally stable (this is not checked here) then val is a string that describes the orthogonal discriminant of chi.

If flag is false then val is equal to "".

This criterion works only if the characteristic of chi is not $2$, (false, "") is returned if the characteristic is $2$.

Examples

julia> t = character_table("A5");
-
-julia> Oscar.OrthogonalDiscriminants.od_from_eigenvalues(t[4])
-(true, "5")
-
-julia> Oscar.OrthogonalDiscriminants.od_from_eigenvalues(mod(t, 3)[4])
-(true, "O-")
-
-julia> Oscar.OrthogonalDiscriminants.od_from_eigenvalues(mod(t, 2)[4])
-(false, "")
source
od_for_specht_moduleFunction
od_for_specht_module(chi::GAPGroupClassFunction)

Return (flag, val) where flag is true if chi is an ordinary irreducible character of a symmetric group or of an alternating group such that chi extends to the corresponding symmetric group. In this case, if chi is orthogonally stable (this is not checked here) then val is a string that describes the orthogonal discriminant of chi; the discriminant is computed using the Jantzen-Schaper formula, via gram_determinant_specht_module.

(false, "") is returned in all cases where this criterion is not applicable.

Examples

julia> t = character_table("A5");
-
-julia> Oscar.OrthogonalDiscriminants.od_for_specht_module(t[4])
-(true, "5")
-
-julia> Oscar.OrthogonalDiscriminants.od_for_specht_module(mod(t, 3)[4])
-(false, "")
source
od_from_p_subgroupMethod
od_from_p_subgroup(chi::GAPGroupClassFunction, p::Int[, pi::GAPGroupClassFunction])

Let chi be an irreducible (ordinary or Brauer) character of the group $G$, and p be an odd prime integer.

Return (flag, val) where flag is true if and only if enough information can be computed to prove that the restriction of chi to a Sylow p-subgroup $P$ is orthogonally stable. In this case, val is a string that describes the orthogonal discriminant of chi.

If flag is false then val is equal to "".

If a character is given as the optional argument pi then it is assumed that pi is the permutation character of $G$ induced from $P$. Otherwise the function tries to compute the possible permutation characters.

Examples

julia> t = character_table("A5");
-
-julia> Oscar.OrthogonalDiscriminants.od_from_p_subgroup(t[4], 5)
-(true, "5")
-
-julia> Oscar.OrthogonalDiscriminants.od_from_p_subgroup(mod(t, 3)[4], 5)
-(true, "O-")
-
-julia> Oscar.OrthogonalDiscriminants.od_from_p_subgroup(mod(t, 2)[4], 5)
-(true, "O-")
source
diff --git a/previews/PR4245/Experimental/OrthogonalDiscriminants/introduction/index.html b/previews/PR4245/Experimental/OrthogonalDiscriminants/introduction/index.html deleted file mode 100644 index e16c2d1f8fc3..000000000000 --- a/previews/PR4245/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/PR4245/Experimental/OrthogonalDiscriminants/misc/index.html b/previews/PR4245/Experimental/OrthogonalDiscriminants/misc/index.html deleted file mode 100644 index a2db2dbda59e..000000000000 --- a/previews/PR4245/Experimental/OrthogonalDiscriminants/misc/index.html +++ /dev/null @@ -1,39 +0,0 @@ - -Miscellaneous functions · Oscar.jl

Miscellaneous functions

Utilities

is_orthogonally_stableFunction
is_orthogonally_stable(chi::GAPGroupClassFunction; check::Bool = true)

Return nothing if the indicator of some irreducible constituent of chi is not known; this can happen only if chi has characteristic 2.

Otherwise return true if chi is orthogonally stable, and false otherwise.

A character is called orthogonally stable if

  • chi is orthogonal, that is, chi is real, and all its absolutely irreducible constituents of indicator - have even multiplicity and
  • all its absolutely irreducible constituents of indicator + have even degree.

If we know that chi is orthogonal then we can set check to false; in this case, some nothing results can be avoided.

Examples

julia> t = character_table("A6");
-
-julia> println(map(is_orthogonally_stable, t))
-Bool[0, 0, 0, 1, 1, 0, 1]
-
-julia> println(map(is_orthogonally_stable, mod(t, 3)))
-Bool[0, 0, 0, 1, 0]
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
show_with_ODsFunction
show_with_ODs(tbl::Oscar.GAPGroupCharacterTable)

Show tbl with 2nd indicators, known ODs, and degrees of character fields. (See Base.show(io::IO, ::MIME"text/plain", tbl::Oscar.GAPGroupCharacterTable) for ways to modify what is shown.)

Examples

julia> t = character_table("A5");
-
-julia> Oscar.OrthogonalDiscriminants.show_with_ODs(t)
-A5
-
-          2  2  2  .  .  .
-          3  1  .  1  .  .
-          5  1  .  .  1  1
-                          
-            1a 2a 3a 5a 5b
-         2P 1a 1a 3a 5b 5a
-         3P 1a 2a 1a 5b 5a
-         5P 1a 2a 3a 1a 1a
-    d OD  2               
-X_1 1     +  1  1  1  1  1
-X_2 2     +  3 -1  .  A A*
-X_3 2     +  3 -1  . A*  A
-X_4 1  5  +  4  .  1 -1 -1
-X_5 1     +  5  1 -1  .  .
-
-A = z_5^3 + z_5^2 + 1
-A* = -z_5^3 - z_5^2
source
show_OD_infoFunction
show_OD_info(tbl::Oscar.GAPGroupCharacterTable)
-show_OD_info(name::String)

Show an overview of known information about the ordinary and modular orthogonal discriminants for tbl or for the character table with identifier name.

Examples

julia> show_OD_info("A5")
-A5:  2^2*3*5
-------------
-
-i|chi|K|disc| 2| 3|       5
--+---+-+----+--+--+--------
-4| 4a|Q|   5|4a|4a|(def. 1)
- |   | |    |O-|O-|        
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
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]
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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]]
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
diff --git a/previews/PR4245/Experimental/PartitionedPermutations/introduction/index.html b/previews/PR4245/Experimental/PartitionedPermutations/introduction/index.html deleted file mode 100644 index ff2cd6da7f05..000000000000 --- a/previews/PR4245/Experimental/PartitionedPermutations/introduction/index.html +++ /dev/null @@ -1,14 +0,0 @@ - -Partitioned Permutations · Oscar.jl

Partitioned Permutations

Partitioned Permutations are used in the context of Free Probability Theory to model higher order freeness and higher order free cumulants, see e.g. [CMS07].

We provide basic functions for working with partitioned permutations. The focus is on factorizing partitioned permutations.

Basics

Formally, a partitioned permutation $(V, \pi)$ consists of a permutation $\pi$ and a partition $V$ of the set $\{1, ..., n\}$ such that the partition dominates the permutation in the sense that every cycle of $\pi$ is contained in one block of $V$. We call $n$ the length of $(V, \pi)$. Mathematically, another length function is more important. It is given by $|(V, \pi)| := n - ( 2 \cdot \text{number of blocks of } V - \text{number of cycles of } \pi),$ and we call this the adjusted length of $(V, \pi)$. Note that this terminology is not used in the literature.

PartitionedPermutationType
PartitionedPermutation

The type of partitioned permutations. Fieldnames are

  • p::PermGroupElem - a permutation
  • V::SetPartition - a partition

If the permutation has length n, then the partition must have n upper points and 0 lower points. Further, if W is the partition given by the cycles of p, then W must be dominated by V in the sense that every block of W is contained in one block of V. There is one inner constructer of PartitionedPermutation:

  • PartitionedPermutation(p::PermGroupElem, V::Vector{Int}) constructs the partitioned permutation where the partition is given by the vector V.

If the optional flag check is set to false, then the constructor skips the validation of the requirements mentioned above.

Examples

julia> PartitionedPermutation(perm(symmetric_group(3), [2, 1, 3]), [1, 1, 2])
-PartitionedPermutation((1,2), SetPartition([1, 1, 2], Int64[]))
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
lengthMethod
length(pp::PartitionedPermutation)

Return the length of a partitioned permutation, i.e. the size of the underlying set.

Examples

julia> length(partitioned_permutation(perm(symmetric_group(2), [2, 1]), [1, 1]))
-2
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
adjusted_lengthMethod
adjusted_length(pp::PartitionedPermutation)

Return the adjusted length of a partitioned permutation as described in [CMS07] as |(V, pi)| for a partition V and a permutation pi.

Examples

julia> adjusted_length(partitioned_permutation(perm(symmetric_group(2), [2, 1]), [1, 1]))
-1
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source

Products of Partitioned Permutations

For two partitioned permutations $(V, \pi)$ and $(W, \sigma)$ one defines their product as $(V, \pi) \cdot (W, \sigma) = (V \vee W, \pi \sigma)$ if $|(V, \pi)| + |(W, \sigma)| = |(V \vee W, \pi \sigma)|$. Otherwise, one sets $(V, \pi) \cdot (W, \sigma) = (O, \mathrm{id})$. Here, $O$ is the partition where every block consists of exactly one element, and $V \vee W$ denotes the join of the partitions $V$ and $W$.

A major problem is the factorization of a partitioned permutation $(V, \pi)$. This involves finding all pairs $(W_1, \sigma_1), (W_2, \sigma_2)$ of partitioned permutations with $(V, \pi) = (W_1, \sigma_1) \cdot (W_2, \sigma_2)$.

*Method
*(pp_1::PartitionedPermutation, pp_2::PartitionedPermutation)

Return the product of two partitioned permutations as described in [CMS07].

Examples

julia> x = partitioned_permutation(perm(symmetric_group(3), [1, 2, 3]), [1, 2, 3])
-PartitionedPermutation((), SetPartition([1, 2, 3], Int64[]))
-
-julia> y = partitioned_permutation(perm(symmetric_group(3), [2, 1, 3]), [1, 1, 3])
-PartitionedPermutation((1,2), SetPartition([1, 1, 2], Int64[]))
-
-julia> x*y
-PartitionedPermutation((1,2), SetPartition([1, 1, 2], Int64[]))
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
enumerate_partitioned_permutationsMethod
enumerate_partitioned_permutations(n::Int)

Return and calculate all PartitionedPermutation objects of length n

Examples

julia> length(enumerate_partitioned_permutations(6))
-4051
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
factorMethod
factor(pp::PartitionedPermutation)

Return the factorization of pp in form of a set of 2-tuples.

Examples

julia> length(factor(partitioned_permutation(perm(symmetric_group(3), [2, 1, 3]), [1, 1, 2])))
-2
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
diff --git a/previews/PR4245/Experimental/QuadFormAndIsom/enumeration/index.html b/previews/PR4245/Experimental/QuadFormAndIsom/enumeration/index.html deleted file mode 100644 index a24cf0aa430f..000000000000 --- a/previews/PR4245/Experimental/QuadFormAndIsom/enumeration/index.html +++ /dev/null @@ -1,128 +0,0 @@ - -Enumeration of isometries · Oscar.jl

Enumeration of isometries

One of the main features of this project is the enumeration of even lattices with isometry of finite order with at most two prime divisors. This is the content of [BH23] which has been implemented. We guide the user here to the global aspects of the available theory, and we refer to the paper [BH23] 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 some cases, $C$ can be obtained as a primitive extension $A \oplus 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 [BH23]).

We say that a triple $(G_A, G_B, G_C)$ of genus symbols for integer lattices is $p$-admissible if there are some lattices $A \in G_A$, $B \in G_B$ and $C \in G_C$ such that $(A, B, C)$ is $p$-admissible.

We use Definition 4.13. and Algorithm 1 of [BH23] 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; pA::Int = -1,
-                                           nA::Int = -1,
-                                           pB::Int = -1,
-                                           nB::Int = -1,
-                                           b::Int = 0)
-                                           -> 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$.

One can choose the positive signatures for the genera $A$ and $B$ in output respectively by setting pA and pB to the desired values. Similarly with the negative signatures nA and nB. The function returns an error if the choice of these values is inconsistent.

If b is set to 0, we allow in output the trivial pair, i.e. when $B$ is the genus of rank 0 lattices. Otherwise, if b is set to 1, the trivial pair is discarded.

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)
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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 [BH23].

The hermitian case

For an irreducible reciprocal polynomial $\chi$ and a genus symbol $G$ of integral integer lattices, if the equation order $\mathbb{Z}[\chi]$ is maximal, one can compute representatives of isomorphism classes of lattices with isometry $(L, f)$ such that $L\in G$ and $\chi(f) = 0$.

representatives_of_hermitian_typeMethod
representatives_of_hermitian_type(G::ZZGenus, chi::Union{ZZPolyRingElem, QQPolyRingElem}; first::Bool=false)
-representatives_of_hermitian_type(L::ZZLat, chi::Union{ZZPolyRingElem, QQPolyRingElem}; first::Bool=false)
-                                                               -> Vector{ZZLatWithIsom}

Given a non-empty genus of integer lattices $G$ and a polynomial $chi$ irreducible over $\mathbb Q$, such that the equation order of the associated number field is maximal, return a list of representatives of isomorphism classes of pairs $(M, g)$ consiting of a lattice $M$ in $G$ and $g \in O(M)$ is an isometry of minimal polynomial $chi$.

One can also provide a representative $L$ of $G$ instead.

If first is set to true, only return the first representative computed.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source

In the case of finite order isometries, when $\chi$ is cyclotomic, one can use as a shortcut the following function instead:

representatives_of_hermitian_typeMethod
representatives_of_hermitian_type(G::ZZGenus, m::Int; first::Bool=false)
-representatives_of_hermitian_type(L::ZZLat, m::Int; first::Bool=false)
-                                                   -> Vector{ZZLatWithIsom}

Given a non-empty genus of integer lattices $G$, return a list of representatives of isomorphism classes of pairs $(M, g)$ consisting of a lattice $M$ in $G$ and $g \in O(M)$ is an isometry of minimal polynomial $\Phi_m(X)$, the $m-$th cyclotomic polynomial.

If $m = 1,2$, this goes back to enumerate $G$ as a genus of integer lattices.

One can also provide a representative $L$ of $G$ instead.

If first is set to true, only return the first representative computed.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source

Orders with two prime divisors

As we will see later, the algorithms from [BH23] 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 even 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 even 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.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
enumerate_prime_power_isometriesMethod
enumerate_prime_power_isometries(L::ZZLat, q::IntegerUnion, vq::IntegerUnion) -> Vector{ZZLatWithIsom}
-enumerate_prime_power_isometries(G::ZZGenus, q::IntegerUnion, vq::IntegerUnion) -> Vector{ZZLatWithIsom}

Given a genus $G$ of even integer lattices, or a representative $L$ of $G$, return representatives of isomorphism classes of lattices with isometry $(M, g)$ where $M$ is a lattice in $G$ and $g$ has order $q^vq$.

$q$ must be a prime number and $vq$ must be a positive integer.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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 [BH23] used previously to enumerate lattices with isometry. The following correspond respectively to Algorithms 3, 4, 5, 6 and 7 of the aforementioned paper:

representatives_of_hermitian_typeMethod
representatives_of_hermitian_type(Lf::ZZLatWithIsom, m::Int = 1)
-                                                   -> Vector{ZZLatWithIsom}

Given a lattice with isometry $(L, f)$ of finite 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 $(M, g)$ of finite hermitian type such that the type of $(M, 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
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
splitting_of_hermitian_prime_powerMethod
splitting_of_hermitian_prime_power(Lf::ZZLatWithIsom, p::Int) -> Vector{ZZLatWithIsom}

Given an even 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
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
splitting_of_prime_powerMethod
splitting_of_prime_power(Lf::ZZLatWithIsom, p::Int, b::Int = 0)
-                                                   -> Vector{ZZLatWithIsom}

Given an even 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$ has 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
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
splitting_of_pure_mixed_prime_powerMethod
splitting_of_pure_mixed_prime_power(Lf::ZZLatWithIsom, p::Int)
-                                             -> Vector{ZZLatWithIsom}

Given an even 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.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
splitting_of_mixed_prime_powerMethod
splitting_of_mixed_prime_power(Lf::ZZLatWithIsom, p::Int, b::Int = 1)
-                                      -> Vector{ZZLatWithIsom}

Given an even lattice with isometry $(L, f)$ and a prime number $p$ such that $f$ has 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$ has order $p^{d+1}q^e$.

Note that $d$ and $e$ can be both 0.

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
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source

Note that an important feature from the theory in [BH23] 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_extensions (Algorithm 2 in [BH23]) which is the major tool making the previous enumeration possible and fast, from an algorithmic point of view.

diff --git a/previews/PR4245/Experimental/QuadFormAndIsom/introduction/index.html b/previews/PR4245/Experimental/QuadFormAndIsom/introduction/index.html deleted file mode 100644 index da4ced6fbc0b..000000000000 --- a/previews/PR4245/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 integral 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

Currently, the project features the following:

  • enumeration of conjugacy classes of isometries of finite order for even lattices (in the case of at most 2 prime divisors);
  • enumeration of conjugacy classes of isometries with irreducible and reciprocal minimal polynomial for integral lattices (with maximal equation order);
  • primitive embeddings/extensions for integral lattices;
  • equivariant primitive extensions for integral lattices;
  • miscellaneous operations on integral/rational quadratic form endowed with an isometry.

Current applications 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/PR4245/Experimental/QuadFormAndIsom/latwithisom/index.html b/previews/PR4245/Experimental/QuadFormAndIsom/latwithisom/index.html deleted file mode 100644 index 30e17c19f53c..000000000000 --- a/previews/PR4245/Experimental/QuadFormAndIsom/latwithisom/index.html +++ /dev/null @@ -1,1091 +0,0 @@ - -Lattices with isometry · Oscar.jl

Lattices 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 of an integer lattice $L$ of type ZZLat and an isometry $f$ given as a QQMatrix representing the action on the basis matrix of $L$.

We store the ambient space $V$ of $L$ together with an isometry $f_a$ inducing $f$ on $L$ seen as a pair $(V, f_a)$ 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.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source

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]
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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]
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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.

Constructors

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 as long as $f$ preserves $L$.

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]
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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]
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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]
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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]
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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> I = invariant_lattice(Lf);
-
-julia> basis_matrix(I)
-[1   0   0   0   0]
-[0   0   1   0   1]
-[0   0   0   1   0]
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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]
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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_elementaryMethod
is_elementary(Lf::ZZLatWithIsom, p::IntegerUnion) -> Bool

Given a lattice with isometry $(L, f)$ and a prime number $p$, return whether $L$ is $p$-elementary, that is whether its discriminant group is an elementary $p$-group.

Examples

julia> L = root_lattice(:E, 7);
-
-julia> Lf = integer_lattice_with_isometry(L);
-
-julia> is_elementary(Lf, 3)
-false
-
-julia> is_elementary(Lf, 2)
-true
-
-julia> genus(Lf)
-Genus symbol for integer lattices
-Signatures: (7, 0, 0)
-Local symbol:
-  Local genus symbol at 2: 1^6 2^1_7
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
is_elementary_with_primeMethod
is_elementary_with_prime(Lf::ZZLatWithIsom) -> Bool, ZZRingElem

Given a lattice with isometry $(L, f)$, return whether $L$ is elementary, that is whether $L$ is integral and its 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.

Examples

julia> L = root_lattice(:A, 7);
-
-julia> Lf = integer_lattice_with_isometry(L);
-
-julia> is_elementary_with_prime(Lf)
-(false, -1)
-
-julia> is_primary(Lf, 2)
-true
-
-julia> genus(Lf)
-Genus symbol for integer lattices
-Signatures: (7, 0, 0)
-Local symbol:
-  Local genus symbol at 2: 1^6 8^1_7
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
is_primaryMethod
is_primary(Lf::ZZLatWithIsom, p::IntegerUnion) -> Bool

Given a lattice with isometry $(L, f)$ and a prime number $p$, return whether $L$ is $p$-primary, that is whether its discriminant group is a $p$-group.

Examples

julia> L = root_lattice(:A, 6);
-
-julia> Lf = integer_lattice_with_isometry(L);
-
-julia> is_primary(Lf, 7)
-true
-
-julia> genus(Lf)
-Genus symbol for integer lattices
-Signatures: (6, 0, 0)
-Local symbols:
-  Local genus symbol at 2: 1^6
-  Local genus symbol at 7: 1^-5 7^-1
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
is_primary_with_primeMethod
is_primary_with_prime(Lf::ZZLatWithIsom) -> Bool, ZZRingElem

Given a lattice with isometry $(L, f)$, return whether $L$ is primary, that is whether $L$ is integral and its 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.

Examples

julia> L = root_lattice(:A, 5);
-
-julia> Lf = integer_lattice_with_isometry(L);
-
-julia> is_primary_with_prime(Lf)
-(false, -1)
-
-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
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
is_unimodularMethod
is_unimodular(Lf::ZZLatWithIsom) -> Bool

Given a lattice with isometry $(L, f)$, return whether `$L$ is unimodular, that is whether its discriminant group is trivial.

Examples

julia> L = root_lattice(:E, 8);
-
-julia> Lf = integer_lattice_with_isometry(L);
-
-julia> is_unimodular(Lf)
-true
-
-julia> genus(Lf)
-Genus symbol for integer lattices
-Signatures: (8, 0, 0)
-Local symbol:
-  Local genus symbol at 2: 1^8
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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)
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source

Similarly, some basic operations on $\mathbb Z$-lattices and matrices are available for integer 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]
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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: quadratic space -> quadratic space, Map: quadratic space -> quadratic space], AbstractSpaceMor[Map: quadratic space -> quadratic space, Map: quadratic space -> quadratic space])
-
-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]
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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: quadratic space -> quadratic space, Map: quadratic space -> quadratic space])
-
-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]
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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: quadratic space -> quadratic space, Map: quadratic space -> quadratic space])
-
-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]
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
orthogonal_submoduleMethod
orthogonal_submodule(Lf::ZZLatWithIsom, B::QQMatrix) -> ZZLatWithIsom

Given a lattice with isometry $(L, f)$ and a matrix $B$ with rational entries defining an $f$-stable sublattice of $L$, return the largest submodule of $L$ orthogonal to each row of $B$, equipped with the induced action from $f$.

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> orthogonal_submodule(Lf, B)
-Integer lattice of rank 2 and degree 5
-  with isometry of finite order 2
-  given by
-  [-1    0]
-  [ 0   -1]
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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]
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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$.

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 the pair $(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
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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 names 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 and the associated order is maximal.

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
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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 structures 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
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source

Discriminant groups

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 $D_L$ of the underlying lattice $L$ as well as the image $D_f$ of the underlying isometry $f$ inside $O(D_L)$.

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]
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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. For the remaining cases, we use the hermitian version of Miranda-Morrison theory as presented in [BH23]. The general computation of $G_{L, f}$ 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(D_L, D_f)$ of the centralizer $O(L, f)$ of $f$ in $O(L)$. Here $D_L$ denotes the discriminant group of $L$ and $D_f$ is the isometry of $D_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, Hom: group of isometries of Finite quadratic module generated by 2 elements -> group of isometries of Finite quadratic module generated by 1 elements)
-
-julia> order(G)
-2
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source

Note: hermitian Miranda-Morrison is only available for even lattices.

For an implementation of the regular Miranda-Morrison theory, we refer to the function image_in_Oq which actually computes the image of $\pi$ in both the definite and the indefinite case.

More generally, for a finitely generated subgroup $G$ of $O(L)$, we have implemented a function which computes the representation of $G$ on $D_L$:

discriminant_representationMethod
discriminant_representation(L::ZZLat, G::MatrixGroup;
-                                      ambient_representation::Bool = true,
-                                      check::Bool = true) -> GAPGroupHomomorphism

Given an integer lattice $L$ and a group $G$ of isometries of $L$, return the orthogonal representation $G\to O(D_L)$ of $G$ on the discriminant group $D_L$ of $L$.

If ambient_representation is set to true, then the isometries in $G$ are considered as matrix representation of their action on the standard basis of the ambient space of $L$. Otherwise, they are considered as matrix representation of their action on the basis matrix of $L$.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source

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{ZZPolyRingElem, 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]
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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]
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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]
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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]
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
invariant_coinvariant_pairMethod
invariant_coinvariant_pair(Lf::ZZLatWithIsom) -> ZZLatWithIsom, ZZLatWithIsom

Given a lattice with isometry $(L, f)$, return the pair of lattices with isometries consisting of $(L^f, f_{\mid L^f})$ and $(L_f, f_{\mid L_f})$, the invariant and coinvariant sublattices with isometry of $(L, f)$.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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$, 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 considered as matrix representation of their action on the standard basis of the ambient space of $L$. Otherwise, they are considered as matrix representation of their action on the basis matrices of $L$ and $L_G$ respectively.

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 QQ)
-
-julia> L == L2
-true
-
-julia> G == G2
-true
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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 considered as matrix representation of their action on the standard basis of the ambient space of $L$. Otherwise, they are considered as matrix representation of their action on the basis matrix 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
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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$, 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$ on $L$.

If ambient_representation is set to true, the isometries in $G$ and $H$ are considered as matrix representation of their action on the standard basis of the ambient space of $L$. Otherwise, they are considered as matrix representation of their action on the basis matrices of $L$ and $L_G$ respectively.

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 QQ)
-
-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]
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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 intrinsically 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 the pair $(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)
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source

Spinor norm

Given an integer lattice with isometry $(L, f)$, one often would like to know the spinor norm of $f$ seen as an isometry of the rational quadratic space $L\times \mathbb{Q}$. See rational_spinor_norm(::QuadSpaceWithIsom) for a definition.

rational_spinor_normMethod
rational_spinor_norm(Lf::ZZLatWithIsom; b::Int = -1) -> QQFieldElem

Given a lattice with isometry $(L, b, f)$, return the rational spinor norm of the extension of $f$ to $L\otimes \mathbb{Q}$.

If $\Phi$ is the form on $L\otimes \mathbb{Q}$, then the spinor norm is computed with respect to $b\Phi$.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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/PR4245/Experimental/QuadFormAndIsom/primembed/index.html b/previews/PR4245/Experimental/QuadFormAndIsom/primembed/index.html deleted file mode 100644 index 89f2096fae3b..000000000000 --- a/previews/PR4245/Experimental/QuadFormAndIsom/primembed/index.html +++ /dev/null @@ -1,37 +0,0 @@ - -Nikulin's theory on primitive embeddings · Oscar.jl

We introduce here the necessary definitions and results which lie behind the methods about primitive embeddings. Most of the content is taken from [Nik79].

Nikulin's theory on primitive embeddings

Primitive embeddings

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 [Nik79].

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 [Nik79]). More generally, the author also provides methods to compute primitive embeddings of any even lattice into an even lattice of a given genus (see Proposition 1.15.1 in [Nik79]). In the latter proposition, it is explained how to classify such embeddings as isomorphic embeddings or as isomorphic sublattices. Moreover, with enough care, one can generalize the previous results for embeddings in odd lattices.

A general method to compute primitive embeddings between integral lattices 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 made 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 = :sub,
-                                         check::Bool = true)
-                                -> Bool, Vector{Tuple{ZZLat, ZZLat, ZZLat}}

Given an integral integer lattice $L$, which is unique in its genus, and an integral integer lattice $M$, return whether $M$ embeds primitively in $L$.

The first output of the function is a boolean T stating whether $M$ embeds primitively in $L$. The second output $V$ consists of 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$ depends on the value of the symbol classification. There are 4 possibilities:

  • classification == :none: $V$ is the empty list;
  • classification == :first: $V$ consists of the first primitive embedding found;
  • classification == :sub: $V$ consists of representatives for all isomorphism classes of primitive embeddings of $M$ in $L$, up to the actions of $O(M)$ and $O(q)$ where $q$ is the discriminant group of $L$;
  • classification == :emb: $V$ consists of representatives for all isomorphism classes of primitive embeddings of $M$ in $L$ 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.

We follow the algorithm described in the proof of Proposition 1.15.1 of [Nik79]. The classification methods for the symbols :sub and :emb correspond to the different classes of primitive embeddings defined in the same proposition: for :sub we classify sublattices of $L$ which are isometric to $M$, and for :emb we classify the different embeddings of $M$ into $L$.

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: there exists a unique class of embedding of the root lattice $A_4$ into the root lattice $E_8$, and the orthogonal primitive sublattice is isometric to $A_4$.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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 = :sub)
-                                  -> Bool, Vector{Tuple{ZZLat, ZZLat, ZZLat}}

Given a genus symbol $G$ for integral integer lattices and an integral integer lattice $M$, return whether $M$ embeds primitively in a lattice in $G$.

The first output of the function is a boolean T stating whether $M$ embeds primitively in a lattice in $G$. The second output $V$ consists of 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$ depends on the value of classification. There are 4 possibilities:

  • classification == :none: $V$ is the empty list;
  • classification == :first: $V$ consists of the first primitive embedding found;
  • classification == :sub: $V$ consists of representatives for all isomorphism classes of primitive embeddings of $M$ in lattices in $G$, up to the actions of $O(M)$ and $O(q)$ where $q$ is the discriminant group of a lattice in $G$;
  • classification == :emb: $V$ consists of representatives for all isomorphism classes of primitive embeddings of $M$ in of lattices in $G$, up to the action of $O(q)$ where $q$ is the discriminant group of a lattice in $G$.

We follow the algorithm described in the proof of Proposition 1.15.1 of [Nik79]. The classification methods for :sub and :emb correspond to the different classes of primitive embeddings defined in the same proposition: for :sub we classify sublattices of lattices in $G$ which are isometric to $M$, and for :emb we classify the different embeddings of $M$ into lattices in $G$.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
primitive_embeddingsMethod
primitive_embeddings(q::TorQuadModule, sign::Tuple{Int, Int}, M::ZZLat;
-                                       classification::Symbol = :sub)
-                                    -> 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 integral integer lattices, return whether the integral integer lattice $M$ embeds primitively in a lattice in $G$.

The first output of the function is a boolean T stating whether $M$ embeds primitively in a lattice in $G$. The second output $V$ consists of 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$ depends on the value of the symbol classification. There are 4 possibilities:

  • classification == :none: $V$ is the empty list;
  • classification == :first: $V$ consists of the first primitive embedding found;
  • classification == :sub: $V$ consists of representatives for all isomorphism classes of primitive embeddings of $M$ in lattices in $G$, up to the actions of $O(M)$ and $O(q)$;
  • classification == :emb: $V$ consists of representatives for all isomorphism classes of primitive embeddings of $M$ in lattices in $G$ $G$, up to the action of $O(q)$.

If the pair (q, sign) does not define a non-empty genus for integer lattices, an error is thrown.

We follow the algorithm described in the proof of Proposition 1.15.1 of [Nik79]. The classification methods for the symbols :sub and :emb correspond to the different classes of primitive embeddings defined in the same proposition: for :sub we classify sublattices of lattices in $G$ which are isometric to $M$, and for :emb we classify the different embeddings of $M$ into lattices in $G$.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source

In order to compute such primitive embeddings of a lattice $M$ into a lattice $L$, we follow the proof of Proposition 1.15.1 of [Nik79].

Note: for the implementation of the algorithm, we construct a lattice $T$ which is unique in its genus, such that $D_T$ and $D_M(-1)$ are isometric and $O(T)\to O(D_T)$ is surjective. We then classify all primitive extensions of $M\oplus T$ modulo $O(D_T)$ (and modulo $O(M)$ for a classification of primitive sublattices). To classify such primitive extensions, we use Proposition 1.5.1 of [Nik79]:

primitive_extensionsMethod
primitive_extensions(M::ZZLat, N::ZZLat; glue_order::Union{IntegerUnion, Nothing} = nothing,
-                                         q::Union{TorQuadModule, Nothing} = nothing,
-                                         even::Bool = is_even(M) && is_even(N),
-                                         classification::Symbol = :subsub)
-                                      -> Bool, Vector{Tuple{ZZLat, ZZLat, ZZLat}}

Given two integral integer lattices $M$ and $N$, return a boolean T and a list $V$ of representatives of isomorphism classes of primitive extensions $M \oplus N \subseteq L$.

One can decide to choose the index of $[L:(M\oplus N)]$, which should be a positive integer by setting glue_order to the desired value. One can also decide on the isometry class of the discriminant form of the primitive extension by setting q to the desired value. If there are no primitive extensions of $M$ and $N$ satisfying the conditions imposed by the choice of glue_order or q, then T = false and $V$ is the empty list.

Otherwise, T = true and $V$ consists of triple $(L, M', N')$ such that $M'$ is isometric to $M$, $N'$ is isometric to $N$ and $L$ is a primitive extension of $M'\oplus N'$ satisfying conditions glue_order or q if assigned.

The content of $V$ depends on the value classification. There are 6 possibilities:

  • classification == :none: $V$ is the empty list;
  • classification == :first: $V$ consists of the first primitive extension computed;
  • classification == :subsub: $V$ consists of representatives for all isomorphism classes of primitive extensions of $M\oplus N$ satisfying the given conditions, up to the actions of $O(M)$ and $O(N)$;
  • classification == :subemb: $V$ consists of representatives for all isomorphism classes of primitive extensions of $M\oplus N$ satisfying the given conditions, up to the action of $O(M)$;
  • classification == :embsub: $V$ consists of representatives for all isomorphism classes of primitive extensions of $M\oplus N$ satisfying the given conditions, up to the action of $O(N)$;
  • classification == :embemb: $V$ consists of representatives for all isomorphism classes of primitive extensions of $M\oplus N$ satisfying the given conditions.

If even = true, then each primitive extension in output is selected to be even.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source

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\oplus N$ such that both $M$ and $N$ embed primitively in $L$ (via the natural embeddings $M,N \to M\oplus N\subseteq L$). Such primitive extensions are obtained, and classified, by classifying 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 gluing.

Equivariant primitive extensions

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 $D_{f_M}$ and $D_{f_N}$ stable along a glue map which commutes with these two actions. If such a gluing exists, then the overlattice $L$ of $M\oplus N$ is equipped with an isometry $f_L$ which preserves both $M$ and $N$, and restricts to $f_M$ and $f_N$ respectively.

equivariant_primitive_extensionsMethod
equivariant_primitive_extensions(M::Union{ZZLat, ZZLatWithIsom},
-                                 N::Union{ZZLat, ZZLatWithIsom};
-                                 glue_order::Union{IntegerUnion, Nothing} = nothing,
-                                 q::Union{IntegerUnion, Nothing} = nothing,
-                                 even::Bool = is_even(M) && is_even(N),
-                                 classification::Symbol = :subsub,
-                                 compute_bar_Gf::Bool = true)
-                                      -> Bool, Vector{Tuple{ZZLatWithIsom,
-                                                            ZZLatWithIsom,
-                                                            ZZLatWithIsom}}

Given two integral integer lattices $M$ and $N$, where at least one of them is equiped with an isometry, return a boolean T and a list $V$ of representatives of isomorphism classes of equivariant primitive extensions $(M, fM) \oplus (N, fN) \subseteq (L, fL)$. Note that if $M$ (resp $N$) is not equiped with an isometry, then $M$ (resp. $N$) has to be definite.

One can decide to choose the index of $[L:(M\oplus N)]$ which should be a positive integer by setting glue_order to the desired value. One can also decide on the isometry class of the discriminant form of a primitive extension by setting q to the desired value. If there are no equivariant primitive extensions of $M$ and $N$ satisfying the conditions imposed by the choice of glue_order or q, then T = false and $V$ is the empty list.

Otherwise, T = true and $V$ consists of triples $((L, f_L), (M', f_M'), (N', f_N'))$ such that $M'$ is isometric to $M$, $N'$ is isometric to $N$ and $(L, f_L)$ is an equivariant primitive extension of $(M', f_M')\oplus (N', f_N')$ such that $L$ satisfies conditions glue_order or q if assigned. If $M$ (resp. $N$) is equiped with an isometry $f_M$ (resp. $f_N$), then $(M', f_M')$ and $(M, f_M)$ (resp. $(N', f_N')$ and $(N, f_N)$) are isomorphic as lattices with isometry.

The content of $V$ depends on the value of classification. There are 6 possibilities:

  • classification == :none: $V$ is empty by default;
  • classification == :first: $V$ consists of the first equivariant primitive extension computed;
  • classification == :subsub: $V$ consists of representatives for all isomorphism classes of equivariant primitive extensions of $(M, f_M)\oplus (N, f_N)$ satisfying the given conditions, up to the actions of $O(M, f_M)$ and $O(N, f_N)$;
  • classification == :subemb: $V$ consists of representatives for all isomorphism classes of equivariant primitive extensions of $(M, f_M)\oplus (N, f_N)$ satisfying the given conditions, up to the action of $O(M, f_M)$;
  • classification == :embsub: $V$ consists of representatives for all isomorphism classes of equivariant primitive extensions of $(M, f_M)\oplus (N, f_N)$ satisfying the given conditions, up to the action of $O(N, f_N)$;
  • classification == :embemb: $V$ consists of representatives for all isomorphism classes of equivariant primitive extensions of $(M, f_M)\oplus (N, f_N)$ satisfying the given conditions;

If $M$ (resp. $N$) is not equiped with an isometry, then the previous classifications are done modulo the action of $O(M)$ (resp. $O(N)$) instead of $O(M, f_M)$ (resp. $O(N, f_N)$). Moreover, the function extends representatives of conjugacy classes of isometries of $M$ (resp. $N$) which can be glued equivariantly with $f_N$ (resp. $f_M$) in a certain coset of $O(M)$ determined by classification. Note that this can be expensive if $M$ (resp. $N$) as large isometry group.

If even = true, then each primitive extension in output is selected to be even.

If compute_bar_Gf is set to true, then for each pair $(L, f_L)$ of an output triple in $V$, the algorithm compute the image of the natural map $O(L, f_L) \to O(D_L, D_{f_L})$ (see image_centralizer_in_Oq).

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source

Admissible equivariant primitive extensions

The following function is a major tool provided by [BH23]. Given a triple of even 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)\oplus (B, b)\to (D, d)$ such that the type of $(D, d^q)$ 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::IntegerUnion,
-                                            q::IntegerUnion = p; check::Bool = true)
-                                                 -> Vector{ZZLatWithIsom}

Given a triple of lattices with isometry $(A, f_A)$, $(B, f_B)$ and $(C, f_C)$, 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, f_A) \to O(D_A, D_{f_A})$ and $O(B, f_B) \to O(D_B, D_{f_B})$;
  • $S$ is the set of all primitive extensions $A \oplus B \subseteq C'$ with isometry $f_C'$ where $p\cdot C' \subseteq A\oplus B$ and such that the type of $(C', (f_C')^q)$ is equal to the type of $(C, f_C)$.

If check == true the input triple is checked to a $p$-admissible triple of integral lattices (with isometry) with $f_A$ and $f_B$ having relatively coprime irreducible minimal polynomials. Moreover, the function checks that $A$ and $B$ are orthogonal if $A$, $B$ and $C$ lie in the same ambient quadratic space.

Note moreover that the function computes the image of the natural map $O(C, f_C) \to O(D_C, D_{f_C})$ along the primitive extension $A\oplus B\subseteq C$ (see Algorithm 2, Line 22 of [BH23]).

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
diff --git a/previews/PR4245/Experimental/QuadFormAndIsom/spacewithisom/index.html b/previews/PR4245/Experimental/QuadFormAndIsom/spacewithisom/index.html deleted file mode 100644 index 99b69119586f..000000000000 --- a/previews/PR4245/Experimental/QuadFormAndIsom/spacewithisom/index.html +++ /dev/null @@ -1,371 +0,0 @@ - -Quadratic spaces with isometry · Oscar.jl

Quadratic spaces 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 Spaces of the documentation for new users.

Note that currently, we support only rational quadratic forms, i.e. quadratic spaces defined over $\mathbb{Q}$.

In Oscar, such a pair is encoded by the type called QuadSpaceWithIsom:

QuadSpaceWithIsomType
QuadSpaceWithIsom

A container type for pairs $(V, f)$ consisting of a 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 infinite.

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]
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source

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]
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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]
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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]
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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)
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source

Similarly, some basic operations on quadratic spaces and matrices 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]
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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: quadratic space -> quadratic space, Map: quadratic space -> quadratic space], AbstractSpaceMor[Map: quadratic space -> quadratic space, Map: quadratic space -> quadratic space])
-
-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]
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
direct_productMethod
direct_product(algebras::StructureConstantAlgebra...; task::Symbol = :sum)
-  -> StructureConstantAlgebra, Vector{AbsAlgAssMor}, Vector{AbsAlgAssMor}
-direct_product(algebras::Vector{StructureConstantAlgebra}; task::Symbol = :sum)
-  -> StructureConstantAlgebra, 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.

source
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: quadratic space -> quadratic space, Map: quadratic space -> quadratic space])
-
-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]
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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

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

source
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: quadratic space -> quadratic space, Map: quadratic space -> quadratic space])
-
-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]
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
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]
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source

Spinor norm

Given a rational quadratic space $(V, \Phi)$, and given an integer $b\in\mathbb{Q}$, we define the rational spinor norm $\sigma$ on $(V, b\Phi)$ to be the group homomorphism

\[\sigma\colon O(V, b\Phi) = O(V, \Phi)\to \mathbb{Q}^\ast/(\mathbb{Q}^\ast)^2\]

defined as follows. For $f\in O(V, b\Phi)$, there exist elements $v_1,\ldots, v_r\in V$ where $1\leq r\leq \text{rank}(V)$ such that $f = \tau_{v_1}\circ\cdots\circ \tau_{v_r}$ is equal to the product of the associated reflections. We define

\[\sigma(f) := (-\frac{b\Phi(v_1, v_1)}{2})\cdots(-\frac{b\Phi(v_r,v_r)}{2}) \mod (\mathbb{Q}^{\ast})^2.\]

rational_spinor_normMethod
rational_spinor_norm(Vf::QuadSpaceWithIsom; b::Int = -1) -> QQFieldElem

Given a rational quadratic space with isometry $(V, b, f)$, return the rational spinor norm of $f$.

If $\Phi$ is the form on $V$, then the spinor norm is computed with respect to $b\Phi$.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source

Equality

We choose as a convention that two pairs $(V, f)$ and $(V', f')$ of quadratic spaces with isometries are equal 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/PR4245/Experimental/Singularities/intro/index.html b/previews/PR4245/Experimental/Singularities/intro/index.html deleted file mode 100644 index 83a1e47c0d80..000000000000 --- a/previews/PR4245/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 organized 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/PR4245/Experimental/Singularities/space_germs/index.html b/previews/PR4245/Experimental/Singularities/space_germs/index.html deleted file mode 100644 index c33995d4d945..000000000000 --- a/previews/PR4245/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 neighborhood 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::AbsAffineScheme, 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::AbsAffineScheme, 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/PR4245/Experimental/StandardFiniteFields/introduction/index.html b/previews/PR4245/Experimental/StandardFiniteFields/introduction/index.html deleted file mode 100644 index b7a15fbc9d8d..000000000000 --- a/previews/PR4245/Experimental/StandardFiniteFields/introduction/index.html +++ /dev/null @@ -1,3 +0,0 @@ - -- · Oscar.jl
standard_finite_fieldMethod
standard_finite_field(p::Union{ZZRingElem, Integer}, n::Union{ZZRingElem, Integer}) -> FinField

Return a finite field of order $p^n$.

Examples

julia> standard_finite_field(3, 24)
-Finite field of degree 24 over GF(3)
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
diff --git a/previews/PR4245/Experimental/intro/index.html b/previews/PR4245/Experimental/intro/index.html deleted file mode 100644 index 9257d2cf70c1..000000000000 --- a/previews/PR4245/Experimental/intro/index.html +++ /dev/null @@ -1,12 +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 projects 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/PROJECT_NAME, that have subfolders docs, src, and test. The general structure is

experimental/PROJECT_NAME/
-├── README.md
-├── docs
-│   ├── doc.main
-│   └── src
-│       └── DOCUMENTATION.md
-├── src
-│   └── PROJECT_NAME.jl
-└── test
-    └── *.jl

The file src/PROJECT_NAME.jl and at least one .jl file in the test/ directory are mandatory and are used by Oscar.jl to find your code and tests. If there is a test/runtests.jl then only this file is executed during testing, otherwise all .jl files will be run automatically (in a random order).

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.

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="",
-  new::Bool=true, timed::Bool=false, ignore=[])

Run the Oscar tests in experimental/<project>/test/<path>:

  • if path is empty then all tests in that module are run, either via runtests.jl or directly.
  • if path or path.jl is a file in that directory only this file is run.

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.

With the optional parameter timed the function will return a dict mapping file names to a named tuple with compilation times and allocations. This only works for new=false.

The parameter ignore can be used to pass a list of String or Regex patterns. Test files or folders matching these will be skipped. Strings will be compared as suffixes. This only works for new=false.

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/PR4245/Fields/algebraic_closure_fp/index.html b/previews/PR4245/Fields/algebraic_closure_fp/index.html deleted file mode 100644 index 924f5d9d84a5..000000000000 --- a/previews/PR4245/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_closureMethod
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 order 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/PR4245/Fields/intro/index.html b/previews/PR4245/Fields/intro/index.html deleted file mode 100644 index 0881b7d6cb08..000000000000 --- a/previews/PR4245/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/PR4245/General/architecture/index.html b/previews/PR4245/General/architecture/index.html deleted file mode 100644 index 333663561702..000000000000 --- a/previews/PR4245/General/architecture/index.html +++ /dev/null @@ -1,24 +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()OSCAR version 1.2.0-DEV
-  combining:
-    AbstractAlgebra.jl   v0.43.7
-    GAP.jl               v0.12.0
-    Hecke.jl             v0.34.6
-    Nemo.jl              v0.47.2
-    Polymake.jl          v0.11.22
-    Singular.jl          v0.23.10

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)OSCAR version 1.2.0-DEV
-  combining:
-    AbstractAlgebra.jl   v0.43.7
-    GAP.jl               v0.12.0
-    Hecke.jl             v0.34.6
-    Nemo.jl              v0.47.2
-    Polymake.jl          v0.11.22
-    Singular.jl          v0.23.10
-  building on:
-    FLINT_jll               v300.100.300+0
-    GAP_jll                 v400.1300.102+2
-    Singular_jll            v404.0.606+0
-    libpolymake_julia_jll   v0.13.0+0
-    libsingular_julia_jll   v0.46.0+0
-    polymake_jll            v400.1300.1+0
-See `]st -m` for a full list of dependencies.

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/PR4245/General/complex/index.html b/previews/PR4245/General/complex/index.html deleted file mode 100644 index 613d0b3bb79f..000000000000 --- a/previews/PR4245/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

Omitted input sanity checks

Some input sanity checks are omitted on purpose, since they would be too expensive to verify performance wise. We will continue to add to the following list.

  • Checking that the input for subdivision_of_points actually defines a proper polyhedral complex covering the convex hull of the given points.
diff --git a/previews/PR4245/General/faq/index.html b/previews/PR4245/General/faq/index.html deleted file mode 100644 index 9f932f875718..000000000000 --- a/previews/PR4245/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 toric variety
-
-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 $\mathbb Z/n\mathbb Z$, 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 $\mathbb Z/n\mathbb Z$, 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 access or install custom GAP packages (e.g. unpublished ones)?

An already locally installed GAP package can be loaded into the OSCAR session via GAP.Packages.load, where the first argument is the local path to the package directory (the one that contains the PackageInfo.g file). This works only if no other version of this package has been loaded already.

If Oscar loads the package in question already on startup but you want a different version of this package to be loaded, you can force this by storing the desired version in the pkg subdirectory of the user's root directory (GAPInfo.UserGapRoot in GAP).

Installing a new GAP package for which you know the URL of a package archive can be done via GAP.Packages.install, where the first argument is this URL.


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.


Q: How do I cite OSCAR?

Please see here.


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/PR4245/General/other/index.html b/previews/PR4245/General/other/index.html deleted file mode 100644 index c5038347278a..000000000000 --- a/previews/PR4245/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.

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.)

  • The interactive sessions behave differently.

    When an error occurs or when the user hits ctrl-C in a GAP session, usually a break loop is entered, from which one can either try to continue the computations, by entering return, or return to the GAP prompt, by entering quit; in the latter case, some objects may be corrupted afterwards.

    In a Julia session, one gets automatically back to the Julia prompt when an error occurs or when the user hits ctrl-C, and again some objects may be corrupted afterwards.

  • 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 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)
diff --git a/previews/PR4245/General/serialization/index.html b/previews/PR4245/General/serialization/index.html deleted file mode 100644 index 6cbd79ebb2bb..000000000000 --- a/previews/PR4245/General/serialization/index.html +++ /dev/null @@ -1,84 +0,0 @@ - -Saving and loading files · Oscar.jl

Saving and loading files

Introduction

For some of our datatypes we provide a way to save them in and load them from JSON format. The most common OSCAR types are supported, but it will take some time until all corners of OSCAR are covered by this effort. Our overall goal 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 of OSCAR (or other computer algebra systems).

For more details read the developer documentation. Work on serialization is supported by the MaRDI project. You can find out more about its Task Area 1 (Computer Algebra) here.

saveFunction
save(io::IO, obj::Any; metadata::MetaData=nothing, with_attrs::Bool=true)
-save(filename::String, obj::Any, metadata::MetaData=nothing, with_attrs::Bool=true)

Save an object obj to the given io stream respectively to the file filename. When used with with_attrs=true then the object will save it's attributes along with all the attributes of the types used in the object's struct. The attributes that will be saved are defined during type registration see @register_serialization_type

See load.

Examples

julia> meta = metadata(author_orcid="0000-0000-0000-0042", name="42", description="The meaning of life, the universe and everything")
-Oscar.MetaData("0000-0000-0000-0042", "42", "The meaning of life, the universe and everything")
-
-julia> save("/tmp/fourtitwo.mrdi", 42; metadata=meta);
-
-julia> read_metadata("/tmp/fourtitwo.mrdi")
-{
-  "author_orcid": "0000-0000-0000-0042",
-  "name": "42",
-  "description": "The meaning of life, the universe and everything"
-}
-
-julia> load("/tmp/fourtitwo.mrdi")
-42
source
loadFunction
load(io::IO; params::Any = nothing, type::Any = nothing, with_attrs::Bool=true)
-load(filename::String; params::Any = nothing, type::Any = nothing, with_attrs::Bool=true)

Load the object stored in the given io stream respectively in the file filename.

If params is specified, then the root object of the loaded data either will attempt a load using these parameters. In the case of Rings this results in setting its parent, or in the case of a container of ring types such as Vector or Tuple, then the parent of the entries will be set using their params.

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.

If with_attrs=true the object will be loaded with attributes available from the file (or serialized data).

See save.

Examples

julia> save("/tmp/fourtitwo.mrdi", 42);
-
-julia> load("/tmp/fourtitwo.mrdi")
-42
-
-julia> load("/tmp/fourtitwo.mrdi"; 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.mrdi", p)
-
-julia> p_loaded = load("/tmp/p.mrdi", params=R)
-x^2 - x + 1
-
-julia> parent(p_loaded) === R
-true
-
-julia> save("/tmp/p_v.mrdi", [p, p])
-
-julia> loaded_p_v = load("/tmp/p_v.mrdi", params=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

Objects that can be serialized

In this section we will list a selection of objects that may be (de-)serialized.

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
-PolyRing
-PolyRingElem
-MPolyRing
-MPolyRingElem

Groups

FPGroup
-FinGenAbGroup
-PcGroup
-PermGroup
-SubFPGroup
-SubPcGroup

Polyhedral Geometry

Cone
-LinearProgram
-PolyhedralFan
-PolyhedralComplex
-Polyhedron
-SubdivisionOfPoints

Toric Geometry

NormalToricVariety
-ToricDivisor

Tropical Geometry

TropicalCurve
-TropicalHypersurface

Listing all serializable types of the current session

If you are curious about whether your type can already be serialized given your version of Oscar you can run the following command in your active session.

julia> Oscar.reverse_type_mapDict{String, Type} with 158 entries:
-  "ArbFieldElem"                        => ArbFieldElem
-  "MPolyRing"                           => MPolyRing
-  "Floats"                              => Floats{Float64}
-  "RationalFunctionFieldElem"           => RationalFunctionFieldElem
-  "Tuple"                               => Tuple
-  "AbstractLieAlgebraElem"              => AbstractLieAlgebraElem
-  "MatSpace"                            => MatSpace
-  "Float64"                             => Float64
-  "QQFieldElem"                         => QQFieldElem
-  "ZZModRingElem"                       => ZZModRingElem
-  "RationalFunctionField"               => RationalFunctionField
-  "Vector"                              => Vector
-  "RelPowerSeriesRingElem"              => RelPowerSeriesRingElem
-  "LaurentSeriesFieldElem"              => LaurentSeriesFieldElem
-  "FreeAssociativeAlgebraElem"          => FreeAssociativeAlgebraElem
-  "Hecke.RelNonSimpleNumFieldEmbedding" => RelNonSimpleNumFieldEmbedding
-  "Hecke.RelSimpleNumFieldElem"         => RelSimpleNumFieldElem
-  "PermGroup"                           => PermGroup
-  "ArbField"                            => ArbField
-  ⋮                                     => ⋮
diff --git a/previews/PR4245/Groups/action/index.html b/previews/PR4245/Groups/action/index.html deleted file mode 100644 index 9012d1832750..000000000000 --- a/previews/PR4245/Groups/action/index.html +++ /dev/null @@ -1,214 +0,0 @@ - -Group actions · Oscar.jl

Group actions

A group action of a group $G$ on a set $\Omega$ (from the right) is defined by a map $\mu:\Omega\times G\to \Omega$ that satisfies the compatibility conditions $\mu(\mu(x,g),h) = \mu(x, gh)$ and $\mu(x, 1_G) = x$ for all $x\in\Omega$.

The maps $\mu$ are implemented as functions that take two arguments, an element $x$ of $\Omega$ 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 $\Omega$ 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::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 = 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::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 = 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::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 = GapObj(a; recursive = true)
-GAP: [ "a", "b", "c" ]
-
-julia> permuted(l, g[1])
-GAP: [ "c", "a", "b" ]
source
on_indeterminatesFunction
on_indeterminates(f::GapObj, p::PermGroupElem)
-on_indeterminates(f::MPolyRingElem, p::PermGroupElem)
-on_indeterminates(f::FreeAssociativeAlgebraElem, p::PermGroupElem)
-on_indeterminates(f::MPolyIdeal, p::PermGroupElem)

Return the image of f under p where p acts via permuting the indeterminates.

For MPolyRingElem, FreeAssociativeAlgebraElem, 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
source
on_indeterminates(f::GapObj, p::MatrixGroupElem)
-on_indeterminates(f::MPolyRingElem{T}, p::MatrixGroupElem{T}) where T
-on_indeterminates(f::MPolyIdeal, p::MatrixGroupElem)

Return the image of f under p where p acts via evaluating f at the vector obtained by multiplying p with the (column) vector of indeterminates. This corresponds to considering the variables of the polynomial ring containing f as the basis of a vector space on which p acts by multiplication from the right.

For MPolyRingElem and MPolyIdeal objects, one can also call ^ instead of on_indeterminates.

Examples

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. Note that the explicit elements of a G-set Omega can be obtained using collect(Omega).

gsetMethod
gset(G::Union{GAPGroup, FinGenAbGroup}[, 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
acting_groupMethod
acting_group(Omega::GSetByElements)

Return the group G acting on Omega.

Examples

julia> G = symmetric_group(4);
-
-julia> acting_group(gset(G, [1])) == G
-true
source
action_functionMethod
action_function(Omega::GSetByElements)

Return the function $f: \Omega \times G \to \Omega$ that defines the G-set.

Examples

julia> G = symmetric_group(4);
-
-julia> action_function(gset(G, [1])) == ^
-true
-
-julia> action_function(gset(G, [[1, 2]])) == on_tuples
-true
-
-julia> action_function(gset(G, on_sets, [[1, 2]])) == on_sets
-true
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(6)
-  to Sym(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
is_conjugateMethod
is_conjugate(Omega::GSet, omega1, omega2)

Return true if omega1, omega2 are in the same orbit of Omega, and false otherwise. To also obtain a conjugating element use is_conjugate_with_data.

Examples

julia> G = sylow_subgroup(symmetric_group(6), 2)[1]
-Permutation group of degree 6 and order 16
-
-julia> Omega = gset(G);
-
-julia> is_conjugate(Omega, 1, 2)
-true
-
-julia> is_conjugate(Omega, 1, 5)
-false
source
is_conjugate_with_dataMethod
is_conjugate_with_data(Omega::GSet, omega1, omega2)

Determine whether omega1, omega2 are in the same orbit of Omega. If yes, return (true, g) where g is an element in the group G of Omega that maps omega1 to omega2. If not, return (false, nothing). If the conjugating element g is not needed, use is_conjugate.

Examples

julia> G = sylow_subgroup(symmetric_group(6), 2)[1]
-Permutation group of degree 6 and order 16
-
-julia> Omega = gset(G);
-
-julia> is_conjugate_with_data(Omega, 1, 2)
-(true, (1,2))
-
-julia> is_conjugate_with_data(Omega, 1, 5)
-(false, ())
source
orbitMethod
orbit(Omega::GSet, omega)

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]
-Permutation group of degree 6 and order 16
-
-julia> Omega = gset(G, [1, 5]);
-
-julia> length(orbit(Omega, 1))
-4
source
orbitMethod
orbit(G::Union{GAPGroup, FinGenAbGroup}[, 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]
-Permutation group of degree 6 and order 16
-
-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::GAPGroup, pnt::Any[, actfun::Function])

Return S, emb where S is 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, and emb is the embedding of S into G.

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
stabilizerMethod
stabilizer(Omega::GSet{T,S})
-stabilizer(Omega::GSet{T,S}, omega::S = representative(Omega); check::Bool = true) where {T,S}

Return the subgroup of G = acting_group(Omega) that fixes omega, together with the embedding of this subgroup into G. If check is false then it is not checked whether omega is in Omega.

Examples

julia> Omega = gset(symmetric_group(3));
-
-julia> stabilizer(Omega)
-(Permutation group of degree 3 and order 2, Hom: permutation group -> Sym(3))
source
diff --git a/previews/PR4245/Groups/autgroup/index.html b/previews/PR4245/Groups/autgroup/index.html deleted file mode 100644 index 7277ebb081cf..000000000000 --- a/previews/PR4245/Groups/autgroup/index.html +++ /dev/null @@ -1,96 +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(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(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(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(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(4)
-  to Sym(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(4)
-
-julia> A = automorphism_group(S)
-Aut( Sym( [ 1 .. 4 ] ) )
-
-julia> g = hom(S,S,x->x^S[1])
-Group homomorphism
-  from Sym(4)
-  to Sym(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::GAPGroup) where T <: GAPGroup

Return whether f(H) == H.

source
restrict_automorphismMethod
restrict_automorphism(f::GAPGroupElem{AutomorphismGroup{T}}, H::GAPGroup) where T <: GAPGroup

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/PR4245/Groups/basics/index.html b/previews/PR4245/Groups/basics/index.html deleted file mode 100644 index 55e512460649..000000000000 --- a/previews/PR4245/Groups/basics/index.html +++ /dev/null @@ -1,215 +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, SubFPGroup, PcGroup, SubPcGroup, 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_finite_orderMethod
is_finite_order(g::GAPGroupElem) -> Bool

Return true if g has finite order, and false otherwise.

Examples

julia> is_finite_order(gen(symmetric_group(5), 1))
-true
-
-julia> is_finite_order(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 of rank 2
-
-julia> has_gens(F)
-true
-
-julia> H = derived_subgroup(F)[1]
-Free group
-
-julia> has_gens(H)
-false
source
number_of_generatorsMethod
number_of_generators(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 one(G) if i == 0, the i-th element of the vector gens(G) if i is positive, and the inverse of the i-th element of gens(G) if i is negative.

For positive i, this is equivalent to G[i], and returns gens(G)[i] but may be more efficient than the latter.

An exception is thrown if abs(i) is larger than the length of gens(G).

Examples

julia> g = symmetric_group(5);  gen(g, 1)
-(1,2,3,4,5)
-
-julia> g[-1]
-(1,5,4,3,2)
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(SubPcGroup, [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_abelianMethod
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_pgroupMethod
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_primeMethod
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_nilpotentMethod
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.

Examples

julia> is_nilpotent(dihedral_group(8))
-true
-
-julia> is_nilpotent(dihedral_group(10))
-false
source
is_supersolvableMethod
is_supersolvable(G::GAPGroup)

Return whether G is supersolvable, i.e., G is finite and has a normal series with cyclic factors.

Examples

julia> is_supersolvable(symmetric_group(3))
-true
-
-julia> is_supersolvable(symmetric_group(4))
-false
-
-julia> is_supersolvable(symmetric_group(5))
-false
source
is_solvableMethod
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.

Examples

julia> is_solvable(symmetric_group(3))
-true
-
-julia> is_solvable(symmetric_group(4))
-true
-
-julia> is_solvable(symmetric_group(5))
-false
source
is_perfectMethod
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_almost_simpleMethod
is_almost_simple(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_almost_simple(symmetric_group(5))
-true
-
-julia> is_almost_simple(special_linear_group(2, 5))
-false
-
source
is_quasisimpleMethod
is_quasisimple(G::GAPGroup)

Return whether G is a quasisimple group, i.e., G is perfect such that the factor group modulo its center 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_simpleMethod
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_finitely_generatedMethod
is_finitely_generated(G::GAPGroup)

Return whether G is a finitely generated group.

Examples

julia> F = free_group(2)
-Free group of rank 2
-
-julia> is_finitely_generated(F)
-true
-
-julia> H = derived_subgroup(F)[1]
-Free group
-
-julia> is_finitely_generated(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_finite_order 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_finite_order(gen(g, 1))
-false
source
abelian_invariantsMethod
abelian_invariants(::Type{T} = ZZRingElem, G::Union{GAPGroup, FinGenAbGroup}) where T <: IntegerUnion

Return the sorted vector of abelian invariants of the commutator factor group of G (see maximal_abelian_quotient). The entries are prime powers or zeroes and have the type T. They describe the structure of the commutator factor group of G as a direct product of cyclic groups of prime power (or infinite) order.

Examples

julia> abelian_invariants(symmetric_group(4))
-1-element Vector{ZZRingElem}:
- 2
-
-julia> abelian_invariants(Int, abelian_group([2, 12]))
-3-element Vector{Int64}:
- 2
- 3
- 4
-
-julia> abelian_invariants(alternating_group(5))
-ZZRingElem[]
source
abelian_invariants_schur_multiplierMethod
abelian_invariants_schur_multiplier(::Type{T} = ZZRingElem, G::Union{GAPGroup, FinGenAbGroup}) where T <: IntegerUnion

Return the sorted vector of abelian invariants (see abelian_invariants) of the Schur multiplier of G. The entries are prime powers or zeroes and have the type T. They describe the structure of the Schur multiplier of G as a direct product of cyclic groups of prime power (or infinite) order.

Examples

julia> abelian_invariants_schur_multiplier(symmetric_group(4))
-1-element Vector{ZZRingElem}:
- 2
-
-julia> abelian_invariants_schur_multiplier(Int, alternating_group(6))
-2-element Vector{Int64}:
- 2
- 3
-
-julia> abelian_invariants_schur_multiplier(abelian_group([2, 12]))
-1-element Vector{ZZRingElem}:
- 2
-
-julia> abelian_invariants_schur_multiplier(cyclic_group(5))
-ZZRingElem[]
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)])
-Permutation group of degree 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 with $n$ steps (meaning that it consists of $n+1$ groups). The trivial group is the unique group with nilpotency class 0 and all abelian groups have nilpotency class 1.

An exception is thrown if G is not nilpotent.

See also lower_central_series and upper_central_series.

Examples

julia> nilpotency_class(dihedral_group(8))
-2
-
-julia> nilpotency_class(dihedral_group(12))
-ERROR: ArgumentError: The group 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
derived_lengthFunction
derived_length(G::GAPGroup)

Return the number of steps in the derived series of $G$, that is the series length minus 1. See also derived_series.

Examples

julia> derived_length(symmetric_group(4))
-3
-
-julia> derived_length(symmetric_group(5))
-1
-
-julia> derived_length(dihedral_group(8))
-2
source
schur_coverMethod
schur_cover(::Type{T} = FPGroup, G::GAPGroup) where T <: GAPGroup

Return S, f where S is a Schur cover of G and f is an epimorphism from S to G.

Examples

julia> S, f = schur_cover(symmetric_group(4));  order(S)
-48
-
-julia> S, f = schur_cover(PermGroup, dihedral_group(12));  order(S)
-24
source
schur_multiplierMethod
schur_multiplier(::Type{T} = FinGenAbGroup, G::Union{GAPGroup, FinGenAbGroup}) where T <: Union{GAPGroup, FinGenAbGroup}

Return the Schur multiplier of G. This is an abelian group whose abelian invariants can be computed with abelian_invariants_schur_multiplier.

Examples

julia> schur_multiplier(symmetric_group(4))
-Z/2
-
-julia> schur_multiplier(PcGroup, alternating_group(6))
-Pc group of order 6
-
-julia> schur_multiplier(abelian_group([2, 12]))
-Z/2
-
-julia> schur_multiplier(cyclic_group(5))
-Z/1
source
diff --git a/previews/PR4245/Groups/fpgroup/index.html b/previews/PR4245/Groups/fpgroup/index.html deleted file mode 100644 index 24f1802357e7..000000000000 --- a/previews/PR4245/Groups/fpgroup/index.html +++ /dev/null @@ -1,101 +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.

For a group G of type FPGroup, the elements in gens(G) satisfy the relators of the underlying presentation.

Functions that compute subgroups of G return groups of type SubFPGroup.

source
FPGroupElemType
FPGroupElem

Element of a finitely presented group.

The generators of a finitely presented group are displayed as f1, f2, f3, etc., and every element of a finitely presented group is displayed as product of the generators.

source
SubFPGroupType
SubFPGroup

Subgroup of a finitely presented group, a group that is defined by generators that are elements of a group G of type FPGroup.

Operations for computing subgroups of a group of type FPGroup or SubFPGroup, such as derived_subgroup and sylow_subgroup, return groups of type SubFPGroup.

Note that functions such as relators do not make sense for proper subgroups of a finitely presented group.

source
SubFPGroupElemType
SubFPGroupElem

Element of a subgroup of a finitely presented group.

The elements are displayed in the same way as the elements of full finitely presented groups, see FPGroupElem.

source
free_groupFunction
free_group(n::Int, s::VarName = :f; eltype::Symbol = :letter) -> FPGroup
-free_group(L::VarName... ; eltype::Symbol = :letter) -> FPGroup
-free_group(varnames_specifiers... ; eltype::Symbol = :letter) -> FPGroup

Return a free group.

The first form returns a free group of rank n, where the generators are printed as "$s1", "$s2", ..., the default being f1, f2, ...

The second form returns a free group of rank n, where n is the length of L, and L consists of strings, symbols or characters giving the variable names.

In the final form, the argument list consists of a sequence of one or more of the following:

  1. A vector L of variable names.
  2. A pair of the form A => B, where A is a VarName (so a string, symbol or character) and B is a range or more generally an AbstractVector. Then length(B) generators are defined whose names derive from a combination of A and the respective element of B. For example :x => 1:3 defines three generators x[1], x[2], x[3].
  3. A pair of the form A => C, where A is again a VarName, and C is a tuple of ranges or v. For example "a" => (1:2, 1:2) defines four generators a[1, 1], a[2, 1], a[1, 2], a[2, 2].

For the second and third type, optionally the A part can contain the placeholder # to modify where the indices are inserted. For example "a#" => (1:2, 1:2) defines four generators a11, a21, a12, a22.

Also, instead of a range, any vector can be used. For example "#" => ([:x,:y], [:A, :B]) defines four generators xA, yA, xB, yB.

In all variants, if the optional keyword argument eltype is given and 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.

Warning

Julia variables named like the group generators are not created by this function. However, the macro @free_group does just that.

Examples

julia> F = free_group(:a, :b)
-Free group of rank 2
-
-julia> w = F[1]^3 * F[2]^F[1] * F[-2]^2
-a^2*b*a*b^-2

Here we show some of the different ways to create a free group.

julia> gens(free_group(2))
-2-element Vector{FPGroupElem}:
- f1
- f2
-
-julia> gens(free_group(2, :a))
-2-element Vector{FPGroupElem}:
- a1
- a2
-
-julia> gens(free_group(:u, :v))
-2-element Vector{FPGroupElem}:
- u
- v
-
-julia> gens(free_group([:a, :b], "x" => 1:2, 'y' => (1:2, 1:2)))
-8-element Vector{FPGroupElem}:
- a
- b
- x[1]
- x[2]
- y[1, 1]
- y[2, 1]
- y[1, 2]
- y[2, 2]
source
@free_groupMacro
@free_group(args...)

Return the free group obtained from free_group(args...) and introduce its generators as Julia variables into the current scope.

Examples

julia> F = @free_group(:a, :b)
-Free group of rank 2
-
-julia> a^2*b*a*b^-2
-a^2*b*a*b^-2

Note that the varname => vector syntax for specifying a vector or matrix or general array of variables behaves slightly differently compared to free_group, as the following example demonstrates.

julia> U1 = free_group("x" => 1:3); gens(U1)
-3-element Vector{FPGroupElem}:
- x[1]
- x[2]
- x[3]
-
-julia> U2 = @free_group("x" => 1:3); gens(U2)
-3-element Vector{FPGroupElem}:
- x1
- x2
- x3
-
-julia> (x2^x1)^-1
-x1^-1*x2^-1*x1
source
full_groupMethod
full_group(G::T) where T <: Union{SubFPGroup, SubPcGroup}
-full_group(G::T) where T <: Union{FPGroup, PcGroup}

Return F, emb where F is the full pc group of f.p. group of which G is a subgroup, and emb is an embedding of G into F.

Examples

julia> G = perfect_group(FPGroup, 60, 1);
-
-julia> H = sylow_subgroup(G, 2)[1];
-
-julia> full_group(H)[1] == G
-true
-
-julia> full_group(G)[1] == G
-true
source
relatorsMethod
relators(G::FPGroup)

Return a vector of relators for the full finitely presented group G, i.e., elements $[w_1, w_2, \ldots, w_n]$ in $F =$ free_group(ngens(G)) such that G is isomorphic with $F/[w_1, w_2, \ldots, w_n]$.

Examples

julia> f = @free_group(:x, :y);
-
-julia> q = quo(f, [x^2, y^2, comm(x, y)])[1];  relators(q)
-3-element Vector{FPGroupElem}:
- x^2
- y^2
- x^-1*y^-1*x*y
source
lengthMethod
length(g::Union{FPGroupElem, SubFPGroupElem})

Return the length of g as a word in terms of the generators of its parent or of the full group of its parent if g is an element of a free group, otherwise an exception is thrown.

Examples

julia> F = @free_group(:F1, :F2);
-
-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_wordMethod
map_word(g::Union{FPGroupElem, SubFPGroupElem}, 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_1} 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[$i_j$]$^{e_j}$.

If g is an element of (a subgroup of) a finitely presented group then the result is defined as map_word applied to a representing element of the underlying free group of full_group(parent(g)). In particular, genimgs are interpreted as the images of the generators of this free group, not of gens(parent(g)).

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[$|k_i|$]$^{\epsilon_i}$ 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 init is different from nothing then the product gets initialized with init.

If v has length zero then init is returned if also genimgs has length zero, otherwise one(genimgs[1]) is returned. Thus the intended value for the empty word must be specified as init whenever it is possible that the elements in genimgs do not support one.

Examples

julia> F = @free_group(:F1, :F2);
-
-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> map_word(one(F), imgs, init = imgs[1])
-(1,2,3,4)
-
-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/PR4245/Groups/group_characters/index.html b/previews/PR4245/Groups/group_characters/index.html deleted file mode 100644 index e6625e416866..000000000000 --- a/previews/PR4245/Groups/group_characters/index.html +++ /dev/null @@ -1,462 +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 the Atlas of Finite Groups [CCNPW85] and from the Atlas of Brauer Characters [JLPW95] are available in OSCAR. Such character tables can be fetched with character_table(id::String, p::Int = 0) from the database, via their names. Moreover, the library of character tables can be used similar to group libraries (see Group libraries) in the sense that all_character_table_names returns descriptions of all those available character tables that have certain properties.

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.

The character table to which a character chi belongs can be fetched as parent(chi).

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_tableMethod
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;
-Character table of Sym(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;
-2-modular Brauer table of Sym(3)
-
- 2  1  .
- 3  1  1
-
-   1a 3a
-2P 1a 3a
-3P 1a 1a
-
-χ₁  1  1
-χ₂  2 -1
source
character_tableFunction
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

Several names can be admissible for the same character table from the library. For example, the alternating group on five points is isomorphic to the projective special linear groups in dimension 2 over the fields with four or five elements, and each of the strings "A5", "L2(4)", "L2(5)" is an admissible name for its library character table. The names are not case sensitive, thus also "a5" is admissible.

Use all_character_table_names for creating a vector that contains one admissible name for each available character table, perhaps filtered by some conditions.

source
character_tableMethod
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")vector [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
quoMethod
quo(tbl::GAPGroupCharacterTable, nclasses::Vector{Int})

Return the pair (fact, proj) where fact is the character table of the factor of tbl modulo the normal subgroup that is the normal closure of the conjugacy classes whose positions are listed in nclasses, and proj is the class fusion from tbl to fact.

Examples

julia> t = character_table("2.A5");
-
-julia> n = class_positions_of_center(t);  println(n)
-[1, 2]
-
-julia> fact, proj = quo(t, n);
-
-julia> order(fact)
-60
-
-julia> println(proj)
-[1, 1, 2, 3, 3, 4, 4, 5, 5]
source
all_character_table_namesFunction
all_character_table_names(L...; ordered_by = nothing)

Return a vector of strings that contains an admissible name of each character table in the character table library that satisfies the conditions in the vector 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_of_conjugacy_classes => 1))
-1
source
is_character_table_nameFunction
is_character_table_name(name::String)

Return true if character_table(name) returns a character table, and false otherwise

Examples

julia> is_character_table_name("J1")
-true
-
-julia> is_character_table_name("J5")
-false
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
conductorMethod
conductor(::Type{T} = ZZRingElem, chi::GAPGroupClassFunction)
-          where T <: IntegerUnion

Return the minimal integer n, as an instance of T, such that all values of chi lie in the n-th cyclotomic field.

Examples

julia> tbl = character_table("A5");
-
-julia> println([conductor(chi) for chi in tbl])
-ZZRingElem[1, 5, 5, 1, 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(==(conj(x)), tbl) for x in tbl])
-[1, 3, 2, 4]
source
degreeMethod
degree(::Type{T} = QQFieldElem, chi::GAPGroupClassFunction)
-       where T <: Union{IntegerUnion, QQFieldElem, QQAbFieldElem}

Return chi[1], as an instance of T.

source
galois_orbit_sumFunction
galois_orbit_sum(chi::GAPGroupClassFunction)

Return a class function psi. If chi is an ordinary character then psi is the sum of all different Galois conjugates of chi; the values of psi are rationals. If chi is a Brauer character then psi is the sum of all different images of chi under powers of the Frobenius automorphism; thus psi is afforded by a representation over the prime field, but the values of psi need not be rationals.

Examples

julia> t = character_table("A5");
-
-julia> println([degree(character_field(x)[1]) for x in t])
-[1, 2, 2, 1, 1]
-
-julia> println([degree(character_field(galois_orbit_sum(x))[1]) for x in t])
-[1, 1, 1, 1, 1]
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

block_distributionFunction
block_distribution(tbl::GAPGroupCharacterTable, p::IntegerUnion)

Return a dictionary with the keys :defect (the vector containing at position i the defect of the i-th p-block of tbl) and :block (the vector containing at position i the number j such that tbl[i] belongs to the j-th p-block).

An exception is thrown if tbl is not an ordinary character table.

Examples

julia> block_distribution(character_table("A5"), 2)
-Dict{Symbol, Vector{Int64}} with 2 entries:
-  :block  => [1, 1, 1, 2, 1]
-  :defect => [2, 0]
source
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.

Note that the vectors conjugacy_classes(group(tbl)) and conjugacy_classes(tbl) are independent. They will usually have the same ordering, but it may happen that they are ordered differently.

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
identifierMethod
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, classes::AbstractVector{Int} = 1:nrows(tbl))

Return the vector of permutation characters of tbl that are induced from cyclic subgroups. If classes is given then only the cyclic subgroups generated by elements in the classes at positions in this vector are returned.

Examples

julia> t = character_table("A5");
-
-julia> ind = induced_cyclic(t);
-
-julia> all(x -> scalar_product(x, t[1]) == 1, ind)
-true
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 a vector 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 vector 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(in(names_of_fusion_sources(tbl)), maxes(tbl))
-true
source
class_lengthsMethod
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 vector 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_representativesMethod
orders_class_representatives(tbl::GAPGroupCharacterTable)

Return the vector 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 QQAbFieldElem(1) in each position.

Examples

julia> t = character_table(symmetric_group(4));
-
-julia> all(==(1), trivial_character(t))
-true
source
regular_characterMethod
regular_character(tbl::GAPGroupCharacterTable)

Return the regular character of tbl.

Examples

julia> tbl = character_table(symmetric_group(3));
-
-julia> values(regular_character(tbl))
-3-element Vector{QQAbFieldElem{AbsSimpleNumFieldElem}}:
- 6
- 0
- 0
source
linear_charactersMethod
linear_characters(tbl::GAPGroupCharacterTable)

Return the array of linear characters of tbl, that is, the characters of degree 1.

Examples

julia> tbl = character_table(symmetric_group(3));
-
-julia> length(linear_characters(tbl))
-2
source

The following properties of a group can be read off from its character table. Therefore it is supported to call these functions with a character table.

is_abelianMethod
is_abelian(tbl::GAPGroupCharacterTable)

Return whether tbl is the ordinary character table of an abelian group, see is_abelian(G::GAPGroup).

Examples

julia> is_abelian(character_table("A5"))
-false
-
-julia> is_abelian(character_table("C2"))
-true
source
is_almost_simpleMethod
is_almost_simple(tbl::GAPGroupCharacterTable)

Return whether tbl is the ordinary character table of an almost simple group, see is_almost_simple(G::GAPGroup).

Examples

julia> is_almost_simple(character_table("S5"))
-true
-
-julia> is_almost_simple(character_table("S4"))
-false
source
is_cyclicMethod
is_cyclic(tbl::GAPGroupCharacterTable)

Return whether tbl is the ordinary character table of a cyclic group, see is_cyclic(G::GAPGroup).

Examples

julia> is_cyclic(character_table("C2"))
-true
-
-julia> is_cyclic(character_table("S4"))
-false
source
is_elementary_abelianMethod
is_elementary_abelian(tbl::GAPGroupCharacterTable)

Return whether tbl is the ordinary character table of an elementary abelian group, see is_elementary_abelian(G::GAPGroup).

Examples

julia> is_elementary_abelian(character_table("C2"))
-true
-
-julia> is_elementary_abelian(character_table("S4"))
-false
source
is_nilpotentMethod
is_nilpotent(tbl::GAPGroupCharacterTable)

Return whether tbl is the ordinary character table of a nilpotent group, see is_nilpotent(G::GAPGroup).

Examples

julia> is_nilpotent(character_table("C2"))
-true
-
-julia> is_nilpotent(character_table("S4"))
-false
source
is_perfectMethod
is_perfect(tbl::GAPGroupCharacterTable)

Return whether tbl is the ordinary character table of a perfect group, see is_perfect(G::GAPGroup).

Examples

julia> is_perfect(character_table("A5"))
-true
-
-julia> is_perfect(character_table("S4"))
-false
source
is_quasisimpleMethod
is_quasisimple(tbl::GAPGroupCharacterTable)

Return whether tbl is the ordinary character table of a quasisimple group, see is_quasisimple(G::GAPGroup).

Examples

julia> is_quasisimple(character_table("A5"))
-true
-
-julia> is_quasisimple(character_table("S4"))
-false
source
is_simpleMethod
is_simple(tbl::GAPGroupCharacterTable)

Return whether tbl is the ordinary character table of a simple group, see is_simple(G::GAPGroup).

Examples

julia> is_simple(character_table("A5"))
-true
-
-julia> is_simple(character_table("S4"))
-false
source
is_solvableMethod
is_solvable(tbl::GAPGroupCharacterTable)

Return whether tbl is the ordinary character table of a solvable group, see is_solvable(G::GAPGroup).

Examples

julia> is_solvable(character_table("A5"))
-false
-
-julia> is_solvable(character_table("S4"))
-true
source
is_sporadic_simpleMethod
is_sporadic_simple(tbl::GAPGroupCharacterTable)

Return whether tbl is the ordinary character table of a sporadic simple group, see is_sporadic_simple(G::GAPGroup).

Examples

julia> is_sporadic_simple(character_table("A5"))
-false
-
-julia> is_sporadic_simple(character_table("M11"))
-true
source
is_supersolvableMethod
is_supersolvable(tbl::GAPGroupCharacterTable)

Return whether tbl is the ordinary character table of a supersolvable group, see is_supersolvable(G::GAPGroup).

Examples

julia> is_supersolvable(character_table("A5"))
-false
-
-julia> is_supersolvable(character_table("S3"))
-true
source

Construct group characters from groups

linear_charactersMethod
linear_characters(G::Union{GAPGroup, FinGenAbGroup})

Return the array of linear characters of G, that is, the characters of degree 1.

Examples

julia> G = symmetric_group(3);
-
-julia> length(linear_characters(G))
-2
source
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{AbsSimpleNumFieldElem}})

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)))
-QQAbFieldElem{AbsSimpleNumFieldElem}[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)))
-QQAbFieldElem{AbsSimpleNumFieldElem}[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)))
-QQAbFieldElem{AbsSimpleNumFieldElem}[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)))
-QQAbFieldElem{AbsSimpleNumFieldElem}[2, -1]
source
trivial_characterMethod
trivial_character(G::GAPGroup)

Return the character of (the ordinary character table of) G that has the value QQAbFieldElem(1) in each position.

Examples

julia> g = symmetric_group(4);
-
-julia> all(==(1), trivial_character(g))
-true
source
regular_characterMethod
regular_character(G::GAPGroup)

Return the regular character of G.

Examples

julia> G = symmetric_group(3);
-
-julia> values(regular_character(G))
-3-element Vector{QQAbFieldElem{AbsSimpleNumFieldElem}}:
- 6
- 0
- 0
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_productMethod
scalar_product(::Type{T} = QQFieldElem, chi::GAPGroupClassFunction, psi::GAPGroupClassFunction)
-               where T <: Union{IntegerUnion, ZZRingElem, QQFieldElem, QQAbFieldElem}

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
tensor_productMethod
tensor_product(chi::GAPGroupClassFunction, psi::GAPGroupClassFunction)

Return the pointwise product of chi and psi. The resulting character is afforded by the tensor product of representations corresponding to chi and psi, hence the name.

Alias for chi * psi.

source
coordinatesMethod
coordinates(::Type{T} = QQFieldElem, chi::GAPGroupClassFunction)
-               where T <: Union{IntegerUnion, ZZRingElem, QQFieldElem, QQAbFieldElem}

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(4)
-
-julia> chi = natural_character(g);
-
-julia> coordinates(Int, chi)
-5-element Vector{Int64}:
- 0
- 0
- 0
- 1
- 1
-
-julia> t = parent(chi);  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))
-QQAbFieldElem{AbsSimpleNumFieldElem}[4, 0, 1, -1, -1]
-
-julia> println(multiplicities_eigenvalues(chi, 5))
-[1, 1, 1, 1, 0]
source
induceMethod
induce(chi::GAPGroupClassFunction, G::Union{GAPGroup, FinGenAbGroup})
-induce(chi::GAPGroupClassFunction, tbl::GAPGroupCharacterTable[, fusion::Vector{Int}])

Return the class function of G or tbl that is induced from chi, which is a class function of a subgroup of G or 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.

The syntax chi^tbl and chi^G is also supported.

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, H::Union{GAPGroup, FinGenAbGroup})
-restrict(chi::GAPGroupClassFunction, subtbl::GAPGroupCharacterTable[, fusion::Vector{Int}])

Return the class function of H or subtbl that is the restriction of chi, which is a class function of a supergroup of H or 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.

Examples

julia> t1 = character_table("A5");  t2 = character_table("A6");
-
-julia> known_class_fusion(t1, t2)
-(true, [1, 2, 3, 6, 7])
-
-julia> known_class_fusion(t2, t1)
-(false, Int64[])
source
known_class_fusionsFunction
known_class_fusions(tbl::GAPGroupCharacterTable)

Return the vector of pairs (name, fus) where name is the identifier of a character table and fus is the stored class fusion from tbl to this table, see known_class_fusion.

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;
-                       decompose::Bool = true,
-                       fusionmap::Vector = [])

Return the vector of possible class fusions from subtbl to tbl. Each entry is an vector 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.

If decompose is set to true then the strategy is changed: The decomposability of restricted characters of tbl as integral linear combinations of characters of subtbl (with perhaps negative coefficients) is not checked; this does not change the result, but in certain situations it is faster to omit this step.

If fusionmap is set to a vector of integers and integer vectors then only those maps are returned that are compatible with the prescribed value.

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
approximate_class_fusionFunction
approximate_class_fusion(subtbl::GAPGroupCharacterTable,
-                         tbl::GAPGroupCharacterTable)

Compute for each class of subtbl all those classes in tbl to which it can fuse under an embedding of the group of subtbl into the group of tbl, according to element orders and centralizer orders in the two tables.

If no embedding is possible then return an empty vector. Otherwise return a vector of length equal to the number of classes of subtbl, such that the entry at position $i$ either an integer (if there is a unique possible image class) or the vector of the positions of possible image classes.

Examples

julia> subtbl = character_table("A5"); tbl = character_table("A6");
-
-julia> println(approximate_class_fusion(subtbl, tbl))
-Union{Int64, Vector{Int64}}[1, 2, [3, 4], [6, 7], [6, 7]]
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_centerMethod
class_positions_of_center(tbl::GAPGroupCharacterTable)

Return the vector of integers $i$ such that the $i$-th conjugacy class of tbl is contained in the center of the group $G$ of tbl, i.e., the $i$-th class has length 1.

Examples

julia> tbl = character_table(dihedral_group(8));
-
-julia> println(class_positions_of_center(tbl))
-[1, 4]
source
class_positions_of_centerMethod
class_positions_of_center(chi::GAPGroupClassFunction)

Return the vector 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
class_positions_of_derived_subgroupFunction
class_positions_of_derived_subgroup(tbl::GAPGroupCharacterTable)

Return the vector of integers $i$ such that the $i$-th conjugacy class of tbl is contained in the derived subgroup of the group $G$ of tbl.

Examples

julia> tbl = character_table(dihedral_group(8));
-
-julia> println(class_positions_of_derived_subgroup(tbl))
-[1, 4]
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 vector 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_normal_subgroupsFunction
class_positions_of_normal_subgroups(tbl::GAPGroupCharacterTable)

Return a vector whose entries describe all normal subgroups of the group of tbl. Each entry is a vector of those class positions such that the union of these classes forms a normal subgroup.

Examples

julia> t = character_table("2.A5");
-
-julia> class_positions_of_normal_subgroups(t)
-3-element Vector{Vector{Int64}}:
- [1]
- [1, 2]
- [1, 2, 3, 4, 5, 6, 7, 8, 9]
source
class_positions_of_pcoreFunction
class_positions_of_pcore(tbl::GAPGroupCharacterTable, p::IntegerUnion)

Return the vector 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
class_positions_of_solvable_residuumFunction
class_positions_of_solvable_residuum(tbl::GAPGroupCharacterTable)

Return the vector of integers $i$ such that the $i$-th conjugacy class of tbl is contained in the solvable residuum of the group $G$ of tbl, i.e., the smallest normal subgroup $N$ of $G$ such that the factor group $G/N$ is solvable. This normal subgroup is equal to the last term of the derived series of $G$, see derived_series.

Examples

julia> tbl = character_table(symmetric_group(4));
-
-julia> println(class_positions_of_solvable_residuum(tbl))
-[1]
source
diff --git a/previews/PR4245/Groups/grouphom/index.html b/previews/PR4245/Groups/grouphom/index.html deleted file mode 100644 index 8d9d288908c1..000000000000 --- a/previews/PR4245/Groups/grouphom/index.html +++ /dev/null @@ -1,82 +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(T::TorQuadModule) -> TorQuadModuleMap

Alias for identity_map.

source
id_hom(G::GAPGroup)

Return the identity homomorphism on the group G.

source
trivial_morphismFunction
trivial_morphism(T::TorQuadModule, U::TorQuadModule) -> TorQuadModuleMap

Return the abelian group homomorphism between T and U sending every elements of T to the zero element of U.

source
trivial_morphism(T::TorQuadModule) -> TorQuadModuleMap

Return the abelian group endomorphism of T sending every elements of T to the zero element of T.

source
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

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

has_preimage_with_preimageMethod
has_preimage_with_preimage(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> has_preimage_with_preimage(f,x)
-(true, (1,4))

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::GAPGroup)

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::GAPGroup) 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

For all functions that return group isomorphisms, we have the following rule about the direction of the result.

If two groups are given as inputs then the domain of the returned isomorphism is the first given group and the codomain is the second.

If one group is given then the domain of the result is this group, and the codomain is some new group constructed by the function.

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, Hom: Sym(3) -> pc group)
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(3)
-  to pc group of order 6
source
isomorphismMethod
isomorphism(::Type{T}, G::GAPGroup) where T <: Union{SubPcGroup, SubFPGroup, PermGroup}
-isomorphism(::Type{T}, G::GAPGroup; on_gens=false) where T <: Union{PcGroup, FPGroup}

Return an isomorphism from G to a group H of type T. An exception is thrown if no such isomorphism exists.

If on_gens is true then gens(G) is guaranteed to correspond to gens(H); an exception is thrown if this is not possible.

Isomorphisms are cached in G, subsequent calls of isomorphism with the same T (and the same value of on_gens) 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 order 6
-
-julia> iso = isomorphism(PermGroup, G)
-Group homomorphism
-  from pc group of order 6
-  to permutation group of degree 3 and order 6
-
-julia> permutation_group(G)
-Permutation group of degree 3 and order 6
-
-julia> codomain(iso) === ans
-true
source
isomorphismMethod
isomorphism(::Type{FinGenAbGroup}, G::GAPGroup)

Return a map from G to an isomorphic (additive) group of type FinGenAbGroup. 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 of rank 3
-
-julia> G = quo(F, [gen(F,1)])[1]
-Finitely presented group of infinite order
-
-julia> simplified_fp_group(G)[1]
-Finitely presented group of infinite order
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 of rank 2
-  to Sym(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/PR4245/Groups/grouplib/index.html b/previews/PR4245/Groups/grouplib/index.html deleted file mode 100644 index 171d9ee66028..000000000000 --- a/previews/PR4245/Groups/grouplib/index.html +++ /dev/null @@ -1,271 +0,0 @@ - -Group libraries · Oscar.jl

Group libraries

Transitive permutation groups of small degree

The functions in this section are wrappers for the GAP library of transitive permutation groups up to degree 48, via the GAP package TransGrp [Hul23].

(The groups of degrees 32 and 48 are currently not automatically available in Oscar, one has to install additional data in order to access them.)

The arrangement and the names of the groups of degree up to 15 is the same as given in [CHM98]. 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

As a special case, the first argument may also be one of the following:

  • intval selects groups whose degree equals intval; this is equivalent to degree => intval
  • intlist selects groups whose degree is in intlist; this is equivalent to degree => intlist

The following functions are currently supported as values for func:

  • degree
  • is_abelian
  • is_almost_simple
  • is_cyclic
  • is_nilpotent
  • is_perfect
  • is_primitive
  • is_quasisimple
  • is_simple
  • is_sporadic_simple
  • is_solvable
  • is_supersolvable
  • is_transitive
  • number_of_conjugacy_classes
  • number_of_moved_points
  • order
  • transitivity

The type of the returned groups is PermGroup.

Examples

julia> all_transitive_groups(4)
-5-element Vector{PermGroup}:
- Permutation group of degree 4
- Permutation group of degree 4
- Permutation group of degree 4
- Alt(4)
- Sym(4)
-
-julia> all_transitive_groups(degree => 3:5, is_abelian)
-4-element Vector{PermGroup}:
- Alt(3)
- Permutation group of degree 4
- Permutation group of degree 4
- Permutation group of degree 5
source
has_number_of_transitive_groupsFunction
has_number_of_transitive_groups(deg::Int)

Return whether the number transitive groups groups of degree deg are available for use via number_of_transitive_groups.

Examples

julia> has_number_of_transitive_groups(30)
-true
-
-julia> has_number_of_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_of_transitive_groupsFunction
number_of_transitive_groups(deg::Int)

Return the number of transitive groups of degree deg, up to permutation isomorphism.

Examples

julia> number_of_transitive_groups(30)
-5712
-
-julia> number_of_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)
-Alt(5)
-
-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]
-Permutation group of degree 7
-
-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

The functions in this section are wrappers for the GAP library of primitive permutation groups up to degree 8191, via the GAP package PrimGrp [HRR23]. See the documentation of this package for more information about the source of the data.

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

As a special case, the first argument may also be one of the following:

  • intval selects groups whose degree equals intval; this is equivalent to degree => intval
  • intlist selects groups whose degree is in intlist; this is equivalent to degree => intlist

The following functions are currently supported as values for func:

  • degree
  • is_abelian
  • is_almost_simple
  • is_cyclic
  • is_nilpotent
  • is_perfect
  • is_primitive
  • is_quasisimple
  • is_simple
  • is_sporadic_simple
  • is_solvable
  • is_supersolvable
  • is_transitive
  • number_of_conjugacy_classes
  • number_of_moved_points
  • order
  • transitivity

The type of the returned groups is PermGroup.

Examples

julia> all_primitive_groups(4)
-2-element Vector{PermGroup}:
- Alt(4)
- Sym(4)
-
-julia> all_primitive_groups(degree => 3:5, is_abelian)
-2-element Vector{PermGroup}:
- Alt(3)
- Permutation group of degree 5 and order 5
source
has_number_of_primitive_groupsFunction
has_number_of_primitive_groups(deg::Int)

Return true if the number of primitive permutation groups of degree deg is available via number_of_primitive_groups, otherwise false.

Currently the number of primitive permutation groups is available up to degree 4095.

Examples

julia> has_number_of_primitive_groups(50)
-true
-
-julia> has_number_of_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_of_primitive_groupsFunction
number_of_primitive_groups(deg::Int)

Return the number of primitive permutation groups of degree deg, up to permutation isomorphism.

Examples

julia> number_of_primitive_groups(10)
-9
-
-julia> number_of_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)
-Permutation group of degree 10 and order 60
-
-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]
-Permutation group of degree 7 and order 720
-
-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 [HP89]. For orders 86016, 368640, or 737280 this work only counted the groups (but did not explicitly list them), the groups of orders 61440, 122880, 172032, 245760, 344064, 491520, 688128, or 983040 were omitted.

Several additional groups omitted from the book [HP89] 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 in 2005 by Jack Schmidt. 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, see [Hul22]. 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.

all_perfect_groupsFunction
all_perfect_groups(L...)

Return the list of all perfect 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

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

The following functions are currently supported as values for func:

  • is_quasisimple
  • is_simple
  • is_sporadic_simple
  • number_of_conjugacy_classes
  • order

The type of the returned groups is PermGroup.

Examples

julia> all_perfect_groups(7200)
-2-element Vector{PermGroup}:
- Permutation group of degree 29 and order 7200
- Permutation group of degree 288 and order 7200
-
-julia> all_perfect_groups(order => 1:200, !is_simple)
-2-element Vector{PermGroup}:
- Permutation group of degree 1 and order 1
- Permutation group of degree 24 and order 120
source
has_number_of_perfect_groupsFunction
has_number_of_perfect_groups(n::Int)

Return true if the number of perfect groups of order n are available via number_of_perfect_groups, otherwise false.

Currently the number of perfect groups is available up to order $2 \cdot 10^6$.

Examples

julia> has_number_of_perfect_groups(7200)
-true
-
-julia> has_number_of_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_of_perfect_groupsFunction
number_of_perfect_groups(n::IntegerUnion)

Return the number of perfect groups of order n, up to isomorphism.

Examples

julia> number_of_perfect_groups(60)
-1
-
-julia> number_of_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)
-Permutation group of degree 5 and order 60
-
-julia> gens(ans)
-2-element Vector{PermGroupElem}:
- (1,2)(4,5)
- (2,3,4)
-
-julia> perfect_group(FPGroup, 60, 1)
-Finitely presented group of order 60
-
-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

The functions in this section are wrappers for the GAP library of the following groups.

The GAP package SmallGrp [BEO23] provides

  • those of order at most 2000 (except those of order 1024),
  • those of cubefree order at most 50000,
  • those of order $p^7$ for the primes $p = 3, 5, 7, 11$,
  • those of order $p^n$ for $n \leq 6$ and all primes $p$,
  • those of order $q^n p$ where $q^n$ divides $2^8$, $3^6$, $5^5$ or $7^4$ and $p$ is an arbitrary prime not equal to $q$,
  • those of squarefree order,
  • those whose order factorises into at most 3 primes.

The GAP package SOTGrps [Pan23] provides

  • those whose order factorises into at most 4 primes,
  • those of order $p^4 q$ where $p$ and $q$ are distinct primes.

The GAP package SglPPow [VE22] provides

  • those of order $p^7$ for primes $p > 11$,
  • those of order $3^8$.
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:

  • exponent
  • is_abelian
  • is_almost_simple
  • is_cyclic
  • is_nilpotent
  • is_perfect
  • is_quasisimple
  • is_simple
  • is_sporadic_simple
  • is_solvable
  • is_supersolvable
  • number_of_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 order 12

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 order 6
- Pc group of order 8
- Pc group of order 8
- Pc group of order 10
source
has_number_of_small_groupsFunction
has_number_of_small_groups(n::IntegerUnion)

Return true if the number of groups of order n is known, otherwise false.

Examples

julia> has_number_of_small_groups(1024)
-true
-
-julia> has_number_of_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_of_small_groupsFunction
number_of_small_groups(n::IntegerUnion)

Return the number of groups of order n, up to isomorphism.

Examples

julia> number_of_small_groups(8)
-5
-
-julia> number_of_small_groups(4096)
-ERROR: ArgumentError: the number of groups of order 4096 is not available
-
-julia> number_of_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 order 60
-
-julia> small_group(60, 5)
-Permutation group of degree 5 and order 60
-
-julia> small_group(PcGroup, 60, 4)
-Pc group of order 60
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 [ATLAS]. 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_of_atlas_groupsFunction
number_of_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_of_atlas_groups("A5")
-18
-
-julia> number_of_atlas_groups(PermGroup, "A5")
-3
-
-julia> number_of_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(:constituents => [1, 4], :repname => "A5G1-p5B0", :degree => 5, :name => "A5")
- Dict(:constituents => [1, 5], :repname => "A5G1-p6B0", :degree => 6, :name => "A5")
-
-julia> atlas_group(info[1])
-Permutation group of degree 5 and order 60
-
-julia> info = all_atlas_group_infos("A5", dim => 4, characteristic => 3)
-1-element Vector{Dict{Symbol, Any}}:
- Dict(:dim => 4, :constituents => [4], :repname => "A5G1-f3r4B0", :name => "A5")
-
-julia> atlas_group(info[1])
-Matrix group of degree 4
-  over prime field of characteristic 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
-Permutation group of degree 5 and order 60
-
-julia> atlas_group(MatrixGroup, "A5")
-Matrix group of degree 4
-  over prime field of characteristic 2
-
-julia> atlas_group("M11")  # Mathieu group M11
-Permutation group of degree 11 and order 7920
-
-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(:constituents => [1, 4], :repname => "A5G1-p5B0", :degree => 5, :name => "A5")
-
-julia> atlas_group(info[1])
-Permutation group of degree 5 and order 60
-
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
-Permutation group of degree 11 and order 720
-
-julia> order(h1)  # largest maximal subgroup of M11
-720
-
-julia> h2, emb = atlas_subgroup("M11", 1);  h2
-Permutation group of degree 11 and order 720
-
-julia> h3, emb = atlas_subgroup(MatrixGroup, "M11", 1 );  h3
-Matrix group of degree 10
-  over prime field of characteristic 2
-
-julia> info = all_atlas_group_infos("M11", degree => 11);
-
-julia> h4, emb = atlas_subgroup(info[1], 1);  h4
-Permutation group of degree 11 and order 720
source
diff --git a/previews/PR4245/Groups/intro/index.html b/previews/PR4245/Groups/intro/index.html deleted file mode 100644 index cfea2356b09a..000000000000 --- a/previews/PR4245/Groups/intro/index.html +++ /dev/null @@ -1,2 +0,0 @@ - -Introduction · Oscar.jl
diff --git a/previews/PR4245/Groups/matgroup/index.html b/previews/PR4245/Groups/matgroup/index.html deleted file mode 100644 index 693737ffbd7e..000000000000 --- a/previews/PR4245/Groups/matgroup/index.html +++ /dev/null @@ -1,127 +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
map_entriesMethod
map_entries(f, G::MatrixGroup)

Return the matrix group obtained by applying f element-wise to each generator of G.

f can be a ring or a field, a suitable map, or a Julia function.

Examples

julia> mat = matrix(ZZ, 2, 2, [1, 1, 0, 1]);
-
-julia> G = matrix_group(mat);
-
-julia> G2 = map_entries(x -> -x, G)
-Matrix group of degree 2
-  over integer ring
-
-julia> is_finite(G2)
-false
-
-julia> order(map_entries(GF(3), G))
-3
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
number_of_rows(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
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

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::AbstractVector{T}) where {T <: NCRingElement}

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]
source
lower_triangular_matrixMethod
lower_triangular_matrix(L::AbstractVector{T}) where {T <: NCRingElement}

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]
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 R must be either a finite field or a residue ring or ZZ.

Examples

julia> F = GF(7)
-Prime field of characteristic 7
-
-julia> H = general_linear_group(2, F)
-GL(2,7)
-
-julia> gens(H)
-2-element Vector{MatrixGroupElem{FqFieldElem, FqMatrix}}:
- [3 0; 0 1]
- [6 1; 6 0]
-
-julia> order(general_linear_group(2, residue_ring(ZZ, 6)[1]))
-288
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 R must be either a finite field or a residue ring or ZZ.

Examples

julia> F = GF(7)
-Prime field of characteristic 7
-
-julia> H = special_linear_group(2, F)
-SL(2,7)
-
-julia> gens(H)
-2-element Vector{MatrixGroupElem{FqFieldElem, FqMatrix}}:
- [3 0; 0 5]
- [6 1; 6 0]
-
-julia> order(special_linear_group(2, residue_ring(ZZ, 6)[1]))
-144
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 R must be either a finite field or a residue ring of prime power order.

Examples

julia> F = GF(7)
-Prime field of characteristic 7
-
-julia> H = symplectic_group(2, F)
-Sp(2,7)
-
-julia> gens(H)
-2-element Vector{MatrixGroupElem{FqFieldElem, FqMatrix}}:
- [3 0; 0 5]
- [6 1; 6 0]
-
-julia> order(symplectic_group(2, residue_ring(ZZ, 4)[1]))
-48
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 R must be either a finite field or a residue ring of odd prime power order.

Examples

julia> F = GF(7)
-Prime field of characteristic 7
-
-julia> H = orthogonal_group(1, 2, F)
-GO+(2,7)
-
-julia> gens(H)
-2-element Vector{MatrixGroupElem{FqFieldElem, FqMatrix}}:
- [3 0; 0 5]
- [0 1; 1 0]
-
-julia> order(orthogonal_group(-1, 2, residue_ring(ZZ, 9)[1]))
-24
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 R must be either a finite field or a residue ring of odd prime power order.

Examples

julia> F = GF(7)
-Prime field of characteristic 7
-
-julia> H = special_orthogonal_group(1, 2, F)
-SO+(2,7)
-
-julia> gens(H)
-3-element Vector{MatrixGroupElem{FqFieldElem, FqMatrix}}:
- [3 0; 0 5]
- [5 0; 0 3]
- [1 0; 0 1]
-
-julia> order(special_orthogonal_group(-1, 2, residue_ring(ZZ, 9)[1]))
-12
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 R must be either a finite field or a residue ring of odd prime power order.

Examples

julia> F = GF(7)
-Prime field of characteristic 7
-
-julia> H = omega_group(1, 2, F)
-Omega+(2,7)
-
-julia> gens(H)
-1-element Vector{MatrixGroupElem{FqFieldElem, FqMatrix}}:
- [2 0; 0 4]
-
-julia> order(omega_group(0, 3, residue_ring(ZZ, 9)[1]))
-324
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{FqFieldElem, FqMatrix}}:
- [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{FqFieldElem, FqMatrix}}:
- [1 2*o+2; 0 1]
- [0 2*o+2; 2*o+2 0]
source
diff --git a/previews/PR4245/Groups/pcgroup/index.html b/previews/PR4245/Groups/pcgroup/index.html deleted file mode 100644 index afc117dac8c1..000000000000 --- a/previews/PR4245/Groups/pcgroup/index.html +++ /dev/null @@ -1,52 +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.

For a group G of type PcGroup, the elements in gens(G) satisfy the relators of the underlying presentation.

Functions that compute subgroups of G return groups of type SubPcGroup.

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, 3]);
-
-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
map_wordMethod
map_word(g::Union{PcGroupElem, SubPcGroupElem}, 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, which is a product of the form $g_{i_1}^{e_1} g_{i_2}^{e_2} \cdots g_{i_n}^{e_n}$ where $g_i$ is the $i$-th entry in the defining polycyclic generating sequence of full_group(parent(g)) and the $e_i$ are nonzero integers, and $R_j =$ imgs[$i_j$]$^{e_j}$.

Examples

julia> G = dihedral_group(10)
-Pc group of order 10
-
-julia> x, y = gens(G);  g = x * y^4
-f1*f2^4
-
-julia> map_word(g, gens(free_group(:x, :y)))
-x*y^4
source

Julia has the following functions that allow to generate polycyclic groups:

abelian_groupMethod
abelian_group(::Type{T} = PcGroup, v::Vector{S}) where T <: Group where S <: IntegerUnion

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, SubFPGroup, PcGroup, or SubPcGroup.

The gens value of the returned group corresponds to v, that is, the number of generators is equal to length(v) and the order of the i-th generator is v[i].

Warning

The type need to be specified in the input of the function abelian_group, otherwise a group of type FinGenAbGroup is returned, which is not a GAP group type. In future versions of Oscar, this may change.

source
elementary_abelian_groupFunction
elementary_abelian_group(::Type{T} = PcGroup, n::S) where T <: Group where S <: IntegerUnion

Return the elementary abelian group group of order n, as an instance of T. Here, T must be one of PermGroup, FPGroup, SubFPGroup, PcGroup, SubPcGroup, or FinGenAbGroup, and n must be a prime power or 1.

The gens vector of the result has minimal length.

Examples

julia> g = elementary_abelian_group(27)
-Pc group of order 27
-
-julia> g = elementary_abelian_group(PermGroup, 27)
-Permutation group of degree 9 and order 27
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 order 5
-
-julia> G = cyclic_group(PermGroup, 5)
-Permutation group of degree 5 and order 5
-
-julia> G = cyclic_group(PosInf())
-Pc group of infinite order
-
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, SubPcGroup, PermGroup, FPGroup, SubFPGroup}.

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 order 6
-
-julia> dihedral_group(PermGroup, 6)
-Permutation group of degree 3
-
-julia> dihedral_group(PosInf())
-Pc group of infinite order
-
-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, SubPcGroup, PermGroup,FPGroup, SubFPGroup}.

Examples

julia> g = quaternion_group(8)
-Pc group of order 8
-
-julia> quaternion_group(PermGroup, 8)
-Permutation group of degree 8
-
-julia> g = quaternion_group(FPGroup, 8)
-Finitely presented group of order 8
-
-julia> relators(g)
-3-element Vector{FPGroupElem}:
- r^2*s^-2
- s^4
- r^-1*s*r*s
-
source
diff --git a/previews/PR4245/Groups/permgroup/index.html b/previews/PR4245/Groups/permgroup/index.html deleted file mode 100644 index 9ea84c4256bd..000000000000 --- a/previews/PR4245/Groups/permgroup/index.html +++ /dev/null @@ -1,404 +0,0 @@ - -Permutation groups · Oscar.jl

Permutation groups

Constructing 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(5)
-
-julia> x=cperm([1,2,3])
-(1,2,3)
-
-julia> parent(x)
-Sym(3)
-
-julia> y=G(x)
-(1,2,3)
-
-julia> parent(y)
-Sym(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(6)
-
-julia> x = G([2,4,6,1,3,5])
-(1,2,4)(3,6,5)
-
-julia> parent(x)
-Sym(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(5)
-
-julia> order(G)
-120
-
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(5)
-
-julia> order(G)
-60
-
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])
-Permutation group of degree 5
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))
-Permutation group of degree 7
-
-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)
-Permutation group of degree 4 and order 24
-
-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)
-Permutation group of degree 4 and order 12
-
-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)
-Permutation group of degree 4 and order 12
-
-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)
-Permutation group of degree 10 and order 24
-
-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)
-Permutation group of degree 10 and order 12
-
-julia> order(g)
-12
source

Operations for permutation groups

All operations, properties and attributes for general groups described in the previous sections are supported for permutation groups. In addition there are some specific to permutation groups.

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.
  • One can use the syntax G(H) in order to get a group that consists of the same permutations as H but has the same degree as G, provided that the elements of H move only points up to degree(G).
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> s4 = symmetric_group(4);
-
-julia> degree(s4)
-4
-
-julia> t4 = trivial_subgroup(symmetric_group(4))[1];
-
-julia> degree(t4)
-4
-
-julia> t5 = trivial_subgroup(symmetric_group(5))[1];
-
-julia> t4 == t5
-false
-
-julia> t4 == s4(t5)
-true
-
-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
smaller_degree_permutation_representationMethod
smaller_degree_permutation_representation(G::PermGroup) -> PermGroup, map

Return an isomorphic permutation group of smaller or equal degree and the isomorphism from G to that group.

Examples

julia> g = symmetric_group(4);
-
-julia> s, _ = sylow_subgroup(g, 3);
-
-julia> rho = smaller_degree_permutation_representation(s)
-(Permutation group of degree 3 and order 3, Hom: s -> permutation group)
source

The following functions deal with the natural action of a given permutation group $G$.

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, map(representative, maximal_subgroup_classes(G)))
-3-element Vector{PermGroup}:
- Permutation group of degree 6 and order 24
- Permutation group of degree 6 and order 36
- Permutation group of degree 6 and order 60
-
-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]
-Permutation group of degree 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]
-Permutation group of degree 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 [Cam99] 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]
-Permutation group of degree 4 and order 8
-
-julia> rank_action(H)  # not 2-transitive
-3
-
-julia> K = stabilizer(G, 1)[1]
-Permutation group of degree 4 and order 6
-
-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]
-Permutation group of degree 4 and order 8
-
-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)
-Permutation group of degree 8
-
-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)
-Permutation group of degree 8
-
-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)
-Permutation group of degree 8
-
-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

The following functions allow efficiently "recognizing" certain permutation groups as alternating or symmetric groups.

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
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

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(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(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(5)
-
-julia> x = cperm(G,[[1,2],[3,4]])
-(1,2)(3,4)
-
-julia> parent(x)
-Sym(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(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(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
cyclesMethod
cycles(g::PermGroupElem)

Return all cycles (including trivial ones) of the permutation g as a sorted list of integer vectors.

Examples

julia> g = cperm(1:3, 6:7, 8:10, 11:15)
-(1,2,3)(6,7)(8,9,10)(11,12,13,14,15)
-
-julia> cycles(g)
-6-element Vector{Vector{Int64}}:
- [1, 2, 3]
- [4]
- [5]
- [6, 7]
- [8, 9, 10]
- [11, 12, 13, 14, 15]
-
-julia> g = cperm()
-()
-
-julia> cycles(g)
-1-element Vector{Vector{Int64}}:
- [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

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
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
diff --git a/previews/PR4245/Groups/products/index.html b/previews/PR4245/Groups/products/index.html deleted file mode 100644 index 75ec514d9727..000000000000 --- a/previews/PR4245/Groups/products/index.html +++ /dev/null @@ -1,135 +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(3)
-
-julia> K = symmetric_group(2)
-Sym(2)
-
-julia> G = direct_product(H,K)
-Direct product of
- Sym(3)
- Sym(2)
-
-julia> elements(G)
-12-element Vector{Oscar.BasicGAPGroupElem{DirectProductGroup}}:
- ()
- (4,5)
- (2,3)
- (2,3)(4,5)
- (1,3,2)
- (1,3,2)(4,5)
- (1,3)
- (1,3)(4,5)
- (1,2,3)
- (1,2,3)(4,5)
- (1,2)
- (1,2)(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, SubPcGroup, FPGroup, SubFPGroup.

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
canonical_injectionMethod
canonical_injection(G::DirectProductGroup, j::Int)

Return the injection of the j-th component of G into G, for j = 1,...,#factors of G. It is not defined for proper subgroups of direct products.

Examples

julia> H = symmetric_group(3)
-Sym(3)
-
-julia> K = symmetric_group(2)
-Sym(2)
-
-julia> G = direct_product(H, K)
-Direct product of
- Sym(3)
- Sym(2)
-
-julia> inj1 = canonical_injection(G, 1)
-Group homomorphism
-  from Sym(3)
-  to direct product of
-   Sym(3)
-   Sym(2)
-
-julia> h = perm(H, [2,3,1])
-(1,2,3)
-
-julia> inj1(h)
-(1,2,3)
-
-julia> inj2 = canonical_injection(G, 2)
-Group homomorphism
-  from Sym(2)
-  to direct product of
-   Sym(3)
-   Sym(2)
-
-julia> k = perm(K, [2,1])
-(1,2)
-
-julia> inj2(k)
-(4,5)
-
-julia> inj1(h)*inj2(k)
-(1,2,3)(4,5)
source
canonical_injectionsMethod
canonical_injections(G::DirectProductGroup)

Return the injection of the j-th component of G into G, for all j = 1,...,#factors of G. It is not defined for proper subgroups of direct products.

source
canonical_projectionMethod
canonical_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(3)
-
-julia> K = symmetric_group(2)
-Sym(2)
-
-julia> G = direct_product(H, K)
-Direct product of
- Sym(3)
- Sym(2)
-
-julia> proj1 = canonical_projection(G, 1)
-Group homomorphism
-  from direct product of
-   Sym(3)
-   Sym(2)
-  to Sym(3)
-
-julia> proj2 = canonical_projection(G, 2)
-Group homomorphism
-  from direct product of
-   Sym(3)
-   Sym(2)
-  to Sym(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
canonical_projectionsMethod
canonical_projection(G::DirectProductGroup)

Return the projection of G into the j-th component of G, for all j = 1,...,#factors of G.

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
canonical_injectionMethod
canonical_injection(G::SemidirectProductGroup, n::Int)

Return the injection of the n-th component of G into G, for n = 1,2. It is not defined for proper subgroups of semidirect products.

source
canonical_projectionMethod
canonical_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 order 3
-
-julia> H = symmetric_group(2)
-Sym(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 order 3
-
-julia> H = symmetric_group(2)
-Sym(2)
-
-julia> W = wreath_product(G,H)
-<group of size 18 with 2 generators>
-
-julia> normal_subgroup(W)
-Pc group of order 3
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 order 3
-
-julia> H = symmetric_group(2)
-Sym(2)
-
-julia> W = wreath_product(G,H)
-<group of size 18 with 2 generators>
-
-julia> acting_subgroup(W)
-Sym(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
canonical_projectionMethod
canonical_projection(G::WreathProductGroup)

Return the projection of wreath_product(G,H) onto the permutation group H.

source
canonical_injectionMethod
canonical_injection(G::WreathProductGroup, n::Int)

Return the injection of the n-th component of G into G. It is not defined for proper subgroups of wreath products.

source
canonical_injectionsMethod
canonical_injections(G::WreathProductGroup)

Return the injection of the n-th component of G into G for all n. It is not defined for proper subgroups of wreath products.

source
diff --git a/previews/PR4245/Groups/quotients/index.html b/previews/PR4245/Groups/quotients/index.html deleted file mode 100644 index 212394848b08..000000000000 --- a/previews/PR4245/Groups/quotients/index.html +++ /dev/null @@ -1,36 +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::GAPGroup, N::GAPGroup) where Q <: 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 or SubPcGroup (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(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::GAPGroup, N::GAPGroup) for information about the type of G/N.

For groups G of type SubFPGroup, this syntax is not supported. In this case, you can switch to group of different type, using isomorphism, or try to create the normal subgroup N in question, and call quo(G, N).

source

This is the typical way to build finitely presented groups.

Example:

julia> F = @free_group(2);
-
-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, FinGenAbGroup}

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/PR4245/Groups/recog/index.html b/previews/PR4245/Groups/recog/index.html deleted file mode 100644 index ac24e6fef562..000000000000 --- a/previews/PR4245/Groups/recog/index.html +++ /dev/null @@ -1,22 +0,0 @@ - -Group recognition · Oscar.jl

Group recognition

The idea of constructive group recognition is to compute a recognition tree for a given (permutation or matrix) group, which describes the structure of this group in a recursive way: Each non-leaf node of the tree describes an epimorphism such that the kernel and the image belong to the two subtrees of the node. Each leaf node describes a group for which efficient methods are available that allow one to decide whether a group element is an element of this group, and if yes to write the element as a word in terms of suitable generators.

The recognition tree has enough information to decide whether a group element is an element of the given group, and if yes to write the element as a word in terms of suitable generators of the given group.

recognizeFunction
recognize(G::Union{PermGroup, MatrixGroup})

Return a GroupRecognitionTree object that describes the structure of G in a recursive way. If the recognition was successful (see is_ready) then the result provides a membership test that is usually more efficient than the membership test without the recognition information.

Examples

julia> recognize(symmetric_group(5))
-Recognition tree: MovesOnlySmallPoints Size=120
-
-julia> g = general_linear_group(4, 9);
-
-julia> s = sub(g, [rand(g), rand(g)])[1];
-
-julia> rec = recognize(s);  is_ready(rec)
-true
-
-julia> rand(s) in rec
-true
source
is_readyFunction
is_ready(tree::GroupRecognitionTree)

Return true if the recognition procedure for the group of tree was successful, and false otherwise.

Examples

julia> rec = recognize(GL(4, 2));  is_ready(rec)
-true
source
nice_gensFunction
nice_gens(tree::GroupRecognitionTree)

Return the vector of generators of the group of tree w.r.t. which the straight line programs for group elements computed by straight_line_program are written.

Examples

julia> rec = recognize(GL(4, 2));  is_ready(rec)
-true
-
-julia> x = rand(group(rec));
-
-julia> slp = straight_line_program(rec, x);
-
-julia> evaluate(slp, nice_gens(rec)) == x
-true
source
straight_line_programMethod
straight_line_program(tree::GroupRecognitionTree, g::GAPGroupElem)

Return a straight line program for the element g of the group of tree. The inputs of this program correspond to nice_gens(tree), see nice_gens for an example.

source
diff --git a/previews/PR4245/Groups/subgroups/index.html b/previews/PR4245/Groups/subgroups/index.html deleted file mode 100644 index 48366dd7cf4d..000000000000 --- a/previews/PR4245/Groups/subgroups/index.html +++ /dev/null @@ -1,474 +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::GAPGroup, G::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
is_subgroupMethod
is_subgroup(H::GAPGroup, G::GAPGroup)

Return (true,f) if H is a subgroup of G, where f is the embedding homomorphism of H into G, otherwise return (false,nothing).

If you do not need the embedding then better call is_subset(H::GAPGroup, G::GAPGroup).

source
embeddingMethod
embedding(H::GAPGroup, G::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::GAPGroup, H::GAPGroup) where I <: IntegerUnion
-index(::Type{I} = ZZRingElem, G::FinGenAbGroup, H::FinGenAbGroup) where I <: IntegerUnion

Return the index of H in G, as an instance of type I.

Examples

julia> G = symmetric_group(5); H, _ = derived_subgroup(G);
-
-julia> index(G,H)
-2
source
is_maximal_subgroupMethod
is_maximal_subgroup(H::GAPGroup, G::GAPGroup; check::Bool = true)

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::GAPGroup, G::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::GAPGroup, G::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::GAPGroup, G::GAPGroup; check::Bool = true)

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.

Examples

julia> trivial_subgroup(symmetric_group(5))
-(Permutation group of degree 5 and order 1, Hom: permutation group -> Sym(5))
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.

Examples

julia> center(symmetric_group(3))
-(Permutation group of degree 3 and order 1, Hom: permutation group -> Sym(3))
-
-julia> center(quaternion_group(8))
-(Sub-pc group of order 2, Hom: sub-pc group -> pc group)
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 G' of G, i.e., the subgroup generated by all commutators of G, together with an embedding G' into G.

Examples

julia> derived_subgroup(symmetric_group(5))
-(Alt(5), Hom: Alt(5) -> Sym(5))
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{<:GAPGroup})

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.

normal_subgroupsFunction
normal_subgroups(G::Group)

Return all normal subgroups of G (see is_normal).

Examples

julia> normal_subgroups(symmetric_group(5))
-3-element Vector{PermGroup}:
- Sym(5)
- Alt(5)
- Permutation group of degree 5 and order 1
-
-julia> normal_subgroups(quaternion_group(8))
-6-element Vector{SubPcGroup}:
- Sub-pc group of order 8
- Sub-pc group of order 4
- Sub-pc group of order 4
- Sub-pc group of order 4
- Sub-pc group of order 2
- Sub-pc group of order 1
source
maximal_normal_subgroupsFunction
maximal_normal_subgroups(G::Group)

Return all maximal normal subgroups of G, i.e., those proper normal subgroups of G that are maximal among the proper normal subgroups.

Examples

julia> maximal_normal_subgroups(symmetric_group(4))
-1-element Vector{PermGroup}:
- Alt(4)
-
-julia> maximal_normal_subgroups(quaternion_group(8))
-3-element Vector{SubPcGroup}:
- Sub-pc group of order 4
- Sub-pc group of order 4
- Sub-pc group of order 4
source
minimal_normal_subgroupsFunction
minimal_normal_subgroups(G::Group)

Return all minimal normal subgroups of G, i.e., of those nontrivial normal subgroups of G that are minimal among the nontrivial normal subgroups.

Examples

julia> minimal_normal_subgroups(symmetric_group(4))
-1-element Vector{PermGroup}:
- Permutation group of degree 4 and order 4
-
-julia> minimal_normal_subgroups(quaternion_group(8))
-1-element Vector{SubPcGroup}:
- Sub-pc group of order 2
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.

Examples

julia> characteristic_subgroups(symmetric_group(3))
-3-element Vector{PermGroup}:
- Sym(3)
- Permutation group of degree 3 and order 3
- Permutation group of degree 3 and order 1
-
-julia> characteristic_subgroups(quaternion_group(8))
-3-element Vector{SubPcGroup}:
- Sub-pc group of order 8
- Sub-pc group of order 2
- Sub-pc group of order 1
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)$. See also derived_length.

Examples

julia> G = derived_series(symmetric_group(4))
-4-element Vector{PermGroup}:
- Sym(4)
- Alt(4)
- Permutation group of degree 4 and order 4
- Permutation group of degree 4 and order 1
-
-julia> derived_series(symmetric_group(5))
-2-element Vector{PermGroup}:
- Sym(5)
- Alt(5)
-
-julia> derived_series(dihedral_group(8))
-3-element Vector{SubPcGroup}:
- Sub-pc group of order 8
- Sub-pc group of order 2
- Sub-pc group of order 1
source
derived_series(L::LieAlgebra) -> Vector{LieAlgebraIdeal}

Return the derived series of L, i.e. the sequence of ideals $L^{(0)} = L$, $L^{(i + 1)} = [L^{(i)}, L^{(i)}]$.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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_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_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
chief_seriesFunction
chief_series(G::GAPGroup)

Return a vector $[ G_1, G_2, \ldots ]$ of normal subgroups of G such that $G_i > G_{i+1}$ and there is no normal subgroup N of G such that G_i > N > G_{i+1}.

Note that in general there is more than one chief series, this function returns an arbitrary one.

Examples

julia> chief_series(alternating_group(4))
-3-element Vector{PermGroup}:
- Alt(4)
- Permutation group of degree 4 and order 4
- Permutation group of degree 4 and order 1
-
-julia> chief_series(quaternion_group(8))
-4-element Vector{SubPcGroup}:
- Sub-pc group of order 8
- Sub-pc group of order 4
- Sub-pc group of order 2
- Sub-pc group of order 1
source
composition_seriesFunction
composition_series(M::ModAlgAss) -> Vector{MatElem}

Given a Fq[G]-module $M$, it returns a composition series for $M$, i.e. a sequence of submodules such that the quotient of two consecutive elements is irreducible.

source
composition_series(G::GAPGroup)

Return a vector $[ G_1, G_2, \ldots ]$ of subgroups forming a subnormal series which cannot be refined, i.e., $G_{i+1}$ is normal in $G_i$ and the quotient $G_i/G_{i+1}$ is simple.

Note that in general there is more than one composition series, this function returns an arbitrary one.

Examples

julia> composition_series(alternating_group(4))
-4-element Vector{PermGroup}:
- Permutation group of degree 4 and order 12
- Permutation group of degree 4 and order 4
- Permutation group of degree 4 and order 2
- Permutation group of degree 4 and order 1
-
-julia> composition_series(quaternion_group(8))
-4-element Vector{SubPcGroup}:
- Sub-pc group of order 8
- Sub-pc group of order 4
- Sub-pc group of order 2
- Sub-pc group of order 1
source
jennings_seriesFunction
jennings_series(G::GAPGroup)

Return for a $p$-group $G$ the vector $[ G_1, G_2, \ldots ]$ where $G_1 = G$ and beyond that $G_{i+1} := [G_i,G] G_j^p$ where $j$ is the smallest integer $> i/p$.

An exception is thrown if $G$ is not a $p$-group.

Examples

julia> jennings_series(dihedral_group(16))
-5-element Vector{SubPcGroup}:
- Sub-pc group of order 16
- Sub-pc group of order 4
- Sub-pc group of order 2
- Sub-pc group of order 2
- Sub-pc group of order 1
-
-julia> jennings_series(dihedral_group(10))
-ERROR: ArgumentError: group must be a p-group
source
p_central_seriesFunction
p_central_series(G::GAPGroup, p::IntegerUnion)

Return the vector $[ G_1, G_2, \ldots ]$ where $G_1 = G$ and beyond that $G_{i+1} := [G, G_i] G_i^p$.

An exception is thrown if $p$ is not a prime.

Examples

julia> p_central_series(alternating_group(4), 2)
-1-element Vector{PermGroup}:
- Alt(4)
-
-julia> p_central_series(alternating_group(4), 3)
-2-element Vector{PermGroup}:
- Alt(4)
- Permutation group of degree 4 and order 4
-
-julia> p_central_series(alternating_group(4), 4)
-ERROR: ArgumentError: p must be a prime
source
lower_central_seriesFunction
lower_central_series(G::GAPGroup)

Return the vector $[ G_1, G_2, \ldots ]$ where $G_1 = G$ and beyond that $G_{i+1} := [G, G_i]$. The series ends as soon as it is repeating (e.g. when the trivial subgroup is reached, which happens if and only if $G$ is nilpotent).

It is a central series of normal (and even characteristic) subgroups of $G$. The name derives from the fact that $G_i$ is contained in the $i$-th step subgroup of any central series.

See also upper_central_series and nilpotency_class.

Examples

julia> lower_central_series(dihedral_group(8))
-3-element Vector{SubPcGroup}:
- Sub-pc group of order 8
- Sub-pc group of order 2
- Sub-pc group of order 1
-
-julia> lower_central_series(dihedral_group(12))
-2-element Vector{SubPcGroup}:
- Sub-pc group of order 12
- Sub-pc group of order 3
-
-julia> lower_central_series(symmetric_group(4))
-2-element Vector{PermGroup}:
- Sym(4)
- Alt(4)
source
lower_central_series(L::LieAlgebra) -> Vector{LieAlgebraIdeal}

Return the lower central series of L, i.e. the sequence of ideals $L^{(0)} = L$, $L^{(i + 1)} = [L, L^{(i)}]$.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
upper_central_seriesFunction
upper_central_series(G::GAPGroup)

Return the vector $[ G_1, G_2, \ldots ]$ where the last entry is the trivial group, and $G_i$ is defined as the overgroup of $G_{i+1}$ satisfying $G_i / G_{i+1} = Z(G/G_{i+1})$. The series ends as soon as it is repeating (e.g. when the whole group $G$ is reached, which happens if and only if $G$ is nilpotent).

It is a central series of normal subgroups. The name derives from the fact that $G_i$ contains every $i$-th step subgroup of a central series.

See also lower_central_series and nilpotency_class.

Examples

julia> upper_central_series(dihedral_group(8))
-3-element Vector{SubPcGroup}:
- Sub-pc group of order 8
- Sub-pc group of order 2
- Sub-pc group of order 1
-
-julia> upper_central_series(dihedral_group(12))
-2-element Vector{SubPcGroup}:
- Sub-pc group of order 2
- Sub-pc group of order 1
-
-julia> upper_central_series(symmetric_group(4))
-1-element Vector{PermGroup}:
- Permutation group of degree 4 and order 1
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(H, G).

The following functions return an iterator of subgroups. Usually it is more efficient to work with (representatives of) the underlying conjugacy classes of subgroups instead.

complementsMethod
complements(G::GAPGroup, N::GAPGroup)

Return an iterator over the complements of the normal subgroup N in G. Very likely it is better to use complement_classes instead.

Examples

julia> G = symmetric_group(3);
-
-julia> describe(first(complements(G, derived_subgroup(G)[1])))
-"C2"
source
hall_subgroupsFunction
hall_subgroups(G::Group, P::AbstractVector{<:IntegerUnion})

Return an iterator over the Hall P-subgroups in G. Very likely it is better to use hall_subgroup_classes instead.

Examples

julia> g = GL(3, 2);
-
-julia> describe(first(hall_subgroups(g, [2, 3])))
-"S4"
source
low_index_subgroupsFunction
low_index_subgroups(G::Group, n::Int)

Return an iterator over the subgroups of index at most n in G. Very likely it is better to use low_index_subgroup_classes instead.

Examples

julia> G = alternating_group(6);
-
-julia> length(collect(low_index_subgroups(G, 6)))
-13
source
maximal_subgroupsFunction
maximal_subgroups(G::Group)

Return an iterator over the maximal subgroups in G. Very likely it is better to use maximal_subgroup_classes instead.

Examples

julia> println([order(H) for H in maximal_subgroups(symmetric_group(3))])
-ZZRingElem[3, 2, 2, 2]
-
-julia> println([order(H) for H in maximal_subgroups(quaternion_group(8))])
-ZZRingElem[4, 4, 4]
source
subgroupsMethod
subgroups(G::GAPGroup)

Return an iterator over all subgroups in G. Very likely it is better to use subgroup_classes instead.

Examples

julia> println([order(H) for H in subgroups(symmetric_group(3))])
-ZZRingElem[1, 2, 2, 2, 3, 6]
-
-julia> println([order(H) for H in subgroups(quaternion_group(8))])
-ZZRingElem[1, 2, 4, 4, 4, 8]
source

Conjugation action of elements and subgroups

is_conjugateMethod
is_conjugate(G::GAPGroup, H::GAPGroup, K::GAPGroup)

Return whether H and K are conjugate subgroups in G, i.e., whether there exists an element z in G such that the conjugate group H^z, which is defined as $\{ z^{-1} h z; h \in H \}$, equals K. To also return the element z, use is_conjugate_with_data(G::GAPGroup, H::GAPGroup, K::GAPGroup).

Examples

julia> G = symmetric_group(4);
-
-julia> H = sub(G, [G([2, 1, 3, 4])])[1]
-Permutation group of degree 4
-
-julia> K = sub(G, [G([1, 2, 4, 3])])[1]
-Permutation group of degree 4
-
-julia> is_conjugate(G, H, K)
-true
-
-julia> K = sub(G, [G([2, 1, 4, 3])])[1]
-Permutation group of degree 4
-
-julia> is_conjugate(G, H, K)
-false
-
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). The conjugate group H^z is defined as $\{ z^{-1} h z; h \in H \}$. If the conjugating element z is not needed, use is_conjugate(G::GAPGroup, H::GAPGroup, K::GAPGroup).

Examples

julia> G = symmetric_group(4);
-
-julia> H = sub(G, [G([2, 1, 3, 4])])[1]
-Permutation group of degree 4
-
-julia> K = sub(G, [G([1, 2, 4, 3])])[1]
-Permutation group of degree 4
-
-julia> is_conjugate_with_data(G, H, K)
-(true, (1,3)(2,4))
-
-julia> K = sub(G, [G([2, 1, 4, 3])])[1]
-Permutation group of degree 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.

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]))
-Conjugacy class of
-  (1,2) in
-  Sym(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]))
-Conjugacy class of
-  (1,2) in
-  Sym(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]))
-Conjugacy class of
-  (1,2) in
-  Sym(4)
source
conjugacy_classMethod
conjugacy_class(G::Group, H::Group) -> GroupConjClass

Return the subgroup conjugacy class cc of H in G, where H = representative(cc).

source
conjugacy_classesMethod
conjugacy_classes(G::Group)

Return a vector of all conjugacy classes of elements in G. It is guaranteed that the class of the identity is in the first position.

source
complement_classesFunction
complement_classes(G::GAPGroup, N::GAPGroup)

Return a vector 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_classes(G, derived_subgroup(G)[1])
-1-element Vector{GAPGroupConjClass{PermGroup, PermGroup}}:
- Conjugacy class of permutation group in G
-
-julia> G = dihedral_group(8)
-Pc group of order 8
-
-julia> complement_classes(G, center(G)[1])
-GAPGroupConjClass{PcGroup, SubPcGroup}[]
source
hall_subgroup_classesFunction
hall_subgroup_classes(G::Group, P::AbstractVector{<:IntegerUnion})

Return a vector that contains the 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_classes(g, [2, 3]);
-
-julia> (length(h), order(representative(h[1])))
-(1, 6)
-
-julia> g = GL(3, 2)
-GL(3,2)
-
-julia> h = hall_subgroup_classes(g, [2, 3]);
-
-julia> (length(h), order(representative(h[1])))
-(2, 24)
-
-julia> h = hall_subgroup_classes(g, [2, 7]); length(h)
-0
source
low_index_subgroup_classesFunction
low_index_subgroup_classes(G::GAPGroup, n::Int)

Return a vector of conjugacy classes of subgroups of index at most n in G.

Examples

julia> G = symmetric_group(5);
-
-julia> low_index_subgroup_classes(G, 5)
-3-element Vector{GAPGroupConjClass{PermGroup, PermGroup}}:
- Conjugacy class of Sym(5) in G
- Conjugacy class of permutation group in G
- Conjugacy class of Alt(5) in G
source
maximal_subgroup_classesMethod
maximal_subgroup_classes(G::Group)

Return a vector of all conjugacy classes of maximal subgroups of G.

Examples

julia> G = symmetric_group(3);
-
-julia> maximal_subgroup_classes(G)
-2-element Vector{GAPGroupConjClass{PermGroup, PermGroup}}:
- Conjugacy class of permutation group in G
- Conjugacy class of permutation group in G
source
subgroup_classesMethod
subgroup_classes(G::GAPGroup; order::T = ZZRingElem(-1)) where T <: IntegerUnion

Return a vector of all conjugacy classes of subgroups of G or, if order is positive, the classes of subgroups of this order.

Examples

julia> G = symmetric_group(3)
-Sym(3)
-
-julia> subgroup_classes(G)
-4-element Vector{GAPGroupConjClass{PermGroup, PermGroup}}:
- Conjugacy class of permutation group in G
- Conjugacy class of permutation group in G
- Conjugacy class of permutation group in G
- Conjugacy class of permutation group in G
-
-julia> subgroup_classes(G, order = ZZRingElem(2))
-1-element Vector{GAPGroupConjClass{PermGroup, PermGroup}}:
- Conjugacy class of permutation group in G
source

Cosets (left/right/double)

GroupCosetType
GroupCoset{T<: Group, S <: GAPGroupElem}

Type of group cosets. 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(5)
-
-julia> g = perm(G,[3,4,1,5,2])
-(1,3)(2,4,5)
-
-julia> H = symmetric_group(3)
-Sym(3)
-
-julia> right_coset(H, g)
-Right coset of Sym(3)
-  with representative (1,3)(2,4,5)
-  in Sym(5)
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(3)
-
-julia> gH = left_coset(H, g)
-Left coset of Sym(3)
-  with representative (1,3)(2,4,5)
-  in Sym(5)
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(5)
-
-julia> H = symmetric_group(4)
-Sym(4)
-
-julia> g = perm(G,[3,4,1,5,2])
-(1,3)(2,4,5)
-
-julia> gH = left_coset(H, g)
-Left coset of Sym(4)
-  with representative (1,3)(2,4,5)
-  in Sym(5)
-
-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 of Sym(4)
-  with representative (1,2)(3,4)
-  in Sym(5)
-
-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(5)
-
-julia> g = perm(G,[3,4,1,5,2])
-(1,3)(2,4,5)
-
-julia> H = symmetric_group(3)
-Sym(3)
-
-julia> gH = left_coset(H,g)
-Left coset of Sym(3)
-  with representative (1,3)(2,4,5)
-  in Sym(5)
-
-julia> acting_domain(gH)
-Sym(3)
source
representativeMethod
representative(C::GroupCoset)

If C = Hx or xH, return x.

Examples

julia> G = symmetric_group(5)
-Sym(5)
-
-julia> g = perm(G,[3,4,1,5,2])
-(1,3)(2,4,5)
-
-julia> H = symmetric_group(3)
-Sym(3)
-
-julia> gH = left_coset(H, g)
-Left coset of Sym(3)
-  with representative (1,3)(2,4,5)
-  in Sym(5)
-
-julia> representative(gH)
-(1,3)(2,4,5)
source
right_cosetsMethod
right_cosets(G::GAPGroup, H::GAPGroup; check::Bool=true)

Return the G-set that describes 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(4)
-
-julia> H = symmetric_group(3)
-Sym(3)
-
-julia> rc = right_cosets(G, H)
-Right cosets of
-  Sym(3) in
-  Sym(4)
-
-julia> collect(rc)
-4-element Vector{GroupCoset{PermGroup, PermGroupElem}}:
- Right coset of H with representative ()
- Right coset of H with representative (1,4)
- Right coset of H with representative (1,4,2)
- Right coset of H with representative (1,4,3)
source
left_cosetsMethod
left_cosets(G::GAPGroup, H::GAPGroup; check::Bool=true)

Return the G-set that describes 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(4)
-
-julia> H = symmetric_group(3)
-Sym(3)
-
-julia> left_cosets(G, H)
-Left cosets of
-  Sym(3) in
-  Sym(4)
source
right_transversalMethod
right_transversal(G::GAPGroup, H::GAPGroup; check::Bool=true)

Return a vector containing a complete set of representatives for the right cosets of H in G. This vector is not mutable, and it does not store its entries explicitly, they are created anew with each access to the transversal.

If check == false, do not check whether H is a subgroup of G.

Examples

julia> G = symmetric_group(4)
-Sym(4)
-
-julia> H = symmetric_group(3)
-Sym(3)
-
-julia> T = right_transversal(G, H)
-Right transversal of length 4 of
-  Sym(3) in
-  Sym(4)
-
-julia> collect(T)
-4-element Vector{PermGroupElem}:
- ()
- (1,4)
- (1,4,2)
- (1,4,3)
source
left_transversalMethod
left_transversal(G::GAPGroup, H::GAPGroup; check::Bool=true)

Return a vector containing a complete set of representatives for the left cosets for H in G. This vector is not mutable, and it does not store its entries explicitly, they are created anew with each access to the transversal.

If check == false, do not check whether H is a subgroup of G.

Examples

julia> G = symmetric_group(4)
-Sym(4)
-
-julia> H = symmetric_group(3)
-Sym(3)
-
-julia> T = left_transversal(G, H)
-Left transversal of length 4 of
-  Sym(3) in
-  Sym(4)
-
-julia> collect(T)
-4-element Vector{PermGroupElem}:
- ()
- (1,4)
- (1,2,4)
- (1,3,4)
source
GroupDoubleCosetType
GroupDoubleCoset{T<: Group, S <: GAPGroupElem}

Group double coset. 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(5)
-
-julia> g = perm(G,[3,4,5,1,2])
-(1,3,5,2,4)
-
-julia> H = symmetric_group(3)
-Sym(3)
-
-julia> K = symmetric_group(2)
-Sym(2)
-
-julia> double_coset(H,g,K)
-Double coset of Sym(3)
-  and Sym(2)
-  with representative (1,3,5,2,4)
-  in Sym(5)
source
double_cosetsMethod
double_cosets(G::GAPGroup, H::GAPGroup, K::GAPGroup; check::Bool=true)

Return a 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(4)
-
-julia> H = symmetric_group(3)
-Sym(3)
-
-julia> K = symmetric_group(2)
-Sym(2)
-
-julia> double_cosets(G,H,K)
-3-element Vector{GroupDoubleCoset{PermGroup, PermGroupElem}}:
- Double coset of H and K with representative ()
- Double coset of H and K with representative (1,4)
- Double coset of H and K with representative (1,4,3)
source
representativeMethod
representative(C::GroupDoubleCoset)

Return a representative x of the double coset C = HxK.

source
orderMethod
order(::Type{T} = ZZRingElem, C::Union{GroupCoset,GroupDoubleCoset})

Return the cardinality of the (double) coset C, as an instance of the type T.

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{<: GAPGroup, GroupCoset, GroupDoubleCoset}})

Return a vector containing all elements belonging to all groups and cosets in V.

source
diff --git a/previews/PR4245/Groups/tom/index.html b/previews/PR4245/Groups/tom/index.html deleted file mode 100644 index 0df84aa347aa..000000000000 --- a/previews/PR4245/Groups/tom/index.html +++ /dev/null @@ -1,68 +0,0 @@ - -Tables of Marks · Oscar.jl

Tables of Marks

The concept of a Table of Marks was introduced by W. Burnside in his book Theory of Groups of Finite Order [Bur55]. Therefore a table of marks is sometimes called a Burnside matrix. The table of marks of a finite group $G$ is a matrix whose rows and columns are labelled by the conjugacy classes of subgroups of $G$ and where for two subgroups $H$ and $K$ the $(H, K)$-entry is the number of fixed points of $K$ in the transitive action of $G$ on the cosets of $H$ in $G$. So the table of marks characterizes the set of all permutation representations of $G$. Moreover, the table of marks gives a compact description of the subgroup lattice of $G$, since from the numbers of fixed points the numbers of conjugates of a subgroup $K$ contained in a subgroup $H$ can be derived.

For small groups the table of marks of $G$ can be constructed directly by first computing the entire subgroup lattice of $G$, see table_of_marks(G::Union{GAPGroup, FinGenAbGroup}). Besides that, the Table of Marks library [MNP24] provides access to several hundred tables of marks of simple groups and maximal subgroups of simple groups. These tables of marks can be fetched via the names of these groups, which coincide with the names of the character tables of these groups in the Character Table Library, see table_of_marks(id::String).

Like the library of character tables, the library of tables of marks can be used similar to group libraries (see Group libraries) in the sense that all_table_of_marks_names returns descriptions of all those available tables of marks that have certain properties.

Construct tables of marks

GAPGroupTableOfMarksType
GAPGroupTableOfMarks <: GroupTableOfMarks

This is the type of tables of marks that can delegate tasks to an underlying table of marks object in the GAP system (field GAPTable).

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 GAPGroupTableOfMarks support get_attribute.

source
table_of_marksMethod
table_of_marks(G::GAPGroup)

Return the table of marks of the finite group G.

Examples

julia> show(stdout, MIME("text/plain"), table_of_marks(symmetric_group(3)))
-Table of marks of Sym(3)
-
-1: 6      
-2: 3 1    
-3: 2 . 2  
-4: 1 1 1 1
source
table_of_marksMethod
table_of_marks(id::String)

Return the table of marks for which id is an admissible name in GAP's library of tables of marks. If no such table is available then nothing is returned.

Examples

julia> println(table_of_marks("A5"))
-table of marks of A5
-
-julia> println(table_of_marks("J5"))
-nothing
source
showMethod
Base.show(io::IO, ::MIME"text/plain", tom::GAPGroupTableOfMarks)

Display the marks of tom and context information as a two-dimensional array.

  • First a header is shown. If tom stores a group then the header describes this group, otherwise it is equal to the identifier(tom::GAPGroupTableOfMarks) value of tom.

  • Then the matrix of marks of tom is shown in column portions that fit on the screen, together with row labels (the number i for the i-th row) on the left of each portion.

Output in $\LaTeX$ syntax can be created by calling show with second argument MIME("text/latex").

Examples

julia> tom = table_of_marks("A5");
-
-julia> show(stdout, MIME("text/plain"), tom)
-A5
-
-1: 60                
-2: 30 2              
-3: 20 . 2            
-4: 15 3 . 3          
-5: 12 . . . 2        
-6: 10 2 1 . . 1      
-7:  6 2 . . 1 . 1    
-8:  5 1 2 1 . . . 1  
-9:  1 1 1 1 1 1 1 1 1
source
all_table_of_marks_namesFunction
all_table_of_marks_names(L...; ordered_by = nothing)

Return a vector of strings that contains an admissible name of each table of marks in the library of tables of marks that satisfies the conditions in the vector L.

The supported conditions in L are the same as for all_character_table_names, and the returned vector contains the subset of those names returned by all_character_table_names with the same input for which a table of marks is available in the library.

Examples

julia> spor_names = all_table_of_marks_names(is_sporadic_simple => true);
-
-julia> println(spor_names[1:5])
-["Co3", "HS", "He", "J1", "J2"]
-
-julia> spor_names = all_table_of_marks_names(is_sporadic_simple;
-         ordered_by = order);
-
-julia> println(spor_names[1:5])
-["M11", "M12", "J1", "M22", "J2"]
-
-julia> length(all_table_of_marks_names(number_of_conjugacy_classes => 5))
-4
source
is_table_of_marks_nameFunction
is_table_of_marks_name(name::String)

Return true if table_of_marks(name) returns a table of marks, and false otherwise

Examples

julia> is_table_of_marks_name("J1")
-true
-
-julia> is_table_of_marks_name("J4")
-false
source

Attributes and operations for tables of marks

class_lengthsMethod
class_lengths(tom::GAPGroupTableOfMarks)

Return the vector of the lengths of the conjugacy classes of subgroups for tom.

Examples

julia> println(class_lengths(table_of_marks("A5")))
-ZZRingElem[1, 15, 10, 5, 6, 10, 6, 5, 1]
source
identifierMethod
identifier(tom::GAPGroupTableOfMarks)

Return a string that identifies tom if tom belongs to the library of tables of marks, and an empty string otherwise.

Examples

julia> identifier(table_of_marks("A5"))
-"A5"
-
-julia> identifier(table_of_marks(symmetric_group(3)))
-""
Note:

The identifier of a table of marks from the library is equal to the identifier of the corresponding library character table. In a few cases, this value differs from the GAP.Globals.Identifier value of the underlying GapObj of the table of marks.

source
orderMethod
order(::Type{T} = ZZRingElem, tom::GAPGroupTableOfMarks) where T <: IntegerUnion

Return the order of the group for which tom is the table of marks, as an instance of T.

Examples

julia> order(table_of_marks(symmetric_group(4)))
-24
source
orders_class_representativesMethod
orders_class_representatives(tom::GAPGroupTableOfMarks)

Return the vector of the orders of conjugacy class representatives for tom, ordered according to the rows and columns of tom.

Examples

julia> println(orders_class_representatives(table_of_marks("A5")))
-ZZRingElem[1, 2, 3, 4, 5, 6, 10, 12, 60]
source
representativeMethod
representative(tom::GAPGroupTableOfMarks, i::Int)

Return a representative from the i-th class of subgroups of tom.

An exception is thrown if tom does not store a group, or if i is larger than length(tom).

Examples

julia> representative(table_of_marks("A5"), 2)
-Permutation group of degree 5 and order 2
source

Marks vectors

The $\mathbb Z$-linear combinations of the rows of the table of marks of the group $G$ can be interpreted as elements of the integral Burnside ring of $G$: The rows of the table represent the isomorphism classes of transitive $G$-sets, the sum of two rows represents the isomorphism class of the disjoint union of the two $G$-sets, and the pointwise product of two rows represents the isomorphism class of the Cartesian product of the two $G$-sets. The coefficients of the decomposition of a linear combination of rows can be computed by coordinates(chi::GAPGroupMarksVector).

The rows of a table of marks and their $\mathbb Z$-linear combinations are implemented as marks vector objects, with parent the table of marks.

length and iteration:

The length of a marks vector is the number of columns of the table of marks. iteration is defined w.r.t. the ordering of columns.

arithmetic operations:

  • chi == psi: two marks vectors are equal if and only if they belong to the same table of marks and have the same values,
  • chi + psi and chi - psi are the pointwise sum and difference, respectively, of the two marks vectors chi, psi,
  • n * chi is the pointwise n-fold sum of chi, for an integer n,
  • chi * psi is the pointwise product of chi and psi,
  • zero(chi) is the marks vector that is zero on all classes,
  • one(chi) is the all-one marks vector, corresponding to the $G$-set that consists of one point,
  • chi^n is the n-th power of chi, for positive integers n.
coordinatesMethod
coordinates(::Type{T} = ZZRingElem, chi::GAPGroupMarksVector)
-               where T <: Union{IntegerUnion, QQFieldElem}

Return the vector $[a_1, a_2, \ldots, a_n]$ such that chi is equal to $\sum_{i=1}^n a_i t[i]$ where $t$ is parent(chi).

The result is an instance of Vector{T}. Note that the result can be shorter than ncols(parent(chi)).

Examples

julia> tom = table_of_marks(symmetric_group(4));
-
-julia> chi = tom[3] * tom[6]
-marks_vector(table of marks of Sym(4), ZZRingElem[72, 0, 4])
-
-julia> println(coordinates(Int, chi))
-[2, 0, 2]
source
restrictMethod
restrict(chi::GAPGroupMarksVector, tbl::GAPGroupCharacterTable)

Return the class function with parent tbl that is the restriction of chi. For that, parent(chi) and tbl must belong to the same group $G$.

If chi is the i-th row in the table of marks parent(chi) then the result is the permutation character of the action of $G$ on the right cosets of its subgroup representative(parent(chi), i).

Examples

julia> tom = table_of_marks("A5");  tbl = character_table(tom);
-
-julia> chi = tom[5]
-marks_vector(table of marks of A5, ZZRingElem[12, 0, 0, 0, 2])
-
-julia> println(values(restrict(chi, tbl)))
-QQAbFieldElem{AbsSimpleNumFieldElem}[12, 0, 0, 2, 2]
source

The interface between tables of marks and character tables

character_tableMethod
character_table(tom::GAPGroupTableOfMarks)

Return the character table of the group of tom. If tom belongs to the library of tables of marks then the corresponding character table from the library of character tables is returned, otherwise the character table of group(tom).

Examples

julia> g = symmetric_group(3);  tom = table_of_marks(g);
-
-julia> character_table(tom) == character_table(g)
-true
source
table_of_marksMethod
table_of_marks(tbl::GAPGroupCharacterTable)

Return the table of marks of the group of tbl. If tbl does not store a group and if the library of tables of marks contains the table of marks corresponding to tbl then this is returned, otherwise nothing.

Examples

julia> g = symmetric_group(3);  tbl = character_table(g);
-
-julia> table_of_marks(tbl) == table_of_marks(g)
-true
source
diff --git a/previews/PR4245/Hecke/.vitepress/config.mts b/previews/PR4245/Hecke/.vitepress/config.mts deleted file mode 100644 index e4c0427b9ca3..000000000000 --- a/previews/PR4245/Hecke/.vitepress/config.mts +++ /dev/null @@ -1,169 +0,0 @@ -import { defineConfig } from 'vitepress' -import { tabsMarkdownPlugin } from 'vitepress-plugin-tabs' -import mathjax3 from "markdown-it-mathjax3"; -import footnote from "markdown-it-footnote"; - -// https://vitepress.dev/reference/site-config -export default defineConfig({ - base: 'REPLACE_ME_DOCUMENTER_VITEPRESS',// TODO: replace this in makedocs! - title: 'REPLACE_ME_DOCUMENTER_VITEPRESS', - description: "A VitePress Site", - lastUpdated: true, - cleanUrls: true, - outDir: 'REPLACE_ME_DOCUMENTER_VITEPRESS', // This is required for MarkdownVitepress to work correctly... - head: [['link', { rel: 'icon', href: 'REPLACE_ME_DOCUMENTER_VITEPRESS_FAVICON' }]], - ignoreDeadLinks: true, - appearance: 'dark', - - markdown: { - math: true, - config(md) { - md.use(tabsMarkdownPlugin), - md.use(mathjax3), - md.use(footnote) - }, - theme: { - light: "github-light", - dark: "github-dark"} - }, - themeConfig: { - outline: 'deep', - logo: 'REPLACE_ME_DOCUMENTER_VITEPRESS', - search: { - provider: 'local', - options: { - detailedView: true - } - }, - nav: [ - { text: 'Home', link: '/' }, - { text: 'Getting Started', link: '/start/' }, - { text: 'Manual', link: '/manual/' }, - { text: 'Tutorials', link: '/tutorials/' }, - { text: 'How-to Guides', link: '/howto/' }, - { - text: 'Versions', items: [ - { text: 'Stable', link: 'https://thofma.com/Hecke.jl/stable/' }, - { text: 'Dev', link: 'https://thofma.com/Hecke.jl/dev/' } - ] - } - ], - sidebar: { - '/manual/': [ - { text: 'Manual', - items: [ - { text: 'Introduction', link: '/manual/'}, - { text: 'Number fields', - collapsed: true, - items: [ - { text: 'Introduction', link: 'manual/number_fields/intro'}, - { text: 'Conventions', link: 'manual/number_fields/conventions'}, - { text: 'Number field operations', link: 'manual/number_fields/fields'}, - { text: 'Elements', link: 'manual/number_fields/elements'}, - { text: 'Complex embeddings', link: 'manual/number_fields/complex_embeddings'}, - { text: 'Class field theory', link: 'manual/number_fields/class_fields.md'}, - { text: 'Internals', link: 'manual/number_fields/internal'} - ] - }, - { - text: 'Orders in number fields', - collapsed: true, - items: [ - { text: 'Introduction', link: 'manual/orders/introduction'}, - { text: 'Basics', link: 'manual/orders/orders'}, - { text: 'Elements', link: 'manual/orders/elements'}, - { text: 'Ideals', link: 'manual/orders/ideals'}, - { text: 'Fractional ideals', link: 'manual/orders/frac_ideals'}, - ] - }, - { - text: 'Quadratic and hermitian forms', - collapsed: true, - items: [ - { text: 'Introduction', link: 'manual//quad_forms/introduction'}, - { text: 'Basics', link: 'manual//quad_forms/basics'}, - { text: 'Lattices', link: 'manual/quad_forms/lattices'}, - { text: 'Integer lattices', link: 'manual/quad_forms/integer_lattices'}, - { text: 'Genera for hermitian lattices', link: 'manual/quad_forms/genusherm'}, - { text: 'Genera for integer lattices', link: 'manual/quad_forms/Zgenera'}, - { text: 'Discriminant groups', link: 'manual/quad_forms/discriminant_group'}, - ] - }, - { text: 'Algebras', - collapsed: true, - items: [ - { text: 'Introduction', link: 'manual/algebras/intro'}, - { text: 'Basics', link: 'manual/algebras/basics'}, - { text: 'Structure constant algebras', link: 'manual/algebras/structureconstant'}, - { text: 'Group algebras', link: 'manual/algebras/groupalgebras'}, - { text: 'Ideals', link: 'manual/algebras/ideals'}, - ] - }, - { - text: 'Elliptic curves', - collapsed: true, - items: [ - { text: 'Introduction', link: 'manual/elliptic_curves/intro'}, - { text: 'Basics', link: 'manual/elliptic_curves/basics'}, - { text: 'Finite fields', link: 'manual/elliptic_curves/finite_fields'}, - { text: 'Number fields', link: 'manual/elliptic_curves/number_fields'}, - ] - }, - { - text: 'Abelian groups', - collapsed: true, - items: [ - { text: 'Introduction', link: 'manual/abelian/introduction'}, - { text: 'Elements', link: 'manual/abelian/elements'}, - { text: 'Operations', link: 'manual/abelian/structural'}, - { text: 'Morphisms', link: 'manual/abelian/maps'}, - ] - }, - { - text: 'Miscellaneous', - collapsed: true, - items: [ - { text: 'Factored elements', link: 'manual/misc/FacElem'}, - { text: 'Sparse linear algebra', link: 'manual/misc/sparse'}, - { text: 'Conjugacy of integer matrices', link: 'manual/misc/conjugacy'}, - { text: 'Multisets', link: 'manual/misc/mset'}, - { text: 'Pseudo-matrices', link: 'manual/misc/pmat'}, - ] - }, - { - text: 'Developer', - collapsed: true, - items: [ - { text: 'Tests', link: 'manual/developer/test'}, - { text: 'Documentation', link: 'manual/developer/documentation'}, - ] - } - ] - } - ], - '/tutorials/': [ - { text: 'Tutorials', - items: [ - { text: 'Add me', link: '/tutorials/'}, - ] - } - ], - '/howto/': [ - { text: 'How-to Guides', - items: [ - { text: 'Reduction of polynomials', link: '/howto/reduction'}, - ] - } - ], - - }, - editLink: 'REPLACE_ME_DOCUMENTER_VITEPRESS', - socialLinks: [ - { icon: 'github', link: 'REPLACE_ME_DOCUMENTER_VITEPRESS' } - ], - footer: { - message: 'Made with DocumenterVitepress.jl
', - copyright: `© Copyright ${new Date().getUTCFullYear()}.` - } - } -}) diff --git a/previews/PR4245/Hecke/.vitepress/theme/index.ts b/previews/PR4245/Hecke/.vitepress/theme/index.ts deleted file mode 100644 index 463b5d858cea..000000000000 --- a/previews/PR4245/Hecke/.vitepress/theme/index.ts +++ /dev/null @@ -1,19 +0,0 @@ -// .vitepress/theme/index.ts -import { h } from 'vue' -import type { Theme } from 'vitepress' -import DefaultTheme from 'vitepress/theme' - -import { enhanceAppWithTabs } from 'vitepress-plugin-tabs/client' -import './style.css' - -export default { - extends: DefaultTheme, - Layout() { - return h(DefaultTheme.Layout, null, { - // https://vitepress.dev/guide/extending-default-theme#layout-slots - }) - }, - enhanceApp({ app, router, siteData }) { - enhanceAppWithTabs(app) - } -} satisfies Theme \ No newline at end of file diff --git a/previews/PR4245/Hecke/.vitepress/theme/style.css b/previews/PR4245/Hecke/.vitepress/theme/style.css deleted file mode 100644 index 816f7d5408f3..000000000000 --- a/previews/PR4245/Hecke/.vitepress/theme/style.css +++ /dev/null @@ -1,210 +0,0 @@ -@import url(https://fonts.googleapis.com/css?family=Space+Grotesk:regular,italic,700,700italic); - -/* Customize default theme styling by overriding CSS variables: -https://github.com/vuejs/vitepress/blob/main/src/client/theme-default/styles/vars.css - */ - -/* Layouts */ - - -:root { - --vp-font-family-mono: "Fira Code", Menlo, Monaco, Consolas, "Courier New", monospace; -} - -/* black */ -:root { - --vp-home-hero-name-color: #000000 !important; -} - -.dark { - --vp-home-hero-name-color: #ffffff !important; -} - -.VPHero .clip { - white-space: pre; - max-width: 500px; -} - -/* Fonts */ - - :root { - /* Typography */ - --vp-font-family-base: "Barlow", "Inter var experimental", "Inter var", - -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, - Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; - - /* Code Snippet font */ - --vp-font-family-mono: "Space Mono", Menlo, Monaco, Consolas, "Courier New", - monospace; -} - -/* Colors */ - -:root { - --julia-blue: #4063D8; - --julia-purple: #9558B2; - --julia-red: #CB3C33; - --julia-green: #389826; - - --vp-c-brand: #389826; - --vp-c-brand-light: #3dd027; - --vp-c-brand-lighter: #9499ff; - --vp-c-brand-lightest: #bcc0ff; - --vp-c-brand-dark: #535bf2; - --vp-c-brand-darker: #454ce1; - --vp-c-brand-dimm: #212425; -} - - /* Component: Button */ - -:root { - --vp-button-brand-border: var(--vp-c-brand-light); - --vp-button-brand-text: var(--vp-c-white); - --vp-button-brand-bg: var(--vp-c-brand); - --vp-button-brand-hover-border: var(--vp-c-brand-light); - --vp-button-brand-hover-text: var(--vp-c-white); - --vp-button-brand-hover-bg: var(--vp-c-brand-light); - --vp-button-brand-active-border: var(--vp-c-brand-light); - --vp-button-brand-active-text: var(--vp-c-white); - --vp-button-brand-active-bg: var(--vp-button-brand-bg); -} - -/* Component: Home */ - -:root { - --vp-home-hero-name-color: transparent; - --vp-home-hero-name-background: -webkit-linear-gradient( - 120deg, - #9558B2 30%, - #CB3C33 - ); -} - -@media (min-width: 640px) { - :root { - --vp-home-hero-image-filter: blur(56px); - } -} - -@media (min-width: 960px) { - :root { - --vp-home-hero-image-filter: blur(72px); - } -} - -/* Component: Custom Block */ - -:root.dark { - --vp-custom-block-tip-border: var(--vp-c-brand); - --vp-custom-block-tip-text: var(--vp-c-brand-lightest); - --vp-custom-block-tip-bg: var(--vp-c-brand-dimm); - - /* // Tweak the color palette for blacks and dark grays */ - --vp-c-black: hsl(220 20% 9%); - --vp-c-black-pure: hsl(220, 24%, 4%); - --vp-c-black-soft: hsl(220 16% 13%); - --vp-c-black-mute: hsl(220 14% 17%); - --vp-c-gray: hsl(220 8% 56%); - --vp-c-gray-dark-1: hsl(220 10% 39%); - --vp-c-gray-dark-2: hsl(220 12% 28%); - --vp-c-gray-dark-3: hsl(220 12% 23%); - --vp-c-gray-dark-4: hsl(220 14% 17%); - --vp-c-gray-dark-5: hsl(220 16% 13%); - - /* // Backgrounds */ - /* --vp-c-bg: hsl(240, 2%, 11%); */ - --vp-custom-block-info-bg: hsl(220 14% 17%); - /* --vp-c-gutter: hsl(220 20% 9%); - - --vp-c-bg-alt: hsl(220 20% 9%); - --vp-c-bg-soft: hsl(220 14% 17%); - --vp-c-bg-mute: hsl(220 12% 23%); - */ -} - - /* Component: Algolia */ - -.DocSearch { - --docsearch-primary-color: var(--vp-c-brand) !important; -} - -/* Component: MathJax */ - -mjx-container > svg { - display: block; - margin: auto; -} - -mjx-container { - padding: 0; -} - -mjx-container { - display: inline; - margin: auto 2px -2px; -} - -mjx-container > svg { - margin: auto; - display: inline-block; -} - -/** - * Colors links - * -------------------------------------------------------------------------- */ - - :root { - --vp-c-brand-1: #CB3C33; - --vp-c-brand-2: #CB3C33; - --vp-c-brand-3: #CB3C33; - --vp-c-sponsor: #ca2971; - --vitest-c-sponsor-hover: #c13071; -} - -.dark { - --vp-c-brand-1: #91dd33; - --vp-c-brand-2: #91dd33; - --vp-c-brand-3: #91dd33; - --vp-c-sponsor: #91dd33; - --vitest-c-sponsor-hover: #e51370; -} - -.MathJax { font-size: 0.9em !important; } - -/* https://bddxg.top/article/note/vitepress优化/一些细节上的优化.html#文档页面调整-加宽 */ - - -.VPDoc.has-aside .content-container { - max-width: 100% !important; -} -.aside { - max-width: 200px !important; - padding-left: 0 !important; -} -.VPDoc { - padding-top: 15px !important; - padding-left: 5px !important; - -} -/* This one does the right menu */ - -.VPDocOutlineItem li { - text-overflow: ellipsis; - overflow: hidden; - white-space: nowrap; - max-width: 200px; -} - -.VPNavBar .title { - text-overflow: ellipsis; - overflow: hidden; - white-space: nowrap; -} - -@media (max-width: 960px) { - .VPDoc { - padding-left: 25px !important; - } -} - -/* .mjx-container {font-size: calc(0.5 * var(--editor-font-size));} */ diff --git a/previews/PR4245/Hecke/.vitepress/theme/style.css.backu b/previews/PR4245/Hecke/.vitepress/theme/style.css.backu deleted file mode 100644 index d2ca479cecb5..000000000000 --- a/previews/PR4245/Hecke/.vitepress/theme/style.css.backu +++ /dev/null @@ -1,179 +0,0 @@ -@import url(https://fonts.googleapis.com/css?family=Space+Mono:regular,italic,700,700italic); -@import url(https://fonts.googleapis.com/css?family=Space+Grotesk:regular,italic,700,700italic); - -/* Customize default theme styling by overriding CSS variables: -https://github.com/vuejs/vitepress/blob/main/src/client/theme-default/styles/vars.css - */ - - /* Layouts */ - -/* - :root { - --vp-layout-max-width: 1440px; -} */ - -.VPHero .clip { - white-space: pre; - max-width: 500px; -} - -/* Fonts */ - - :root { - /* Typography */ - --vp-font-family-base: "Barlow", "Inter var experimental", "Inter var", - -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, - Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; - - /* Code Snippet font */ - --vp-font-family-mono: "Space Mono", Menlo, Monaco, Consolas, "Courier New", - monospace; -} - -.mono { - /* - Disable contextual alternates (kind of like ligatures but different) in monospace, - which turns `/>` to an up arrow and `|>` (the Julia pipe symbol) to an up arrow as well. - This is pretty bad for Julia folks reading even though copy+paste retains the same text. - */ - font-feature-settings: 'calt' 0; -} - -/* Colors */ - -:root { - --julia-blue: #4063D8; - --julia-purple: #9558B2; - --julia-red: #CB3C33; - --julia-green: #389826; - - --vp-c-brand: #389826; - --vp-c-brand-light: #3dd027; - --vp-c-brand-lighter: #9499ff; - --vp-c-brand-lightest: #bcc0ff; - --vp-c-brand-dark: #535bf2; - --vp-c-brand-darker: #454ce1; - --vp-c-brand-dimm: #212425; -} - - /* Component: Button */ - -:root { - --vp-button-brand-border: var(--vp-c-brand-light); - --vp-button-brand-text: var(--vp-c-white); - --vp-button-brand-bg: var(--vp-c-brand); - --vp-button-brand-hover-border: var(--vp-c-brand-light); - --vp-button-brand-hover-text: var(--vp-c-white); - --vp-button-brand-hover-bg: var(--vp-c-brand-light); - --vp-button-brand-active-border: var(--vp-c-brand-light); - --vp-button-brand-active-text: var(--vp-c-white); - --vp-button-brand-active-bg: var(--vp-button-brand-bg); -} - -/* Component: Home */ - -:root { - --vp-home-hero-name-color: transparent; - --vp-home-hero-name-background: -webkit-linear-gradient( - 120deg, - #9558B2 30%, - #CB3C33 - ); - - --vp-home-hero-image-background-image: linear-gradient( - -45deg, - #9558B2 30%, - #389826 30%, - #CB3C33 - ); - --vp-home-hero-image-filter: blur(40px); -} - -@media (min-width: 640px) { - :root { - --vp-home-hero-image-filter: blur(56px); - } -} - -@media (min-width: 960px) { - :root { - --vp-home-hero-image-filter: blur(72px); - } -} - -/* Component: Custom Block */ - -:root.dark { - --vp-custom-block-tip-border: var(--vp-c-brand); - --vp-custom-block-tip-text: var(--vp-c-brand-lightest); - --vp-custom-block-tip-bg: var(--vp-c-brand-dimm); - - /* // Tweak the color palette for blacks and dark grays */ - --vp-c-black: hsl(220 20% 9%); - --vp-c-black-pure: hsl(220, 24%, 4%); - --vp-c-black-soft: hsl(220 16% 13%); - --vp-c-black-mute: hsl(220 14% 17%); - --vp-c-gray: hsl(220 8% 56%); - --vp-c-gray-dark-1: hsl(220 10% 39%); - --vp-c-gray-dark-2: hsl(220 12% 28%); - --vp-c-gray-dark-3: hsl(220 12% 23%); - --vp-c-gray-dark-4: hsl(220 14% 17%); - --vp-c-gray-dark-5: hsl(220 16% 13%); - - /* // Backgrounds */ - /* --vp-c-bg: hsl(240, 2%, 11%); */ - --vp-custom-block-info-bg: hsl(220 14% 17%); - /* --vp-c-gutter: hsl(220 20% 9%); - - --vp-c-bg-alt: hsl(220 20% 9%); - --vp-c-bg-soft: hsl(220 14% 17%); - --vp-c-bg-mute: hsl(220 12% 23%); - */ -} - - /* Component: Algolia */ - -.DocSearch { - --docsearch-primary-color: var(--vp-c-brand) !important; -} - -/* Component: MathJax */ - -mjx-container > svg { - display: block; - margin: auto; -} - -mjx-container { - padding: 0.5rem 0; -} - -mjx-container { - display: inline-block; - margin: auto 2px -2px; -} - -mjx-container > svg { - margin: auto; - display: inline-block; -} - -/** - * Colors links - * -------------------------------------------------------------------------- */ - - :root { - --vp-c-brand-1: #CB3C33; - --vp-c-brand-2: #CB3C33; - --vp-c-brand-3: #CB3C33; - --vp-c-sponsor: #ca2971; - --vitest-c-sponsor-hover: #c13071; -} - -.dark { - --vp-c-brand-1: #91dd33; - --vp-c-brand-2: #91dd33; - --vp-c-brand-3: #91dd33; - --vp-c-sponsor: #91dd33; - --vitest-c-sponsor-hover: #e51370; -} \ No newline at end of file diff --git a/previews/PR4245/Hecke/Hecke.bib b/previews/PR4245/Hecke/Hecke.bib deleted file mode 100644 index 0d05ed6fb083..000000000000 --- a/previews/PR4245/Hecke/Hecke.bib +++ /dev/null @@ -1,86 +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}, -} - -@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}, -} - -@book{PZ97, - AUTHOR = {Pohst, M. and Zassenhaus, H.}, - TITLE = {Algorithmic algebraic number theory}, - SERIES = {Encyclopedia of Mathematics and its Applications}, - VOLUME = {30}, - 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}, - 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}, -} - -@book{CS99, - AUTHOR = {Conway, J. H. and Sloane, N. J. A.}, - TITLE = {Sphere packings, lattices and groups}, - SERIES = {Grundlehren der mathematischen Wissenschaften}, - VOLUME = {290}, - EDITION = {Third}, - 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/PR4245/Hecke/css/extra.css b/previews/PR4245/Hecke/css/extra.css deleted file mode 100644 index b445b7fb8e88..000000000000 --- a/previews/PR4245/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/PR4245/Hecke/examples/index.html b/previews/PR4245/Hecke/examples/index.html deleted file mode 100644 index da160221db8b..000000000000 --- a/previews/PR4245/Hecke/examples/index.html +++ /dev/null @@ -1,2 +0,0 @@ - -Examples and sample code · Oscar.jl
diff --git a/previews/PR4245/Hecke/howto/index.html b/previews/PR4245/Hecke/howto/index.html deleted file mode 100644 index 34511c06564d..000000000000 --- a/previews/PR4245/Hecke/howto/index.html +++ /dev/null @@ -1,2 +0,0 @@ - -How-to guides · Oscar.jl
diff --git a/previews/PR4245/Hecke/howto/reduction/index.html b/previews/PR4245/Hecke/howto/reduction/index.html deleted file mode 100644 index 5f227bfa7f66..000000000000 --- a/previews/PR4245/Hecke/howto/reduction/index.html +++ /dev/null @@ -1,10 +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> FPrime field of characteristic 29
julia> reduction_map_OKMap - from maximal order of Cyclotomic field of order 7 - with basis AbsSimpleNumFieldElem[1, z_7, z_7^2, z_7^3, z_7^4, z_7^5] - to prime field of characteristic 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
-  from cyclotomic field of order 7
-  to prime field of characteristic 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/PR4245/Hecke/index.html b/previews/PR4245/Hecke/index.html deleted file mode 100644 index a75b758f9a0b..000000000000 --- a/previews/PR4245/Hecke/index.html +++ /dev/null @@ -1,37 +0,0 @@ - -- · Oscar.jl
--- -# https://vitepress.dev/reference/default-theme-home-page -layout: home - -hero: - name: "Hecke" - tagline: Computational number theory for everyone - actions: - - theme: alt - text: Getting Started - link: /start/ - - theme: alt - text: Manual - link: /manual/ - - theme: alt - text: View on Github - link: https://github.com/thofma/Hecke.jl - -features: - - title: What is Hecke? - details: Hecke is a software package for computational algebraic number theory. It is written in julia and makes use of the computer algebra packages Nemo and AbstractAlgebra. - - title: OSCAR - details: Hecke is part of the [OSCAR](https://www.oscar-system.org/) system, which covers, in addition to number theory, also commutative algebra, algebraic geometry, group theory and polyhedral geometry. ----

Features

  • Number fields (absolute, relative, simple and non-simple)
  • Orders and ideals in number fields
  • Class and unit group computations of orders
  • Lattice enumeration
  • Sparse linear algebra
  • Class field theory
  • Abelian groups
  • Associative algebras
  • Ideals and orders in (semsimple) associative algebras
  • Locally free class groups of orders in semisimple algebras
  • Quadratic and Hermitian forms and lattices

Citing Hecke

If your research depends on computations done with Hecke, please consider giving us a formal citation:

@inproceedings{nemo,
-    author = {Fieker, Claus and Hart, William and Hofmann, Tommy and Johansson, Fredrik},
-     title = {Nemo/Hecke: Computer Algebra and Number Theory Packages for the Julia Programming Language},
- booktitle = {Proceedings of the 2017 ACM on International Symposium on Symbolic and Algebraic Computation},
-    series = {ISSAC '17},
-      year = {2017},
-     pages = {157--164},
-  numpages = {8},
-       url = {https://doi.acm.org/10.1145/3087604.3087611},
-       doi = {10.1145/3087604.3087611},
- publisher = {ACM},
-   address = {New York, NY, USA},
-}

Acknowledgement

Hecke is part of the OSCAR project and the development is supported by the Deutsche Forschungsgemeinschaft DFG within the Collaborative Research Center TRR 195.

diff --git a/previews/PR4245/Hecke/manual/abelian/elements/index.html b/previews/PR4245/Hecke/manual/abelian/elements/index.html deleted file mode 100644 index caa53eba95e7..000000000000 --- a/previews/PR4245/Hecke/manual/abelian/elements/index.html +++ /dev/null @@ -1,8 +0,0 @@ - -Elements · Oscar.jl

Elements

Elements in a finitely generated abelian group are of type FinGenAbGroupElem 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::FinGenAbGroup) -> Vector{FinGenAbGroupElem}

The sequence of generators of $G$.

source
FinGenAbGroupMethod
(A::FinGenAbGroup)(x::Vector{ZZRingElem}) -> FinGenAbGroupElem

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.

source
FinGenAbGroupMethod
(A::FinGenAbGroup)(x::ZZMatrix) -> FinGenAbGroupElem

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.

source
getindexMethod
getindex(A::FinGenAbGroup, i::Int) -> FinGenAbGroupElem

Returns the element of $A$ with components $(0,\dotsc,0,1,0,\dotsc,0)$, where the $1$ is at the $i$-th position.

source
randMethod
rand(G::FinGenAbGroup) -> FinGenAbGroupElem

Returns an element of $G$ chosen uniformly at random.

source
randMethod
rand(G::FinGenAbGroup, B::ZZRingElem) -> FinGenAbGroupElem

For a (potentially infinite) abelian group $G$, return an element chosen uniformly at random with coefficients bounded by $B$.

source
parentMethod
parent(x::FinGenAbGroupElem) -> FinGenAbGroup

Returns the parent of $x$.

source

Access

getindexMethod
getindex(x::FinGenAbGroupElem, v::AbstractVector{Int}) -> Vector{ZZRingElem}

Returns the $i$-th components of the element $x$ where $i \in v$.

Note

This function is inefficient since the elements are internally stored using ZZMatrix but this function outputs a vector.

source
getindexMethod
getindex(x::FinGenAbGroupElem, i::Int) -> ZZRingElem

Returns the $i$-th component of the element $x$.

source

Predicates

We have the standard predicates iszero, isone and is_identity to test an element for being trivial.

Invariants

orderMethod
order(A::FinGenAbGroupElem) -> ZZRingElem

Returns the order of $A$. It is assumed that the order is finite.

source

Iterator

One can iterate over the elements of a finite abelian group.


julia> G = abelian_group(ZZRingElem[1 2; 3 4])Finitely generated abelian group - with 2 generators and 2 relations and relation matrix - [1 2] - [3 4]
julia> for g = G - println(g) - endAbelian group element [0, 0] -Abelian group element [0, 1]
diff --git a/previews/PR4245/Hecke/manual/abelian/introduction/index.html b/previews/PR4245/Hecke/manual/abelian/introduction/index.html deleted file mode 100644 index 3c3e46d07137..000000000000 --- a/previews/PR4245/Hecke/manual/abelian/introduction/index.html +++ /dev/null @@ -1,6 +0,0 @@ - -Introduction · Oscar.jl

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 FinGenAbGroup with elements of type FinGenAbGroupElem. 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} = FinGenAbGroup, M::ZZMatrix) -> FinGenAbGroup

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.

source
abelian_groupMethod
abelian_group(::Type{T} = FinGenAbGroup, 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.

source
abelian_groupMethod
abelian_group(::Type{T} = FinGenAbGroup, 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.

source

Alternatively, there are shortcuts to create products of cyclic groups:

abelian_groupMethod
abelian_group(::Type{T} = FinGenAbGroup, M::AbstractVector{<:IntegerUnion}) -> FinGenAbGroup
-abelian_group(::Type{T} = FinGenAbGroup, M::IntegerUnion...) -> FinGenAbGroup

Creates the direct product of the cyclic groups $\mathbf{Z}/m_i$, where $m_i$ is the $i$th entry of M.

source

julia> G = abelian_group(2, 2, 6)(Z/2)^2 x Z/6

or even

free_abelian_groupMethod
free_abelian_group(::Type{T} = FinGenAbGroup, n::Int) -> FinGenAbGroup

Creates the free abelian group of rank n.

source
abelian_groupsMethod
abelian_groups(n::Int) -> Vector{FinGenAbGroup}

Given a positive integer $n$, return a list of all abelian groups of order $n$.

source

julia> abelian_groups(8)3-element Vector{FinGenAbGroup}: - (Z/2)^3 - Z/2 x Z/4 - Z/8

Invariants

is_snfMethod
is_snf(G::FinGenAbGroup) -> Bool

Return whether the current relation matrix of the group $G$ is in Smith normal form.

source
number_of_generatorsMethod
number_of_generators(G::FinGenAbGroup) -> Int

Return the number of generators of $G$ in the current representation.

source
nrelsMethod
number_of_relations(G::FinGenAbGroup) -> Int

Return the number of relations of $G$ in the current representation.

source
relsMethod
rels(A::FinGenAbGroup) -> ZZMatrix

Return the currently used relations of $G$ as a single matrix.

source
is_finiteMethod
isfinite(A::FinGenAbGroup) -> Bool

Return whether $A$ is finite.

source
torsion_free_rankMethod
torsion_free_rank(A::FinGenAbGroup) -> Int

Return the torsion free rank of $A$, that is, the dimension of the $\mathbf{Q}$-vectorspace $A \otimes_{\mathbf Z} \mathbf Q$.

See also rank.

source
orderMethod
order(A::FinGenAbGroup) -> ZZRingElem

Return the order of $A$. It is assumed that $A$ is finite.

source
exponentMethod
exponent(A::FinGenAbGroup) -> ZZRingElem

Return the exponent of $A$. It is assumed that $A$ is finite.

source
is_trivialMethod
is_trivial(A::FinGenAbGroup) -> Bool

Return whether $A$ is the trivial group.

source
is_torsionMethod
is_torsion(G::FinGenAbGroup) -> Bool

Return whether G is a torsion group.

source
is_cyclicMethod
is_cyclic(G::FinGenAbGroup) -> Bool

Return whether $G$ is cyclic.

source
elementary_divisorsMethod
elementary_divisors(G::FinGenAbGroup) -> Vector{ZZRingElem}

Given $G$, return the elementary divisors of $G$, that is, the unique non-negative integers $e_1,\dotsc,e_k$ with $e_i \mid e_{i + 1}$ and $e_i\neq 1$ such that $G \cong \mathbf{Z}/e_1\mathbf{Z} \times \dotsb \times \mathbf{Z}/e_k\mathbf{Z}$.

source
diff --git a/previews/PR4245/Hecke/manual/abelian/maps/index.html b/previews/PR4245/Hecke/manual/abelian/maps/index.html deleted file mode 100644 index 8d6c87ba4bcf..000000000000 --- a/previews/PR4245/Hecke/manual/abelian/maps/index.html +++ /dev/null @@ -1,6 +0,0 @@ - -Morphisms · Oscar.jl

Maps

Maps between abelian groups are mainly of type FinGenAbGroupHom. They allow normal map operations such as image, preimage, domain, codomain and can be created in a variety of situations.

Maps between abelian groups can be constructed via

  • images of the generators
  • pairs of elements
  • via composition
  • and isomorphism/ inclusion testing
hom_direct_sumMethod
hom_direct_sum(G::FinGenAbGroup, H::FinGenAbGroup, A::Matrix{ <: Map{FinGenAbGroup, FinGenAbGroup}}) -> 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.

source
is_isomorphicMethod
is_isomorphic(G::FinGenAbGroup, H::FinGenAbGroup) -> Bool

Return whether $G$ and $H$ are isomorphic.

source

julia> G = free_abelian_group(2)Z^2
julia> h = hom(G, G, [gen(G, 2), 3*gen(G, 1)])Map - from Z^2 - to Z^2
julia> h(gen(G, 1))Abelian group element [0, 1]
julia> h(gen(G, 2))Abelian group element [3, 0]

Homomorphisms also allow addition and subtraction corresponding to the pointwise operation:


julia> G = free_abelian_group(2)Z^2
julia> h = hom(G, G, [2*gen(G, 2), 3*gen(G, 1)])Map - from Z^2 - to Z^2
julia> (h+h)(gen(G, 1))Abelian group element [0, 4]
diff --git a/previews/PR4245/Hecke/manual/abelian/structural/index.html b/previews/PR4245/Hecke/manual/abelian/structural/index.html deleted file mode 100644 index d28bf1f577e9..000000000000 --- a/previews/PR4245/Hecke/manual/abelian/structural/index.html +++ /dev/null @@ -1,84 +0,0 @@ - -Structural Computations · 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::FinGenAbGroup) -> FinGenAbGroup, FinGenAbGroupHom

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$.

source
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.

source

Subgroups and Quotients

torsion_subgroupMethod
torsion_subgroup(G::FinGenAbGroup) -> FinGenAbGroup, Map

Return the torsion subgroup of G.

source
subMethod
sub(G::FinGenAbGroup, s::Vector{FinGenAbGroupElem}) -> FinGenAbGroup, FinGenAbGroupHom

Create the subgroup $H$ of $G$ generated by the elements in s together with the injection $\iota : H \to G$.

source
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$.

source
sub(s::Vector{FinGenAbGroupElem}) -> FinGenAbGroup, FinGenAbGroupHom

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$.

source
sub(F::FreeMod{T}, V::Vector{<:FreeModElem{T}}; cache_morphism::Bool=false) where {T}

Given a vector V of (homogeneous) elements of F, return a pair (I, inc) consisting of the (graded) submodule I of F generated by these elements and its inclusion map inc : I ↪ F.

When cache_morphism is set to true, then inc will be cached and available for transport and friends.

If only the submodule itself is desired, use sub_object instead.

source
sub(F::FreeMod{T}, A::MatElem{T}; cache_morphism::Bool=false) where {T}

Given a (homogeneous) matrix A interpret the rows of A as elements of the free module F and return a pair (I, inc) consisting of the (graded) submodule I of F generated by these row vectors, together with its inclusion map inc : I ↪ F.

When cache_morphism is set to true, then inc will be cached and available for transport and friends.

If only the submodule itself is desired, use sub_object instead.

source
sub(F::FreeMod{T}, O::Vector{<:SubquoModuleElem{T}}; cache_morphism::Bool=false) where T

Suppose the ambient_free_module of the parent M of the elements v_i in O is F and M is a submodule (i.e. no relations are present). Then this returns a pair (I, inc) consisting of the submodule I generated by the elements in O in F, together with its inclusion morphism inc : I ↪ F.

When cache_morphism is set to true, then inc will be cached and available for transport and friends.

If only the submodule itself is desired, use sub_object instead.

source
sub(F::FreeMod{T}, M::SubquoModule{T}; cache_morphism::Bool=false) where T

Return M as a submodule of F, together with its inclusion morphism inc : M ↪ F.

When cache_morphism is set to true, then inc will be cached and available for transport and friends.

The ambient_free_module of M needs to be F and M has to have no relations.

If only the submodule itself is desired, use sub_object instead.

source
sub(M::SubquoModule{T}, V::Vector{<:SubquoModuleElem{T}}; cache_morphism::Bool=false) where T

Given a vector V of (homogeneous) elements of M, return the (graded) submodule I of M generated by these elements together with its inclusion map `inc : I ↪ M.

When cache_morphism is set to true, then inc will be cached and available for transport and friends.

If only the submodule itself is desired, use sub_object instead.

source
sub(M::ModuleFP{T}, V::Vector{<:ModuleFPElem{T}}; cache_morphism::Bool=false) where T

Given a vector V of (homogeneous) elements of M, return the (graded) submodule I of M generated by these elements together with its inclusion map `inc : I ↪ M.

When cache_morphism is set to true, then inc will be cached and available for transport and friends.

If only the submodule itself is desired, use sub_object instead.

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 R
source
subMethod
sub(G::FinGenAbGroup, M::ZZMatrix) -> FinGenAbGroup, FinGenAbGroupHom

Create the subgroup $H$ of $G$ generated by the elements corresponding to the rows of $M$ together with the injection $\iota : H \to G$.

source
subMethod
sub(G::FinGenAbGroup, n::ZZRingElem) -> FinGenAbGroup, FinGenAbGroupHom

Create the subgroup $n \cdot G$ of $G$ together with the injection $\iota : n\cdot G \to G$.

source
subMethod
sub(G::FinGenAbGroup, n::Integer) -> FinGenAbGroup, Map

Create the subgroup $n \cdot G$ of $G$ together with the injection $\iota : n \cdot G \to G$.

source
sylow_subgroupMethod
sylow_subgroup(G::FinGenAbGroup, p::IntegerUnion) -> FinGenAbGroup, FinGenAbGroupHom

Return the Sylow $p-$subgroup of the finitely generated abelian group G, for a prime p. This is the subgroup of p-power order in G whose index in G is coprime to p.

Examples

julia> A = abelian_group(ZZRingElem[2, 6, 30])
-Z/2 x Z/6 x Z/30
-
-julia> H, j = sylow_subgroup(A, 2);
-
-julia> H
-(Z/2)^3
-
-julia> divexact(order(A), order(H))
-45
source
has_quotientMethod
has_quotient(G::FinGenAbGroup, invariant::Vector{Int}) -> Bool

Given an abelian group $G$, return true if it has a quotient with given elementary divisors and false otherwise.

source
has_complementMethod
has_complement(f::FinGenAbGroupHom) -> Bool, FinGenAbGroupHom
-has_complement(U::FinGenAbGroup, G::FinGenAbGroup) -> Bool, FinGenAbGroupHom

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

source
is_pureMethod
is_pure(U::FinGenAbGroup, G::FinGenAbGroup) -> 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
source
is_neatMethod
is_neat(U::FinGenAbGroup, G::FinGenAbGroup) -> 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
source
saturateMethod
saturate(U::FinGenAbGroup, G::FinGenAbGroup) -> FinGenAbGroup

For a subgroup U of G find a minimal overgroup that is pure, and thus has a complement.

See also: is_pure, has_complement

source

A sophisticated algorithm for the enumeration of all (or selected) subgroups of a finite abelian group is available.

psubgroupsMethod
psubgroups(g::FinGenAbGroup, 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.

source

julia> G = abelian_group([6, 12])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{Vector{ZZRingElem}} with 8 elements: - 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::FinGenAbGroup;
-          subtype = :all ,
-          quotype = :all,
-          index = -1,
-          order = -1)

Return an iterator for the subgroups of $G$ of the specific form.

source
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]))) = (Z/2, FinGenAbGroupElem[[0, 6]])
-(U[1], map(U[2], gens(U[1]))) = (Z/2, FinGenAbGroupElem[[3, 6]])
-(U[1], map(U[2], gens(U[1]))) = (Z/2, FinGenAbGroupElem[[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]))) = (Finitely generated abelian group with 3 generators and 3 relations, FinGenAbGroupElem[[3, 3], [0, 4], [2, 0]]) -(U[1], map(U[2], gens(U[1]))) = (Finitely generated abelian group with 3 generators and 3 relations, FinGenAbGroupElem[[0, 3], [0, 4], [2, 0]]) -(U[1], map(U[2], gens(U[1]))) = (Finitely generated abelian group with 4 generators and 4 relations, FinGenAbGroupElem[[3, 6], [0, 6], [0, 4], [2, 0]])
quoMethod
quo(G::FinGenAbGroup, s::Vector{FinGenAbGroupElem}) -> FinGenAbGroup, GrpAbfinGemMap

Create the quotient $H$ of $G$ by the subgroup generated by the elements in $s$, together with the projection $p : G \to H$.

source
quoMethod
quo(G::FinGenAbGroup, M::ZZMatrix) -> FinGenAbGroup, FinGenAbGroupHom

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$.

source
quoMethod
quo(G::FinGenAbGroup, n::Integer}) -> FinGenAbGroup, Map
-quo(G::FinGenAbGroup, n::ZZRingElem}) -> FinGenAbGroup, Map

Returns the quotient $H = G/nG$ together with the projection $p : G \to H$.

source
quoMethod
quo(G::FinGenAbGroup, n::Integer}) -> FinGenAbGroup, Map
-quo(G::FinGenAbGroup, n::ZZRingElem}) -> FinGenAbGroup, Map

Returns the quotient $H = G/nG$ together with the projection $p : G \to H$.

source
quoMethod
quo(G::FinGenAbGroup, U::FinGenAbGroup) -> FinGenAbGroup, Map

Create the quotient $H$ of $G$ by $U$, together with the projection $p : G \to H$.

source

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::FinGenAbGroupHom, mH::FinGenAbGroupHom) -> FinGenAbGroup, Map

Given two injective maps of abelian groups with the same codomain $G$, return the intersection of the images as a subgroup of $G$.

source

Direct Products

direct_productMethod
direct_product(G::FinGenAbGroup...) -> FinGenAbGroup, Vector{FinGenAbGroupHom}

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.

source
canonical_injectionMethod
canonical_injection(G::FinGenAbGroup, i::Int) -> FinGenAbGroupHom

Given a group $G$ that was created as a direct product, return the injection from the $i$th component.

source
canonical_projectionMethod
canonical_projection(G::FinGenAbGroup, i::Int) -> FinGenAbGroupHom

Given a group $G$ that was created as a direct product, return the projection onto the $i$th component.

source
flatMethod
flat(G::FinGenAbGroup) -> FinGenAbGroupHom

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$).

source

Tensor Producs

tensor_productMethod
tensor_product(G::FinGenAbGroup...; task::Symbol = :map) -> FinGenAbGroup, 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.

source
hom_tensorMethod
hom_tensor(G::FinGenAbGroup, H::FinGenAbGroup, A::Vector{ <: Map{FinGenAbGroup, FinGenAbGroup}}) -> 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.

source

Hom-Group

homMethod
hom(G::FinGenAbGroup, H::FinGenAbGroup; task::Symbol = :map) -> FinGenAbGroup, 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.

source
diff --git a/previews/PR4245/Hecke/manual/algebras/basics/index.html b/previews/PR4245/Hecke/manual/algebras/basics/index.html deleted file mode 100644 index d4e561849a50..000000000000 --- a/previews/PR4245/Hecke/manual/algebras/basics/index.html +++ /dev/null @@ -1,32 +0,0 @@ - -Basics · Oscar.jl

Basics

Creation of algebras

See the corresponding sections on structure constant algebras.

zero_algebraMethod
zero_algebra([T, ] K::Field) -> AbstractAssociativeAlgebra

Return the zero ring as an algebra over the field $K$.

The optional first argument determines the type of the algebra, and can be StructureConstantAlgebra (default) or MatrixAlgebra.

Examples

julia> A = zero_algebra(QQ)
-Structure constant algebra of dimension 0 over QQ
source

Basic properties

base_ringMethod
base_ring(A::AbstractAssociativeAlgebra) -> Field

Given a $K$-algebra $A$, return $K$.

source
basisMethod
basis(A::AbstractAssociativeAlgebra) -> Vector

Given a $K$-algebra $A$ return the $K$-basis of $A$. See also coordinates to get the the coordinates of an element with respect to the bases.

source

Predicates

is_zeroMethod
is_zero(A::AbstractAssociativeAlgebra) -> Bool

Return whether $A$ is the zero algebra.

source
is_commutativeMethod
is_commutative(A::AbstractAssociativeAlgebra) -> Bool

Return whether $A$ is commutative.

Examples

julia> A = matrix_algebra(QQ, 2);
-
-julia> is_commutative(A)
-false
source
is_centralMethod
is_central(A::AbstractAssociativeAlgebra)

Return whether the $K$-algebra $A$ is central, that is, whether $K$ is the center of $A$.

source

Generators

gensMethod
gens(A::AbstractAssociativeAlgebra; thorough_search::Bool = false) -> Vector

Given a $K$-algebra $A$, return a subset of basis(A), which generates $A$ as an algebra over $K$.

If thorough_search is true, the number of returned generators is possibly smaller. This will in general increase the runtime. It is not guaranteed that the number of generators is minimal in any case.

The gens_with_data function computes additional data for expressing a basis as words in the generators.

Examples

julia> A = matrix_algebra(QQ, 3);
-
-julia> gens(A; thorough_search = true)
-5-element Vector{MatAlgebraElem{QQFieldElem, QQMatrix}}:
- [1 0 0; 0 0 0; 0 0 0]
- [0 0 0; 1 0 0; 0 0 0]
- [0 0 0; 0 0 0; 1 0 0]
- [0 1 0; 0 0 0; 0 0 0]
- [0 0 1; 0 0 0; 0 0 0]
source
gens_with_dataMethod
gens_with_data(A::AbstractAssociativeAlgebra; thorough_search::Bool = false)
-                                                   -> Vector, Vector, Vector

Given a $K$-algebra $A$, return a triple $(G, B, w)$ consisting of

  • a subset $G$ of basis(A), which generates $A$ as an algebra over $K$,
  • a (new) basis $B$ and a vector w::Vector{Tuple{Int, Int}}, such that B[i] = prod(G[j]^k for (j, k) in w[i].

If thorough_search is true, the number of returned generators is possibly smaller. This will in general increase the runtime. It is not guaranteed that the number of generators is minimal in any case.

Examples

julia> A = matrix_algebra(QQ, 3);
-
-julia> G, B, w = gens_with_data(A; thorough_search = true);
-
-julia> B[1] == prod(G[i]^j for (i, j) in w[1])
-true
source

Center

centerMethod
center(A::AbstractAssociativeAlgebra)
-                                   -> StructureConstantAlgebra, Map

Returns the center $C$ of $A$ and the inclusion $C \to A$. Note that $C$ itself is an algebra.

Examples

julia> A = matrix_algebra(QQ, 2);
-
-julia> C, CtoA = center(A);
-
-julia> C
-Structure constant algebra of dimension 1 over QQ
source
dimension_of_centerMethod
dimension_of_center(A::AbstractAssociativeAlgebra) -> Int

Given a $K$-algebra, return the $K$-dimension of the center of $A$.

Examples

julia> A = matrix_algebra(QQ, 2);
-
-julia> dimension_of_center(A)
-1
source
dimension_over_centerMethod
dimension_over_center(A::AbstractAssociativeAlgebra) -> Int

Given a simple $K$-algebra with center $C$, return the $C$-dimension $A$.

Examples

julia> A = matrix_algebra(QQ, 2);
-
-julia> dimension_of_center(A)
-1
source
diff --git a/previews/PR4245/Hecke/manual/algebras/groupalgebras/index.html b/previews/PR4245/Hecke/manual/algebras/groupalgebras/index.html deleted file mode 100644 index 7713cb82e36e..000000000000 --- a/previews/PR4245/Hecke/manual/algebras/groupalgebras/index.html +++ /dev/null @@ -1,15 +0,0 @@ - -Group algebras · Oscar.jl

Group algebras

As is natural, the basis of a group algebra $K[G]$ correspond to the elements of $G$ with respect to some arbitrary ordering.

Creation

group_algebraMethod
group_algebra(K::Ring, G::Group; cached::Bool = true) -> GroupAlgebra

Return the group algebra of the group $G$ over the ring $R$. Shorthand syntax for this construction is R[G].

Examples

julia> QG = group_algebra(QQ, small_group(8, 5))
-Group algebra
-  of generic group of order 8 with multiplication table
-  over rational field
source

Elements

Given a group algebra A and an element of a group g, the corresponding group algebra element can be constructed using the syntax A(g).

julia> G = abelian_group([2, 2]); a = G([0, 1]);
-
-julia> QG = group_algebra(QQ, G);
-
-julia> x = QG(a)
-[0, 0, 1, 0]

Vice versa, one can obtain the coordinate of a group algebra element x with respect to a group element a using the syntax x[a].

julia> x[a]
-1

It is also possible to create elements by specifying for each group element the corresponding coordinate either by a list of pairs or a dictionary:

julia> QG(a => 2, zero(G) => 1) == 2 * QG(a) + 1 * QG(zero(G))
-true
-
-julia> QG(Dict(a => 2, zero(G) => 1)) == 2 * QG(a) + 1 * QG(zero(G))
-true
diff --git a/previews/PR4245/Hecke/manual/algebras/intro/index.html b/previews/PR4245/Hecke/manual/algebras/intro/index.html deleted file mode 100644 index bc07dd372cfc..000000000000 --- a/previews/PR4245/Hecke/manual/algebras/intro/index.html +++ /dev/null @@ -1,2 +0,0 @@ - -Introduction · Oscar.jl

Introduction

Note

The functions described in this section are experimental. While the overall functionality provided will stay the same, names of specific functions or conventions for the return values might change in future versions.

This section describes the functionality for finite-dimensional associative algebras (or just algebras for short). Since different applications have different requirements, the following types of algebras are implemented:

  • structure constant algebras,
  • matrix algebras,
  • group algebras,
  • quaternion algebras.

These share a common interface encompassing a wide range of functions, which is indicated by the use of the type AbstractAssociativeAlgebra in the signature.

diff --git a/previews/PR4245/Hecke/manual/algebras/structureconstant/index.html b/previews/PR4245/Hecke/manual/algebras/structureconstant/index.html deleted file mode 100644 index c96337cf34d4..000000000000 --- a/previews/PR4245/Hecke/manual/algebras/structureconstant/index.html +++ /dev/null @@ -1,17 +0,0 @@ - -Structure constant algebras · Oscar.jl

Structure constant algebras

Creation

structure_constant_algebraMethod
structure_constant_algebra(R::Ring, sctable::Array{_, 3}; one::Vector = nothing,
-                                                          check::Bool = true)

Given an array with dimensions $(d, d, d)$ and a ring $R$, return the $d$-dimensional structure constant algebra over $R$. The basis e of $R$ satisfies e[i] * e[j] = sum(sctable[i,j,k] * e[k] for k in 1:d).

Unless check = false, this includes (time consuming) associativity and distributivity checks. If one is given, record the element with the supplied coordinate vector as the one element of the algebra.

Examples

julia> associative_algebra(QQ, reshape([1, 0, 0, 2, 0, 1, 1, 0], (2, 2, 2)))
-Structure constant algebra of dimension 2 over QQ
source
structure_constant_algebraMethod
structure_constant_algebra(K::SimpleNumField) -> StructureConstantAlgebra, Map

Given a number field $L/K$, return $L$ as a $K$-algebra $A$ together with a $K$-linear map $A \to L$.

Examples

julia> L, = quadratic_field(2);
-
-julia> structure_constant_algebra(L)
-(Structure constant algebra of dimension 2 over QQ, Map: structure constant algebra -> real quadratic field)
source

Structure constant table

structure_constant_tableMethod
structure_constant_table(A::StructureConstantAlgebra; copy::Bool = true) -> Array{_, 3}

Given an algebra $A$, return the structure constant table of $A$. See structure_constant_algebra for the defining property.

Examples

julia> A = associative_algebra(QQ, reshape([1, 0, 0, 2, 0, 1, 1, 0], (2, 2, 2)));
-
-julia> structure_constant_table(A)
-2×2×2 Array{QQFieldElem, 3}:
-[:, :, 1] =
- 1  0
- 0  2
-
-[:, :, 2] =
- 0  1
- 1  0
source
diff --git a/previews/PR4245/Hecke/manual/developer/documentation/index.html b/previews/PR4245/Hecke/manual/developer/documentation/index.html deleted file mode 100644 index b496d649e972..000000000000 --- a/previews/PR4245/Hecke/manual/developer/documentation/index.html +++ /dev/null @@ -1,4 +0,0 @@ - -Documentation · Oscar.jl

Documentation

The files for the documentation are located in the docs/src/manual/ directory.

Adding files to the documentation

To add files to the documentation edit directly the file docs/src/.vitepress/config.mts.

Building the documentation

  1. Run julia and execute (with Hecke developed in your current environment)
julia> using Hecke
-
-julia> Hecke.build_doc() # or Hecke.build_doc(;doctest = false) to speed things up
  1. In the terminal, navigate to docs/ and run
Hecke/docs> npm run docs:build

(This step takes place outside of julia.)

Note

To speed up the development process, step 1 can be repeated within the same julia session.

diff --git a/previews/PR4245/Hecke/manual/developer/test/index.html b/previews/PR4245/Hecke/manual/developer/test/index.html deleted file mode 100644 index a857253541c2..000000000000 --- a/previews/PR4245/Hecke/manual/developer/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/PR4245/Hecke/manual/elliptic_curves/basics/index.html b/previews/PR4245/Hecke/manual/elliptic_curves/basics/index.html deleted file mode 100644 index a0ef1ca19889..000000000000 --- a/previews/PR4245/Hecke/manual/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) -> EllipticCurve

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
source
elliptic_curve_from_j_invariantFunction
elliptic_curve_from_j_invariant(j::FieldElem) -> EllipticCurve

Return an elliptic curve with the given $j$-invariant.

Examples

julia> K = GF(3)
-Prime field of characteristic 3
-
-julia> elliptic_curve_from_j_invariant(K(2))
-Elliptic curve with equation
-y^2 + x*y = x^3 + 1
source

Basic properties

base_fieldMethod
base_field(E::EllipticCurve) -> Field

Return the base field over which E is defined.

source
base_field(C::HypellCrv) -> Field

Return the base field over which C is defined.

source
base_changeMethod
base_change(K::Field, E::EllipticCurve) -> EllipticCurve

Return the base change of the elliptic curve $E$ over $K$ if coercion is possible.

source
base_changeMethod
base_change(f, E::EllipticCurve) -> EllipticCurve

Return the base change of the elliptic curve $E$ using the map $f$.

source
coefficientsMethod
coefficients(E::EllipticCurve{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.

source
a_invariantsMethod
a_invariants(E::EllipticCurve{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$.

source
b_invariantsMethod
b_invariants(E::EllipticCurve{T}) -> Tuple{T, T, T, T}

Return the b-invariants of $E$ as a tuple $(b_2, b_4, b_6, b_8)$.

source
c_invariantsMethod
c_invariants(E::EllipticCurve{T}) -> Tuple{T, T}

Return the c-invariants of $E as a tuple $(c_4, c_6)$.

source
discriminantMethod
discriminant(E::EllipticCurve) -> FieldElem

Return the discriminant of $E$.

source
discriminant(C::HypellCrv{T}) -> T

Compute the discriminant of $C$.

source
discriminant(O::AlgssRelOrd)

Returns the discriminant of $O$.

source
j_invariantMethod
j_invariant(E::EllipticCurve) -> FieldElem

Compute the j-invariant of $E$.

source
equationMethod
equation([R::MPolyRing,] E::EllipticCurve) -> MPolyRingElem

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
source
hyperelliptic_polynomialsMethod
hyperelliptic_polynomials([R::PolyRing,] E::EllipticCurve) -> PolyRingElem, PolyRingElem

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)
source

Points

    (E::EllipticCurve)(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::EllipticCurve) -> EllipticCurvePoint

Return the point at infinity with project coordinates $[0 : 1 : 0]$.

source
parentMethod
parent(P::EllipticCurvePoint) -> EllipticCurve

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
source
is_on_curveMethod
is_on_curve(E::EllipticCurve, 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
source
+Method
+(P::EllipticCurvePoint, Q::EllipticCurvePoint) -> EllipticCurvePoint

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
source
division_pointsMethod
division_points(P::EllipticCurvePoint, m::Int) -> EllipticCurvePoint

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{EllipticCurvePoint{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
source
diff --git a/previews/PR4245/Hecke/manual/elliptic_curves/finite_fields/index.html b/previews/PR4245/Hecke/manual/elliptic_curves/finite_fields/index.html deleted file mode 100644 index 9d36dc32d72d..000000000000 --- a/previews/PR4245/Hecke/manual/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::EllipticCurve{<: 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} = BigInt, G::Group) where T

Return the order of $G$ as an instance of T. If $G$ is of infinite order, an InfiniteOrderError exception will be thrown. Use is_finite(G) to avoid this kind of exception. If the order does not fit into type T, an InexactError exception will be thrown.

source
order(::Type{T} = BigInt, g::GroupElem) where T

Return the order of $g$ as an instance of T. If $g$ is of infinite order, an InfiniteOrderError exception will be thrown. Use is_finite_order(G) to avoid this kind of exception. If the order does not fit into type T, an InexactError exception will be thrown.

source
order(E::EllipticCurve{<: 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
source
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(::Type{T}, W::WeylGroup) where {T} -> T

Returns the order of W.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
orderMethod
order(::Type{T} = BigInt, G::Group) where T

Return the order of $G$ as an instance of T. If $G$ is of infinite order, an InfiniteOrderError exception will be thrown. Use is_finite(G) to avoid this kind of exception. If the order does not fit into type T, an InexactError exception will be thrown.

source
order(::Type{T} = BigInt, g::GroupElem) where T

Return the order of $g$ as an instance of T. If $g$ is of infinite order, an InfiniteOrderError exception will be thrown. Use is_finite_order(G) to avoid this kind of exception. If the order does not fit into type T, an InexactError exception will be thrown.

source
order(P::EllipticCurvePoint, [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
source
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(::Type{T}, W::WeylGroup) where {T} -> T

Returns the order of W.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source

Frobenius

trace_of_frobeniusMethod
trace_of_frobenius(E::EllipticCurve{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
source
trace_of_frobeniusMethod
trace_of_frobenius(E::EllipticCurve{<: 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
source

Group structure of rational points

gensMethod
gens(E::EllipticCurve{<:FinFieldElem}) -> Vector{EllipticCurvePoint}

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{EllipticCurvePoint{FqFieldElem}}:
- Point  (16*o + 42 : 88*o + 97 : 1)  of Elliptic curve with equation
-y^2 = x^3 + x + 2
- Point  (88*o + 23 : 94*o + 22 : 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{EllipticCurvePoint{FqFieldElem}}:
- Point  (85 : 58 : 1)  of Elliptic curve with equation
-y^2 = x^3 + x + 2
source
abelian_groupMethod
abelian_group(E::EllipticCurve{<:FinFieldElem}) -> FinGenAbGroup, 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
-Z/2 x Z/5200
source

Discrete logarithm

disc_logMethod
disc_log(P::EllipticCurvePoint, Q::EllipticCurvePoint, [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
source
diff --git a/previews/PR4245/Hecke/manual/elliptic_curves/intro/index.html b/previews/PR4245/Hecke/manual/elliptic_curves/intro/index.html deleted file mode 100644 index 4a03b12f9c71..000000000000 --- a/previews/PR4245/Hecke/manual/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/PR4245/Hecke/manual/elliptic_curves/number_fields/index.html b/previews/PR4245/Hecke/manual/elliptic_curves/number_fields/index.html deleted file mode 100644 index cb1afdd3c68f..000000000000 --- a/previews/PR4245/Hecke/manual/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/PR4245/Hecke/manual/index.html b/previews/PR4245/Hecke/manual/index.html deleted file mode 100644 index 5be0f9763e04..000000000000 --- a/previews/PR4245/Hecke/manual/index.html +++ /dev/null @@ -1,2 +0,0 @@ - -Manual · Oscar.jl
diff --git a/previews/PR4245/Hecke/manual/misc/FacElem/index.html b/previews/PR4245/Hecke/manual/misc/FacElem/index.html deleted file mode 100644 index 55f5bbf42665..000000000000 --- a/previews/PR4245/Hecke/manual/misc/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{AbsSimpleNumFieldElem, AbsSimpleNumField}, factored algerbaic numbers
  • FacElem{AbsNumFieldOrderIdeal, AbsNumFieldOrderIdealSet}, 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.

source
FacElemMethod
FacElem{B}(R, base::Vector{B}, exp::Vector{ZZRingElem}) -> FacElem{B}

Returns the element $\prod b_i^{e_i}$, un-expanded.

source
FacElem{B}(base::Vector{B}, exp::Vector{ZZRingElem}) -> FacElem{B}

Returns the element $\prod b_i^{e_i}$, un-expanded.

source
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.

source
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.

source
idealMethod
 ideal(O::AbsSimpleNumFieldOrder, a::FacElem{AbsSimpleNumFieldElem, AbsSimpleNumField)

The factored fractional ideal $a*O$.

source

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.

source
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.

source
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.

source
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.

source

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{AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}, AbsNumFieldOrderIdealSet{AbsSimpleNumField, AbsSimpleNumFieldElem}}) -> FacElem
-simplify(x::FacElem{AbsSimpleNumFieldOrderFractionalIdeal, AbsNumFieldOrderFractionalIdealSet{AbsSimpleNumField, AbsSimpleNumFieldElem}}) -> 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!.

source
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.

source

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.

source
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.

source
factor_coprimeMethod
factor_coprime(x::FacElem{AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}, AbsNumFieldOrderIdealSet{AbsSimpleNumField, AbsSimpleNumFieldElem}}) -> Dict{AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}, Int}

Computed a partial factorisation of $x$, ie. writes $x$ as a product of pariwise coprime integral ideals.

source
factor_coprimeMethod
factor_coprime(Q::FacElem{AbsSimpleNumFieldOrderFractionalIdeal, AbsNumFieldOrderFractionalIdealSet{AbsSimpleNumField, AbsSimpleNumFieldElem}}) -> Dict{AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}, 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.

source
factor_coprimeMethod
factor_coprime(I::AbsNumFieldOrderIdealSet{AbsSimpleNumField, AbsSimpleNumFieldElem}, a::FacElem{AbsSimpleNumFieldElem, AbsSimpleNumField}) -> Dict{AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}, ZZRingElem}

Factors the rincipal ideal generated by $a$ into coprimes by computing a coprime basis from the principal ideals in the factorisation of $a$.

source
factorMethod
 factor(Q::FacElem{AbsSimpleNumFieldOrderFractionalIdeal, AbsNumFieldOrderFractionalIdealSet{AbsSimpleNumField, AbsSimpleNumFieldElem}}) -> Dict{AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}, Int}

The factorisation of $Q$, by refining a coprime factorisation.

source
factorMethod
factor(I::AbsNumFieldOrderIdealSet{AbsSimpleNumField, AbsSimpleNumFieldElem}, a::FacElem{AbsSimpleNumFieldElem, AbsSimpleNumField}) -> Dict{AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}, ZZRingElem}

Factors the principal ideal generated by $a$ by refining a coprime factorisation.

source

For factorised algebraic numbers a unique simplification is not possible, however, this allows still do obtain partial results:

compact_presentationFunction
compact_presentation(a::FacElem{AbsSimpleNumFieldElem, AbsSimpleNumField}, 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}.

source
valuationMethod
valuation(a::FacElem{AbsSimpleNumFieldElem, AbsSimpleNumField}, P::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}) -> ZZRingElem

The valuation of $a$ at $P$.

source
valuationMethod
valuation(A::FacElem{AbsSimpleNumFieldOrderFractionalIdeal, AbsNumFieldOrderFractionalIdealSet{AbsSimpleNumField, AbsSimpleNumFieldElem}}, p::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem})
-valuation(A::FacElem{AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}, AbsNumFieldOrderIdealSet{AbsSimpleNumField, AbsSimpleNumFieldElem}}, p::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem})

The valuation of $A$ at $P$.

source
evaluate_modMethod
evaluate_mod(a::FacElem{AbsSimpleNumFieldElem, AbsSimpleNumField}, B::AbsSimpleNumFieldOrderFractionalIdeal) -> AbsSimpleNumFieldElem

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".

source
reduce_idealMethod
reduce_ideal(A::FacElem{AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}}) -> AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}, FacElem{AbsSimpleNumFieldElem}

Computes $B$ and $\alpha$ in factored form, such that $\alpha B = A$.

source
modular_projMethod
modular_proj(a::FacElem{AbsSimpleNumFieldElem, AbsSimpleNumField}, 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.

source

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$.

source
min_expMethod
min_exp(a::FacElem)

Finds the smallest exponent in the factored element $a$.

source
maxabs_expMethod
maxabs_exp(a::FacElem)

Finds the largest exponent by absolute value in the factored element $a$.

source
diff --git a/previews/PR4245/Hecke/manual/misc/conjugacy/index.html b/previews/PR4245/Hecke/manual/misc/conjugacy/index.html deleted file mode 100644 index f9139ecc2a59..000000000000 --- a/previews/PR4245/Hecke/manual/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
source
diff --git a/previews/PR4245/Hecke/manual/misc/mset/index.html b/previews/PR4245/Hecke/manual/misc/mset/index.html deleted file mode 100644 index 5cc26a008e35..000000000000 --- a/previews/PR4245/Hecke/manual/misc/mset/index.html +++ /dev/null @@ -1,157 +0,0 @@ - -Multi-sets and sub-set iterators · Oscar.jl

Multi-sets and sub-set iterators

Multi-sets

Type and constructors

Objects of type MSet consists of a dictionary whose keys are the elements in the set, and the values are their respective multiplicity.

MSetType
MSet{T} <: AbstractSet{T}

Type for a multi-set, i.e. a set where elements are not unique, they (can) have a multiplicity. MSets can be created from any finite iterator.

Examples

julia> MSet([1,1,2,3,4,4,5])
-MSet{Int64} with 7 elements:
-  5
-  4 : 2
-  2
-  3
-  1 : 2

4 : 2 means the element 4 has multiplicity 2, i.e. was included twice.

source

We can create multi-sets from any finite iterator, dictionary or pair of lists with the appropriate conditions.

multisetFunction
multiset(iter) -> MSet{eltype(iter)}
-multiset(d::Dict{T, Int}) -> MSet{T}
-multiset{l::Vector{T}, m::Vector{Int}} -> MSet{T}

Given either:

  • a finite iterator iter;
  • a dictionary d whose values are positive integers;
  • a list l and a list of positive integers m of same length as l;

return the asscciated multi-set M.

Examples

julia> str = "A nice sentence"
-"A nice sentence"
-
-julia> multiset(str)
-MSet{Char} with 15 elements:
-  'n' : 3
-  'A'
-  'c' : 2
-  'i'
-  'e' : 4
-  's'
-  't'
-  ' ' : 2
-
-julia> multiset(Int[x^3%8 for x = 1:50])
-MSet{Int64} with 50 elements:
-  0 : 25
-  5 : 6
-  7 : 6
-  3 : 6
-  1 : 7
-
-julia> d = Dict("a" => 4, "b" => 1, "c" =>9)
-Dict{String, Int64} with 3 entries:
-  "c" => 9
-  "b" => 1
-  "a" => 4
-
-julia> multiset(d)
-MSet{String} with 14 elements:
-  "c" : 9
-  "b"
-  "a" : 4
-
-julia> multiset(["a", "b", "c"], [4, 1, 9])
-MSet{String} with 14 elements:
-  "c" : 9
-  "b"
-  "a" : 4
source
multiset(T::Type) -> MSet{T}

Create an empty multi-set M with elements of type T.

Examples

julia> multiset(QQFieldElem)
-MSet{QQFieldElem}()
-
-julia> multiset()
-MSet{Any}()
source

Functions

One can iterate over an MSet as on a regular Set. Here is moreover a list of functions defined for collections of objects which are currently available for MSet:

  • ==
  • all
  • any
  • copy
  • delete!
  • eltype
  • filter
  • filter!
  • in
  • intersect
  • intersect!
  • isempty
  • issubset
  • length
  • pop!
  • push!
  • setdiff
  • setdiff!
  • similar
  • unique
  • union
  • union!
  • ...

Note that pop! and delete! for MSet are available but have a different behaviour. For an element x in an multi-set M <: MSet, then pop!(M, x) will remove one instance of x in M - in particular multiplicity(M, x) will drop by $1$. Much stronger, delete!(M, x) will remove all instances of x in M and so multiplicity(M, x) will be $0$.

While unique will return the keys of the underlying dictionary, one can access the values (i.e. the multiplicities of the elements in the multi-set) via the following functions:

multiplicitiesMethod
multiplicities(s::MSet{T}) -> ValueIterator{Dict{T, Int}}

Return an iterator for the multiplicities of all the elements in s.

Examples

julia> m = multiset([1,1,2,3,4,4,5])
-MSet{Int64} with 7 elements:
-  5
-  4 : 2
-  2
-  3
-  1 : 2
-
-julia> mult_m = multiplicities(m)
-ValueIterator for a Dict{Int64, Int64} with 5 entries. Values:
-  1
-  2
-  1
-  1
-  2
-
-julia> collect(mult_m)
-5-element Vector{Int64}:
- 1
- 2
- 1
- 1
- 2
source
multiplicityMethod
multiplicity(s::MSet{T}, x::T) -> Int

Return the multiplicity of the element x in the multi-set s. If x is not in s, return 0.

Examples

julia> m = multiset([1,1,2,3,4,4,5])
-MSet{Int64} with 7 elements:
-  5
-  4 : 2
-  2
-  3
-  1 : 2
-
-julia> multiplicity(m, 2)
-1
-
-julia> multiplicity(m, 6)
-0
source

Finally, the sum and difference for MSet are also available. Difference is given by the complements of sets and the sum is given by disjoint union of sets.

+Method
(+)(s::MSet, itrs...) -> MSet

Return the multi-sets associated to the disjoint union of s and the collections of objects in itrs.

Examples

julia> m = multiset("A nice sentence")
-MSet{Char} with 15 elements:
-  'n' : 3
-  'A'
-  'c' : 2
-  'i'
-  'e' : 4
-  's'
-  't'
-  ' ' : 2
-
-julia> n = multiset("A very nice sentence")
-MSet{Char} with 20 elements:
-  'n' : 3
-  'e' : 5
-  'A'
-  'y'
-  'i'
-  'r'
-  's'
-  't'
-  ' ' : 3
-  'c' : 2
-  'v'
-
-julia> m + n
-MSet{Char} with 35 elements:
-  'n' : 6
-  'e' : 9
-  'A' : 2
-  's' : 2
-  'i' : 2
-  't' : 2
-  'y'
-  'r'
-  ' ' : 5
-  'c' : 4
-  'v'
source
-Method
(-)(s::MSet, itrs...) -> MSet

Return the multi-set associated to the complement in s of the collections in itrs.

Alias for setdiff(s, itrs...).

Examples

julia> m = multiset("A very nice sentence")
-MSet{Char} with 20 elements:
-  'n' : 3
-  'e' : 5
-  'A'
-  'y'
-  'i'
-  'r'
-  's'
-  't'
-  ' ' : 3
-  'c' : 2
-  'v'
-
-julia> n = multiset("A nice sentence")
-MSet{Char} with 15 elements:
-  'n' : 3
-  'A'
-  'c' : 2
-  'i'
-  'e' : 4
-  's'
-  't'
-  ' ' : 2
-
-julia> n-m
-MSet{Char}()
-
-julia> m-n
-MSet{Char} with 5 elements:
-  'e'
-  'y'
-  'r'
-  ' '
-  'v'
source

Sub-set iterators

Sub-multi-sets

subsetsMethod
subsets(s::MSet) -> MSubSetIt{T}

Return an iterator on all sub-multi-sets of s.

source
subsets(s::Set) -> SubSetItr{T}

Return an iterator for all sub-sets of s.

source
subsets(s::Set, k::Int) -> SubSetSizeItr{T}

Return an iterator on all sub-sets of size k of s.

source
subsets(v::Vector{T}, k::Int) where T

Return a vector of all ordered k-element sub-vectors of v.

source

Sub-sets

subsetsMethod
subsets(s::MSet) -> MSubSetIt{T}

Return an iterator on all sub-multi-sets of s.

source
subsets(s::Set) -> SubSetItr{T}

Return an iterator for all sub-sets of s.

source
subsets(s::Set, k::Int) -> SubSetSizeItr{T}

Return an iterator on all sub-sets of size k of s.

source
subsets(v::Vector{T}, k::Int) where T

Return a vector of all ordered k-element sub-vectors of v.

source

Sub-sets of a given size

subsetsMethod
subsets(s::Set, k::Int) -> SubSetSizeItr{T}

Return an iterator on all sub-sets of size k of s.

source
diff --git a/previews/PR4245/Hecke/manual/misc/pmat/index.html b/previews/PR4245/Hecke/manual/misc/pmat/index.html deleted file mode 100644 index e4c76bc434f3..000000000000 --- a/previews/PR4245/Hecke/manual/misc/pmat/index.html +++ /dev/null @@ -1,19 +0,0 @@ - -Pseudo-matrices · Oscar.jl

Pseudo-matrices

This chapter deals with pseudo-matrices. We follow the common terminology and conventions introduced in [Coh00], 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{AbsSimpleNumFieldElem}, c::Vector{AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}}) -> PMat{AbsSimpleNumFieldElem, AbsSimpleNumFieldOrderFractionalIdeal}

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$.

source
pseudo_matrixMethod
pseudo_matrix(m::Generic.Mat{AbsSimpleNumFieldOrderElem}, c::Vector{AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}}) -> PMat{AbsSimpleNumFieldElem, AbsSimpleNumFieldOrderFractionalIdeal}

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$.

source
pseudo_matrixMethod
pseudo_matrix(m::Generic.Mat{AbsSimpleNumFieldOrderElem}) -> PMat{AbsSimpleNumFieldElem, AbsSimpleNumFieldOrderFractionalIdeal}

Returns the free (row) pseudo matrix representing the $Z_k$-module $\sum Z_k m_i$ where $m_i$ are the rows of $M$.

source

(Those functions are also available as pseudo_matrix)

Operations

matrixMethod
matrix(M::PMat)

Returns the matrix part of the PMat.

source
base_ringMethod
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$.

source
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 generated by
-  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::AbsAffineScheme)

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
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

source
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

source

Examples

diff --git a/previews/PR4245/Hecke/manual/misc/sparse/index.html b/previews/PR4245/Hecke/manual/misc/sparse/index.html deleted file mode 100644 index 941d414b784f..000000000000 --- a/previews/PR4245/Hecke/manual/misc/sparse/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$.

source
sparse_rowMethod
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$.

source
sparse_rowMethod
sparse_row(R::NCRing, 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$.

source

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$.

source
add_scaled_rowMethod
add_scaled_row(A::SRow{T}, B::SRow{T}, c::T) -> SRow{T}

Returns the row $c A + B$.

source
add_scaled_rowMethod
add_scaled_row(A::SRow{T}, B::SRow{T}, c::T) -> SRow{T}

Returns the row $c A + B$.

source
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)$.

source
lengthMethod
length(A::SRow)

Returns the number of nonzero entries of $A$.

source

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$.

source

Maximum, minimum and 2-norm

maximumMethod
maximum(A::SRow{T}) -> T

Returns the largest entry of $A$.

source
maximumMethod
maximum(A::SRow{T}) -> T

Returns the largest entry of $A$.

source
minimumMethod
minimum(A::SRow{T}) -> T

Returns the smallest entry of $A$.

source
  minimum(A::RelNumFieldOrderIdeal) -> AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}
-  minimum(A::RelNumFieldOrderIdeal) -> RelNumFieldOrderIdeal

Returns the ideal $A \cap O$ where $O$ is the maximal order of the coefficient ideals of $A$.

source
minimumMethod
minimum(A::SRow{T}) -> T

Returns the smallest entry of $A$.

source
norm2Method
norm2(A::SRow{T} -> T

Returns $A \cdot A^t$.

source

Functionality for integral sparse rows

liftMethod
lift(A::SRow{zzModRingElem}) -> SRow{ZZRingElem}

Return the sparse row obtained by lifting all entries in $A$.

source
mod!Method
mod!(A::SRow{ZZRingElem}, n::ZZRingElem) -> SRow{ZZRingElem}

Inplace reduction of all entries of $A$ modulo $n$ to the positive residue system.

source
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.

source
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.

source
maximumMethod
maximum(abs, A::SRow{ZZRingElem}) -> ZZRingElem

Returns the largest, in absolute value, entry of $A$.

source

Conversion to/from julia and AbstractAlgebra types

VectorMethod
Vector(a::SMat{T}, n::Int) -> Vector{T}

The first n entries of a, as a julia vector.

source
sparse_rowMethod
sparse_row(A::MatElem)

Convert A to a sparse row. nrows(A) == 1 must hold.

source
dense_rowMethod
dense_row(r::SRow, n::Int)

Convert r[1:n] to a dense row, that is an AbstractAlgebra matrix.

source

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$.

source
sparse_matrixMethod
sparse_matrix(R::Ring, n::Int, m::Int) -> SMat

Return a sparse $n$ times $m$ zero matrix over $R$.

source

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$.

source
sparse_matrixMethod
sparse_matrix(R::Ring, A::Matrix{T}) -> SMat

Constructs the sparse matrix over $R$ corresponding to $A$.

source
sparse_matrixMethod
sparse_matrix(R::Ring, A::Matrix{T}) -> SMat

Constructs the sparse matrix over $R$ corresponding to $A$.

source

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.

source

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$.

source
vcatMethod
vcat(A::SMat, B::SMat) -> SMat

Vertically joins $A$ and $B$.

source
hcat!Method
hcat!(A::SMat, B::SMat) -> SMat

Horizontally concatenates $A$ and $B$, inplace, changing $A$.

source
hcatMethod
hcat(A::SMat, B::SMat) -> SMat

Horizontally concatenates $A$ and $B$.

source

(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$.

source
zero_matrixMethod
zero_matrix(::Type{SMat}, R::Ring, n::Int)

Return a sparse $n$ times $n$ zero matrix over $R$.

source
zero_matrixMethod
zero_matrix(::Type{SMat}, R::Ring, n::Int, m::Int)

Return a sparse $n$ times $m$ zero matrix over $R$.

source
block_diagonal_matrixMethod
block_diagonal_matrix(xs::Vector{SMat})

Return the block diagonal matrix with the matrices in xs on the diagonal. Requires all blocks to have the same base ring.

source

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$.

source

Transpose:

transposeMethod
transpose(A::SMat) -> SMat

Returns the transpose of $A$.

source

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.

source
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.

source
nnzMethod
nnz(A::SMat) -> Int

Return the number of non-zero entries of $A$.

source
isoneMethod
isone(A::SMat)

Tests if $A$ is an identity matrix.

source
iszeroMethod
iszero(A::SMat)

Tests if $A$ is a zero matrix.

source
maximumMethod
maximum(A::SMat{T}) -> T

Finds the largest entry of $A$.

source
minimumMethod
minimum(A::SMat{T}) -> T

Finds the smallest entry of $A$.

source
maximumMethod
maximum(abs, A::SMat{ZZRingElem}) -> ZZRingElem

Finds the largest, in absolute value, entry of $A$.

source
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$.

source
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.

source
hadamard_bound2Method
hadamard_bound2(A::SMat{T}) -> T

The square of the product of the norms of the rows of $A$.

source
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.

source
reduce_fullMethod
reduce_full(A::SMat{ZZRingElem}, g::SRow{ZZRingElem},
-                      with_transform = 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 with_transform is set to Val(true), then additionally an array of transformations is returned.

source
hnf!Method
hnf!(A::SMat{ZZRingElem})

Inplace transform of $A$ into upper right Hermite normal form.

source
hnfMethod
hnf(A::SMat{ZZRingElem}) -> SMat{ZZRingElem}

Return the upper right Hermite normal form of $A$.

source
snfMethod
snf(A::SMat{ZZRingElem})

The Smith normal form (snf) of $A$.

source
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$.

source
is_diagonalMethod
is_diagonal(A::SMat) -> Bool

True iff only the i-th entry in the i-th row is non-zero.

source
detMethod
det(A::SMat{ZZRingElem})

The determinant of $A$ using a modular algorithm. Uses the dense (zzModMatrix) determinant on $A$ for various primes $p$.

source
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$.

source
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.

source
saturateMethod
saturate(A::SMat{ZZRingElem}) -> SMat{ZZRingElem}

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 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.

source
hnf_kannan_bachemMethod
hnf_kannan_bachem(A::SMat{ZZRingElem}) -> SMat{ZZRingElem}

Compute the Hermite normal form of $A$ using the Kannan-Bachem algorithm.

source
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.

source

Manipulation/ Access

getindexMethod
getindex(A::SMat, i::Int, j::Int)

Given a sparse matrix $A = (a_{ij})_{i, j}$, return the entry $a_{ij}$.

source
getindexMethod
getindex(A::SMat, i::Int) -> SRow

Given a sparse matrix $A$ and an index $i$, return the $i$-th row of $A$.

source
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$.

source
swap_rows!Method
swap_rows!(A::SMat{T}, i::Int, j::Int)

Swap the $i$-th and $j$-th row of $A$ inplace.

source
swap_cols!Method
swap_cols!(A::SMat, i::Int, j::Int)

Swap the $i$-th and $j$-th column of $A$ inplace.

source
scale_row!Method
scale_row!(A::SMat{T}, i::Int, c::T)

Multiply the $i$-th row of $A$ by $c$ inplace.

source
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$.

source
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$.

source
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$.

source
diagonalMethod
diagonal(A::SMat) -> ZZRingElem[]

The diagonal elements of $A$ in an array.

source
mod_sym!Method
mod_sym!(A::SMat{ZZRingElem}, n::ZZRingElem)

Inplace reduction of all entries of $A$ modulo $n$ to the symmetric residue system.

source
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.

source
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.

source
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$.

source
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$.

source
rand_rowMethod
rand_row(A::SMat) -> SRow

Return a random row of the sparse matrix $A$.

source

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$.

source
change_base_ringMethod
change_base_ring(R::Ring, A::SMat)

Create a new sparse matrix by coercing all elements into the ring $R$.

source

Arithmetic

Matrices support the usual operations as well

  • +, -, ==
  • div, divexact by scalars
  • multiplication by scalars

Various products:

*Method
*(A::SMat{T}, b::AbstractVector{T}) -> Vector{T}

Return the product $A \cdot b$ as a dense vector.

source
*Method
*(A::SMat{T}, b::AbstractMatrix{T}) -> Matrix{T}

Return the product $A \cdot b$ as a dense array.

source
*Method
*(A::SMat{T}, b::MatElem{T}) -> MatElem

Return the product $A \cdot b$ as a dense matrix.

source
*Method
*(A::SRow, B::SMat) -> SRow

Return the product $A\cdot B$ as a sparse row.

source
dotMethod
dot(x::SRow{T}, A::SMat{T}, y::SRow{T}) where T -> T

Return the generalized dot product dot(x, A*y).

source
dotMethod
dot(x::MatrixElem{T}, A::SMat{T}, y::MatrixElem{T}) where T -> T

Return the generalized dot product dot(x, A*y).

source
dotMethod
dot(x::AbstractVector{T}, A::SMat{T}, y::AbstractVector{T}) where T -> T

Return the generalized dot product dot(x, A*y).

source

Other:

sparseMethod
sparse(A::SMat) -> SparseMatrixCSC

The same matrix, but as a sparse matrix of julia type SparseMatrixCSC.

source
ZZMatrixMethod
ZZMatrix(A::SMat{ZZRingElem})

The same matrix $A$, but as an ZZMatrix.

source
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$.

source
MatrixMethod
Matrix(A::SMat{T}) -> Matrix{T}

The same matrix, but as a julia matrix.

source
ArrayMethod
Array(A::SMat{T}) -> Matrix{T}

The same matrix, but as a two-dimensional julia array.

source
diff --git a/previews/PR4245/Hecke/manual/number_fields/class_fields/index.html b/previews/PR4245/Hecke/manual/number_fields/class_fields/index.html deleted file mode 100644 index 02e9b272ec2c..000000000000 --- a/previews/PR4245/Hecke/manual/number_fields/class_fields/index.html +++ /dev/null @@ -1,15 +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::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}, inf_plc::Vector{InfPlc}; n_quo::Int, lp::Dict{AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}, Int}) -> FinGenAbGroup, 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.

source
class_groupMethod
class_group(K::AbsSimpleNumField) -> FinGenAbGroup, 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.

source
norm_groupMethod
norm_group(f::Nemo.PolyRingElem, mR::Hecke.MapRayClassGrp, is_abelian::Bool = true; of_closure::Bool = false) -> Hecke.FinGenGrpAb, Hecke.FinGenGrpAbMap
-
-norm_group(f::Array{PolyRingElem{AbsSimpleNumFieldElem}}, 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.

source
norm_groupMethod
norm_group(K::RelSimpleNumField{AbsSimpleNumFieldElem}, mR::Hecke.MapRayClassGrp) -> Hecke.FinGenGrpAb, Hecke.FinGenGrpAbMap
-
-norm_group(K::RelNonSimpleNumField{AbsSimpleNumFieldElem}, mR::Hecke.MapRayClassGrp) -> Hecke.FinGenGrpAb, Hecke.FinGenGrpAbMap

Computes the subgroup of the Ray Class Group $R$ given by the norm of the extension.

source

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}.

source
ray_class_fieldMethod
ray_class_field(m::Union{MapClassGrp, MapRayClassGrp}, quomap::FinGenAbGroupHom) -> 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$.

source
ray_class_fieldMethod
ray_class_field(I::AbsNumFieldOrderIdeal; n_quo = 0) -> ClassField

The ray class field modulo $I$. If n_quo is given, then the largest subfield of exponent $n$ is computed.

source
ray_class_fieldMethod
ray_class_field(I::AbsNumFieldOrderIdeal, 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.

source
hilbert_class_fieldMethod
hilbert_class_field(k::AbsSimpleNumField) -> ClassField

The Hilbert class field of $k$ as a formal (ray-) class field.

source
ring_class_fieldMethod
ring_class_field(O::AbsNumFieldOrder) -> 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.

source

Example


julia> Qx, x = polynomial_ring(FlintQQ, "x");
julia> K, a = number_field(x^2 - 10, "a");
julia> c, mc = class_group(K)(Z/2, ClassGroup map of -Set of ideals of Maximal order of Number field of degree 2 over QQ -with basis AbsSimpleNumFieldElem[1, a])
julia> A = ray_class_field(mc)Class field defined mod (<1, 1>, InfPlc{AbsSimpleNumField, AbsSimpleNumFieldEmbedding}[]) of 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) -> RelNonSimpleNumField{AbsSimpleNumFieldElem}

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.

source

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{AbsSimpleNumField, AbsSimpleNumFieldEmbedding}[]) of 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::RelSimpleNumField{AbsSimpleNumFieldElem}) -> ClassField
-ray_class_field(K::AbsSimpleNumField) -> ClassField

For a (relative) abelian extension, compute an abstract representation as a class field.

source
genus_fieldMethod
genus_field(A::ClassField, k::AbsSimpleNumField) -> ClassField

The maximal extension contained in $A$ that is the compositum of $K$ with an abelian extension of $k$.

source
maximal_abelian_subfieldMethod
maximal_abelian_subfield(A::ClassField, k::AbsSimpleNumField) -> ClassField

The maximal abelian extension of $k$ contained in $A$. $k$ must be a subfield of the base field of $A$.

source
maximal_abelian_subfieldMethod
maximal_abelian_subfield(K::RelSimpleNumField{AbsSimpleNumFieldElem}; 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).

source

Invariants

degreeMethod
degree(A::ClassField)

The degree of $A$ over its base field, i.e. the size of the defining ideal group.

source
base_ringMethod
base_ring(A::ClassField)

The maximal order of the field that $A$ is defined over.

source
base_fieldMethod
base_field(A::ClassField)

The number field that $A$ is defined over.

source
discriminantMethod
discriminant(C::ClassField) -> AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}

Using the conductor-discriminant formula, compute the (relative) discriminant of $C$. This does not use the defining equations.

source
conductorMethod
conductor(C::ClassField) -> AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}, Vector{InfPlc}

Return the conductor of the abelian extension corresponding to $C$.

source
defining_modulusMethod
defining_modulus(CF::ClassField)

The modulus, i.e. an ideal of the set of real places, used to create the class field.

source
is_cyclicMethod
is_cyclic(C::ClassField)

Tests if the (relative) automorphism group of $C$ is cyclic (by checking the defining ideal group).

source
is_conductorMethod
is_conductor(C::Hecke.ClassField, m::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}, inf_plc::Vector{InfPlc}=InfPlc[]; check) -> AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}, 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.

source
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$.

source
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$.

source

Operations

*Method
*(A::ClassField, B::ClassField) -> ClassField

The compositum of $a$ and $b$ as a (formal) class field.

source
compositumMethod
compositum(a::ClassField, b::ClassField) -> ClassField

The compositum of $a$ and $b$ as a (formal) class field.

source
==Method
==(a::ClassField, b::ClassField)

Tests if $a$ and $b$ are equal.

source
intersectMethod
intersect(a::ClassField, b::ClassField) -> ClassField

The intersection of $a$ and $b$ as a class field.

source
prime_decomposition_typeMethod
prime_decomposition_type(C::ClassField, p::AbsNumFieldOrderIdeal) -> (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$.

source
is_subfieldMethod
is_subfield(a::ClassField, b::ClassField) -> Bool

Determines if $a$ is a subfield of $b$.

source
is_local_normMethod
is_local_norm(r::ClassField, a::AbsNumFieldOrderElem) -> Bool

Tests if $a$ is a local norm at all finite places in the extension implicitly given by $r$.

source
is_local_normMethod
is_local_norm(r::ClassField, a::AbsNumFieldOrderElem, p::AbsNumFieldOrderIdeal) -> Bool

Tests if $a$ is a local norm at $p$ in the extension implicitly given by $r$. Currently the conductor cannot have infinite places.

source
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$.

source
subfieldsMethod
subfields(C::ClassField; degree::Int, is_normal, type) -> 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.

If the optional keyword is_normal is given, then only those that are normal over the field fixed by the automorphisms is returned. For normal base fields, this amounts to extensions that are normal over Q.

If the optional keyword is_normal is set to a list of automorphisms, then only those wil be considered.

type can be set to the desired relative Galois group, given as a vector of integers descibing the structure.

Note

This will not find all subfields over $\mathbf{Q}$, but only the ones sharing the same base field.

source
diff --git a/previews/PR4245/Hecke/manual/number_fields/complex_embeddings/index.html b/previews/PR4245/Hecke/manual/number_fields/complex_embeddings/index.html deleted file mode 100644 index ed5feef61eff..000000000000 --- a/previews/PR4245/Hecke/manual/number_fields/complex_embeddings/index.html +++ /dev/null @@ -1,131 +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{AbsSimpleNumFieldEmbedding}:
- Complex embedding corresponding to 0.00 + 1.73 * i of imaginary quadratic field
- Complex embedding corresponding to 0.00 - 1.73 * i of imaginary quadratic field
-
-julia> complex_embeddings(K, conjugates = false)
-1-element Vector{AbsSimpleNumFieldEmbedding}:
- Complex embedding corresponding to 0.00 + 1.73 * i of imaginary quadratic field
source
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{AbsSimpleNumFieldEmbedding}:
- Complex embedding corresponding to -1.73 of real quadratic field
- Complex embedding corresponding to 1.73 of real quadratic field
source

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
source
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
source
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
source

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
source

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) -> AcbFieldElem
  • Note that the return type will be a complex ball of type AcbFieldElem. 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
source

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)
-Complex embedding corresponding to 1.41
-  of real quadratic field defined by x^2 - 2
-
-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 real quadratic field defined by x^2 - 3
source
restrictMethod
restrict(f::NumFieldEmb, g::NumFieldHom)

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 = cyclotomic_field(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
source

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::NumFieldHom)

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 = cyclotomic_field(5, "a");
-
-julia> k, ktoK = Hecke.subfield(K, [a + inv(a)]);
-
-julia> e = complex_embeddings(k)[1];
-
-julia> extend(e, ktoK)
-2-element Vector{AbsSimpleNumFieldEmbedding}:
- 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
source

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
source
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{AbsSimpleNumFieldEmbedding, 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
source
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
source
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
source
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.

source
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
source
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
source

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{AbsNonSimpleNumFieldEmbedding}:
- 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 imaginary quadratic field defined by x^2 + 1
-
-julia> restrict(emb[3], i)
-Complex embedding corresponding to -1.00 * i
-  of imaginary quadratic field defined by x^2 + 1
diff --git a/previews/PR4245/Hecke/manual/number_fields/conventions/index.html b/previews/PR4245/Hecke/manual/number_fields/conventions/index.html deleted file mode 100644 index 0ae3003ea7f2..000000000000 --- a/previews/PR4245/Hecke/manual/number_fields/conventions/index.html +++ /dev/null @@ -1,11 +0,0 @@ - -Conventions · Oscar.jl

Conventions

By an absolute number field we mean finite extensions of $\mathbf Q$, which is of type AbsSimpleNumField and whose elements are of type AbsSimpleNumFieldElem. 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/PR4245/Hecke/manual/number_fields/elements/index.html b/previews/PR4245/Hecke/manual/number_fields/elements/index.html deleted file mode 100644 index b3d00105df96..000000000000 --- a/previews/PR4245/Hecke/manual/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$.

source
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$.

source

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$.

source
hilbert_symbolMethod
hilbert_symbol(a::NumFieldElem, b::NumFieldElem, p::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}) -> Int

Returns the local Hilbert symbol $(a,b)_p$.

source
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$.

source
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$.

source
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.

source
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).

source
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).

source
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.

source
valuationMethod
valuation(a::NumFieldElem, p::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}) -> ZZRingElem

Computes the $\mathfrak p$-adic valuation of $a$, that is, the largest $i$ such that $a$ is contained in $\mathfrak p^i$.

source
torsion_unit_orderMethod
torsion_unit_order(x::AbsSimpleNumFieldElem, 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.

source
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$.

source
absolute_trMethod
absolute_tr(a::NumFieldElem) -> QQFieldElem

Given a number field element $a$, returns the absolute trace of $a$.

source
algebraic_splitMethod
algebraic_split(a::AbsSimpleNumFieldElem) -> AbsSimpleNumFieldElem, AbsSimpleNumFieldElem

Writes the input as a quotient of two "small" algebraic integers.

source

Conjugates

conjugatesMethod
conjugates(x::AbsSimpleNumFieldElem, C::AcbField) -> Vector{AcbFieldElem}

Compute the conjugates of $x$ as elements of type AcbFieldElem. 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.

source
conjugatesMethod
conjugates(x::AbsSimpleNumFieldElem, abs_tol::Int) -> Vector{AcbFieldElem}

Compute the conjugates of $x$ as elements of type AcbFieldElem. 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.

source
conjugates_logMethod
conjugates_arb_log(x::AbsSimpleNumFieldElem, abs_tol::Int) -> Vector{ArbFieldElem}

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 ArbFieldElem with radius less then 2^-abs_tol.

source
conjugates_realMethod
conjugates_arb_real(x::AbsSimpleNumFieldElem, abs_tol::Int) -> Vector{ArbFieldElem}

Compute the real conjugates of $x$ as elements of type ArbFieldElem.

Every entry $y$ of the array returned satisfies radius(y) < 2^-abs_tol.

source
conjugates_complexMethod
conjugates_complex(x::AbsSimpleNumFieldElem, abs_tol::Int) -> Vector{AcbFieldElem}

Compute the complex conjugates of $x$ as elements of type AcbFieldElem. 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.

source
conjugates_arb_log_normaliseMethod
conjugates_arb_log_normalise(x::AbsSimpleNumFieldElem, p::Int = 10)
-conjugates_arb_log_normalise(x::FacElem{AbsSimpleNumFieldElem, AbsSimpleNumField}, 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.

source
minkowski_mapMethod
minkowski_map(a::AbsSimpleNumFieldElem, abs_tol::Int) -> Vector{ArbFieldElem}

Returns the image of $a$ under the Minkowski embedding. Every entry of the array returned is of type ArbFieldElem with radius less then 2^(-abs_tol).

source

Predicates

is_integralMethod
is_integral(a::NumFieldElem) -> Bool

Returns whether $a$ is integral, that is, whether the minimal polynomial of $a$ has integral coefficients.

source
is_torsion_unitMethod
is_torsion_unit(x::AbsSimpleNumFieldElem, 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.

source
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.

source
is_norm_divisibleMethod
is_norm_divisible(a::AbsSimpleNumFieldElem, n::ZZRingElem) -> Bool

Checks if the norm of $a$ is divisible by $n$, assuming that the norm of $a$ is an integer.

source
is_normMethod
is_norm(K::AbsSimpleNumField, a::ZZRingElem; extra::Vector{ZZRingElem}) -> Bool, AbsSimpleNumFieldElem

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.

source

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$.

source
absolute_normMethod
absolute_norm(a::NumFieldElem) -> QQFieldElem

Given a number field element $a$, returns the absolute norm of $a$.

source
minpolyMethod
minpoly(a::NumFieldElem) -> PolyRingElem

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$.

source
absolute_minpolyMethod
absolute_minpoly(a::NumFieldElem) -> PolyRingElem

Given a number field element $a$ of a number field $K$, this function returns the minimal polynomial of $a$ over the rationals $\mathbf{Q}$.

source
charpolyMethod
charpoly(a::NumFieldElem) -> PolyRingElem

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$.

source
absolute_charpolyMethod
absolute_charpoly(a::NumFieldElem) -> PolyRingElem

Given a number field element $a$ of a number field $K$, this function returns the characteristic polynomial of $a$ over the rationals $\mathbf{Q}$.

source
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$.

source
diff --git a/previews/PR4245/Hecke/manual/number_fields/fields/index.html b/previews/PR4245/Hecke/manual/number_fields/fields/index.html deleted file mode 100644 index ed738a573a2b..000000000000 --- a/previews/PR4245/Hecke/manual/number_fields/fields/index.html +++ /dev/null @@ -1,64 +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::VarName;
-            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");
source
number_fieldMethod
number_field(f::Vector{PolyRingElem{<:NumFieldElem}}, s::VarName="_\$", 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, AbsNonSimpleNumFieldElem[a1, a2])
source
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::Bool = 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.

source
quadratic_fieldMethod
quadratic_field(d::IntegerUnion) -> AbsSimpleNumField, AbsSimpleNumFieldElem

Returns the field with defining polynomial $x^2 - d$.

Examples

julia> quadratic_field(5)
-(Real quadratic field defined by x^2 - 5, sqrt(5))
source
wildanger_fieldMethod
wildanger_field(n::Int, B::ZZRingElem) -> AbsSimpleNumField, AbsSimpleNumFieldElem

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)
source
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)
source
rationals_as_number_fieldMethod
rationals_as_number_field() -> AbsSimpleNumField, AbsSimpleNumFieldElem

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)
source

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{AbsSimpleNumFieldElem}:
- 1
- a
source
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{AbsNonSimpleNumFieldElem}:
- 1
- a1
- a2
- a1*a2
source
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.

source
defining_polynomialMethod
defining_polynomial(L::SimpleNumField) -> PolyRingElem

Given a simple number field $L/K$, constructed as $L = K[x]/(f)$, this function returns $f$.

source
defining_polynomialsMethod
defining_polynomials(L::NonSimpleNumField) -> Vector{PolyRingElem}

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.

source
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)$.

source
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.

source
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}$.

source

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
source
absolute_degreeMethod
absolute_degree(L::NumField) -> Int

Given a number field $L/K$, this function returns the degree of $L$ over $\mathbf Q$.

source
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)
source
unit_group_rankMethod
unit_group_rank(K::NumField) -> Int

Return the rank of the unit group of any order of $K$.

source
class_numberMethod
class_number(K::AbsSimpleNumField) -> ZZRingElem

Returns the class number of $K$.

source
relative_class_numberMethod
relative_class_number(K::AbsSimpleNumField) -> ZZRingElem

Returns the relative class number of $K$. The field must be a CM-field.

source
regulatorMethod
regulator(K::AbsSimpleNumField)

Computes the regulator of $K$, i.e. the discriminant of the unit lattice for the maximal order of $K$.

source
discriminantMethod
discriminant(L::SimpleNumField) -> NumFieldElem

The discriminant of the defining polynomial of $L$, not the discriminant of the maximal order of $L$.

source
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$.

source

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.

source
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}$.

source
is_totally_realMethod
is_totally_real(K::NumField) -> Bool

Return true if and only if $K$ is totally real, that is, if all roots of the defining polynomial are real.

source
is_totally_complexMethod
is_totally_complex(K::NumField) -> Bool

Return true if and only if $K$ is totally complex, that is, if all roots of the defining polynomial are not real.

source
is_cm_fieldMethod
is_cm_field(K::AbsSimpleNumField) -> Bool, NumFieldHom{AbsSimpleNumField, AbsSimpleNumField}

Given a number field $K$, this function returns true and the complex conjugation if the field is CM, false and the identity otherwise.

source
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.

source
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$.

source
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$.

source
is_weakly_ramifiedMethod
is_weakly_ramified(K::AbsSimpleNumField, P::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}) -> 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.

source
is_tamely_ramifiedMethod
is_tamely_ramified(K::AbsSimpleNumField) -> Bool

Returns whether the number field $K$ is tamely ramified.

source
is_tamely_ramifiedMethod
is_tamely_ramified(O::AbsSimpleNumFieldOrder, p::Union{Int, ZZRingElem}) -> Bool

Returns whether the integer $p$ is tamely ramified in $\mathcal O$. It is assumed that $p$ is prime.

source
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.

source

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$.

source
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$.

source
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$.

Examples

julia> Qx, x = QQ["x"];
-
-julia> K, a = number_field(x^8 - x^4 + 1);
-
-julia> length(principal_subfields(K))
-8
source
compositumMethod
compositum(K::AbsSimpleNumField, L::AbsSimpleNumField) -> AbsSimpleNumField, 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$.

source
embeddingMethod
embedding(k::NumField, K::NumField) -> Map

Assuming $k$ is known to be a subfield of $K$, return the embedding map.

source
normal_closureMethod
normal_closure(K::AbsSimpleNumField) -> AbsSimpleNumField, NumFieldHom{AbsSimpleNumField, AbsSimpleNumField}

The normal closure of $K$ together with the embedding map.

source
relative_simple_extensionMethod
relative_simple_extension(K::NumField, k::NumField) -> RelSimpleNumField

Given two fields $K\supset k$, it returns $K$ as a simple relative extension $L$ of $k$ and an isomorphism $L \to K$.

source
is_subfield_normalMethod
  is_subfield_normal(K::AbsSimpleNumField, L::AbsSimpleNumField) -> Bool, NumFieldHom{AbsSimpleNumField, AbsSimpleNumField}

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.

source

Conversion

simplifyMethod
simplify(K::AbsSimpleNumField; canonical::Bool = false) -> AbsSimpleNumField, NumFieldHom{AbsSimpleNumField, AbsSimpleNumField}

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.

source
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$.

source
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$.

source
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.

source

Morphisms

is_isomorphicMethod
is_isomorphic(K::SimpleNumField, L::SimpleNumField) -> Bool

Return true if $K$ and $L$ are isomorphic, otherwise false.

source
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$.

source
is_involutionMethod
is_involution(f::NumFieldHom{AbsSimpleNumField, AbsSimpleNumField}) -> Bool

Returns true if $f$ is an involution, i.e. if $f^2$ is the identity, false otherwise.

source
fixed_fieldMethod
fixed_field(K::SimpleNumField,
-            sigma::Map;
-            simplify::Bool = true) -> number_field, NumFieldHom{AbsSimpleNumField, AbsSimpleNumField}

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.

source
automorphism_listMethod
automorphism_list(L::NumField) -> Vector{NumFieldHom}

Given a number field $L/K$, return a list of all $K$-automorphisms of $L$.

source
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$.

source
complex_conjugationMethod
complex_conjugation(K::AbsSimpleNumField)

Given a normal number field, this function returns an automorphism which is the restriction of complex conjugation at one embedding.

source

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$.

source
decomposition_groupMethod
decomposition_group(K::AbsSimpleNumField, P::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}, 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.

source
ramification_groupMethod
ramification_group(K::AbsSimpleNumField, P::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}, 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.

source
inertia_subgroupMethod
inertia_subgroup(K::AbsSimpleNumField, P::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}, 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.

source

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{AbsSimpleNumField, AbsSimpleNumFieldEmbedding}}:
- Infinite place corresponding to (Complex embedding corresponding to -2.24 of real quadratic field)
- Infinite place corresponding to (Complex embedding corresponding to 2.24 of real quadratic field)
source
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{AbsSimpleNumField, AbsSimpleNumFieldEmbedding}}:
- Infinite place corresponding to (Complex embedding corresponding to -2.24 of real quadratic field)
- Infinite place corresponding to (Complex embedding corresponding to 2.24 of real quadratic field)
source
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{AbsSimpleNumField, AbsSimpleNumFieldEmbedding}}:
- Infinite place corresponding to (Complex embedding corresponding to 0.00 + 2.24 * i of imaginary quadratic field)
source
isrealMethod
isreal(P::Plc)

Return whether the embedding into $\mathbf{C}$ defined by $P$ is real or not.

source
is_complexMethod
is_complex(P::Plc) -> Bool

Return whether the embedding into $\mathbf{C}$ defined by $P$ is complex or not.

source

Miscellaneous

norm_equationMethod
norm_equation(K::AnticNumerField, a) -> AbsSimpleNumFieldElem

For $a$ an integer or rational, try to find $T \in K$ s.th. $N(T) = a$. Raises an error if unsuccessful.

source
lorenz_moduleMethod
lorenz_module(k::AbsSimpleNumField, n::Int) -> AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}

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.

source
kummer_failureMethod
kummer_failure(x::AbsSimpleNumFieldElem, 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$.

source
diff --git a/previews/PR4245/Hecke/manual/number_fields/internal/index.html b/previews/PR4245/Hecke/manual/number_fields/internal/index.html deleted file mode 100644 index 80f3c4275dcd..000000000000 --- a/previews/PR4245/Hecke/manual/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:

  • AbsSimpleNumField: a finite simple extension of the rational numbers $\mathbf{Q}$
  • AbsNonSimpleNumField: 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.
  • RelSimpleNumField: 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 (AbsSimpleNumField) is RelSimpleNumField{AbsSimpleNumFieldElem}. The next extension thus will be RelSimpleNumField{RelSimpleNumFieldElem{AbsSimpleNumFieldElem}}.
  • RelNonSimpleNumField: extensions of number fields given by several polynomials. This too will be referred to as a non-simple field.

The simple types AbsSimpleNumField and RelSimpleNumField are also called simple fields in the rest of this document, RelSimpleNumField and RelNonSimpleNumField are referred to as relative extensions while AbsSimpleNumField and AbsNonSimpleNumField 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 AbsSimpleNumField. 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/PR4245/Hecke/manual/number_fields/intro/index.html b/previews/PR4245/Hecke/manual/number_fields/intro/index.html deleted file mode 100644 index 3f36deca3afa..000000000000 --- a/previews/PR4245/Hecke/manual/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/PR4245/Hecke/manual/orders/elements/index.html b/previews/PR4245/Hecke/manual/orders/elements/index.html deleted file mode 100644 index d2169e4d47cc..000000000000 --- a/previews/PR4245/Hecke/manual/orders/elements/index.html +++ /dev/null @@ -1,44 +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 AbsNumFieldOrderElem, 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 AbsSimpleNumFieldOrderElem

AbsNumFieldOrderType
  (O::NumFieldOrder)(a::NumFieldElem, check::Bool = true) -> NumFieldOrderElem

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.

source
  (O::NumFieldOrder)(a::NumFieldOrderElem, check::Bool = true) -> NumFieldOrderElem

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.

source
  (O::NumFieldOrder)(a::IntegerUnion) -> NumFieldOrderElem

Given an element $a$ of type ZZRingElem or Integer, this function coerces the element into $\mathcal O$.

source
  (O::AbsNumFieldOrder)(arr::Vector{ZZRingElem})

Returns the element of $\mathcal O$ with coefficient vector arr.

source
  (O::AbsNumFieldOrder)(arr::Vector{Integer})

Returns the element of $\mathcal O$ with coefficient vector arr.

source

Basic properties

parentMethod
parent(a::NumFieldOrderElem) -> NumFieldOrder

Returns the order of which $a$ is an element.

source
parent(a::MatRingElem{T}) where T <: NCRingElement

Return the parent object of the given matrix.

source
elem_in_nfMethod
elem_in_nf(a::NumFieldOrderElem) -> NumFieldElem

Returns the element $a$ considered as an element of the ambient number field.

source
coordinatesMethod
coordinates(a::AbsNumFieldOrderElem) -> Vector{ZZRingElem}

Returns the coefficient vector of $a$ with respect to the basis of the order.

source
discriminantMethod
discriminant(B::Vector{NumFieldOrderElem})

Returns the discriminant of the family $B$ of algebraic numbers, i.e. $det((tr(B[i]*B[j]))_{i, j})^2$.

source
discriminant(E::EllipticCurve) -> FieldElem

Return the discriminant of $E$.

source
discriminant(C::HypellCrv{T}) -> T

Compute the discriminant of $C$.

source
discriminant(O::AlgssRelOrd)

Returns the discriminant of $O$.

source
discriminant(g::Vector)

Compute the product of all differences of distinct elements in the array.

source
==Method
==(x::NumFieldOrderElem, y::NumFieldOrderElem) -> Bool

Returns whether $x$ and $y$ are equal.

source

Arithmetic

All the usual arithmetic operatinos are defined:

  • -(::NUmFieldOrdElem)
  • +(::NumFieldOrderElem, ::NumFieldOrderElem)
  • -(::NumFieldOrderElem, ::NumFieldOrderElem)
  • *(::NumFieldOrderElem, ::NumFieldOrderElem)
  • ^(::NumFieldOrderElem, ::Int)
  • mod(::AbsNumFieldOrderElem, ::Int)
  • mod_sym(::NumFieldOrderElem, ::ZZRingElem)
  • powermod(::AbsNumFieldOrderElem, ::ZZRingElem, ::Int)

Miscellaneous

representation_matrixMethod
representation_matrix(a::AbsNumFieldOrderElem) -> ZZMatrix

Returns the representation matrix of the element $a$.

source
representation_matrixMethod
representation_matrix(a::AbsNumFieldOrderElem, K::AbsSimpleNumField) -> 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$.

source
trMethod
tr(a::NumFieldOrderElem)

Returns the trace of $a$ as an element of the base ring.

source
normMethod
norm(a::NumFieldOrderElem)

Returns the norm of $a$ as an element in the base ring.

source
absolute_normMethod
absolute_norm(a::NumFieldOrderElem) -> ZZRingElem

Return the absolute norm as an integer.

source
absolute_trMethod
absolute_tr(a::NumFieldOrderElem) -> ZZRingElem

Return the absolute trace as an integer.

source
randMethod
rand(O::AbsSimpleNumFieldOrder, n::IntegerUnion) -> AbsNumFieldOrderElem

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$.

source
minkowski_mapMethod
minkowski_map(a::NumFieldOrderElem, abs_tol::Int) -> Vector{ArbFieldElem}

Returns the image of $a$ under the Minkowski embedding. Every entry of the array returned is of type ArbFieldElem with radius less then 2^-abs_tol.

source
conjugates_arbMethod
conjugates_arb(x::NumFieldOrderElem, abs_tol::Int) -> Vector{AcbFieldElem}

Compute the conjugates of $x$ as elements of type AcbFieldElem. 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.

source
conjugates_arb_logMethod
conjugates_arb_log(x::NumFieldOrderElem, abs_tol::Int) -> Vector{ArbFieldElem}

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 ArbFieldElem radius less then 2^-abs_tol.

source
t2Method
t2(x::NumFieldOrderElem, abs_tol::Int = 32) -> ArbFieldElem

Return the $T_2$-norm of $x$. The radius of the result will be less than 2^-abs_tol.

source
minpolyMethod
minpoly(M::MatElem{T}, charpoly_only::Bool = false) where {T <: RingElement}
-minpoly(S::PolyRing{T}, M::MatElem{T}, charpoly_only::Bool = false) where {T <: RingElement}

Return the minimal polynomial $p$ of the square matrix $M$. If a polynomial ring $S$ over the same base ring as $Y$ is supplied, the resulting polynomial is an element of it.

Examples

julia> R = GF(13)
-Finite field F_13
-
-julia> S, 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(S, M)
-y^2 + 10*y
-
-julia> A = minpoly(M)
-x^2 + 10*x
-
source
minpoly(a::AbsNumFieldOrderElem) -> ZZPolyRingElem

The minimal polynomial of $a$.

source
minpoly(S::Ring, M::MatRingElem{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.

source
charpolyMethod
charpoly(Y::MatrixElem{T}) where {T <: RingElement}
-charpoly(S::PolyRing{T}, Y::MatrixElem{T}) where {T <: RingElement}

Return the characteristic polynomial $p$ of the square matrix $Y$. If a polynomial ring $S$ over the same base ring as $Y$ is supplied, the resulting polynomial is an element of it.

Examples

julia> R, = residue_ring(ZZ, 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, y = polynomial_ring(R, :y)
-(Univariate polynomial ring in y over residue ring, y)
-
-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)
-y^4 + 2*y^2 + 6*y + 2
-
-julia> A = charpoly(M)
-x^4 + 2*x^2 + 6*x + 2
-
source
charpoly(a::AbsNumFieldOrderElem) -> ZZPolyRingElem
-charpoly(a::AbsNumFieldOrderElem, FlintZZ) -> ZZPolyRingElem

The characteristic polynomial of $a$.

source
factorMethod
factor(a::AbsSimpleNumFieldOrderElem) -> Fac{AbsSimpleNumFieldOrderElem}

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.

source
denominatorMethod
denominator(a::NumFieldElem, O::AbsSimpleNumFieldOrder) -> ZZRingElem

Returns the smallest positive integer $k$ such that $k \cdot a$ is contained in $\mathcal O$.

source
discriminantMethod
discriminant(B::Vector{NumFieldOrderElem})

Returns the discriminant of the family $B$ of algebraic numbers, i.e. $det((tr(B[i]*B[j]))_{i, j})^2$.

source
discriminant(E::EllipticCurve) -> FieldElem

Return the discriminant of $E$.

source
discriminant(C::HypellCrv{T}) -> T

Compute the discriminant of $C$.

source
discriminant(O::AlgssRelOrd)

Returns the discriminant of $O$.

source
discriminant(g::Vector)

Compute the product of all differences of distinct elements in the array.

source
diff --git a/previews/PR4245/Hecke/manual/orders/frac_ideals/index.html b/previews/PR4245/Hecke/manual/orders/frac_ideals/index.html deleted file mode 100644 index a5b93f59266a..000000000000 --- a/previews/PR4245/Hecke/manual/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 AbsSimpleNumFieldOrderFractionalIdeal.

Creation

fractional_idealMethod
fractional_ideal(O::AbsNumFieldOrder, M::ZZMatrix, b::ZZRingElem; M_in_hnf::Bool = false) -> AbsNumFieldOrderFractionalIdeal

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.

source
fractional_idealMethod
fractional_ideal(O::AbsNumFieldOrder, M::ZZMatrix, b::ZZRingElem; M_in_hnf::Bool = false) -> AbsNumFieldOrderFractionalIdeal

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.

source
fractional_idealMethod
fractional_ideal(O::AbsNumFieldOrder, M::QQMatrix) -> AbsNumFieldOrderFractionalIdeal

Creates the fractional ideal of $\mathcal O$ generated by the elements corresponding to the rows of $M$.

source
fractional_idealMethod
fractional_ideal(O::AbsSimpleNumFieldOrder, I::AbsNumFieldOrderIdeal) -> AbsSimpleNumFieldOrderFractionalIdeal

The fractional ideal of $O$ generated by a $Z$-basis of $I$.

source
fractional_ideal(O::AbsNumFieldOrder, I::AbsNumFieldOrderIdeal) -> AbsNumFieldOrderFractionalIdeal

Turns the ideal $I$ into a fractional ideal of $\mathcal O$.

source
fractional_idealMethod
fractional_ideal(O::AbsNumFieldOrder, I::AbsNumFieldOrderIdeal, b::ZZRingElem) -> AbsNumFieldOrderFractionalIdeal

Creates the fractional ideal $I/b$ of $\mathcal O$.

source
fractional_idealMethod
fractional_ideal(O::AbsNumFieldOrder, a::AbsSimpleNumFieldElem) -> AbsNumFieldOrderFractionalIdeal

Creates the principal fractional ideal $(a)$ of $\mathcal O$.

source
fractional_idealMethod
fractional_ideal(O::AbsNumFieldOrder, a::AbsNumFieldOrderElem) -> AbsNumFieldOrderFractionalIdeal

Creates the principal fractional ideal $(a)$ of $\mathcal O$.

source
invMethod
inv(A::AbsNumFieldOrderIdeal) -> AbsSimpleNumFieldOrderFractionalIdeal

Computes the inverse of $A$, that is, the fractional ideal $B$ such that $AB = \mathcal O_K$.

source
 inv(a::LocalizedEuclideanRingElem{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.

source

Arithmetic

All the normal operations are provided as well.

invMethod
inv(A::AbsNumFieldOrderFractionalIdeal) -> AbsNumFieldOrderFractionalIdeal

Returns the fractional ideal $B$ such that $AB = \mathcal O$.

source
 inv(a::LocalizedEuclideanRingElem{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.

source
integral_splitMethod
integral_split(A::AbsNumFieldOrderFractionalIdeal) -> AbsNumFieldOrderIdeal, AbsNumFieldOrderIdeal

Computes the unique coprime integral ideals $N$ and $D$ s.th. $A = ND^{-1}$

source
numeratorMethod
numerator(a::RelNumFieldOrderFractionalIdeal) -> RelNumFieldOrderIdeal

Returns the ideal $d*a$ where $d$ is the denominator of $a$.

source
denominatorMethod
denominator(a::RelNumFieldOrderFractionalIdeal) -> ZZRingElem

Returns the smallest positive integer $d$ such that $da$ is contained in the order of $a$.

source

Miscaellenous

orderMethod
order(::Type{T} = BigInt, G::Group) where T

Return the order of $G$ as an instance of T. If $G$ is of infinite order, an InfiniteOrderError exception will be thrown. Use is_finite(G) to avoid this kind of exception. If the order does not fit into type T, an InexactError exception will be thrown.

source
order(::Type{T} = BigInt, g::GroupElem) where T

Return the order of $g$ as an instance of T. If $g$ is of infinite order, an InfiniteOrderError exception will be thrown. Use is_finite_order(G) to avoid this kind of exception. If the order does not fit into type T, an InexactError exception will be thrown.

source
order(a::AbsNumFieldOrderFractionalIdeal) -> AbsNumFieldOrder

The order that was used to define the ideal $a$.

source
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(::Type{T}, W::WeylGroup) where {T} -> T

Returns the order of W.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
basis_matrixMethod
basis_matrix(I::AbsNumFieldOrderFractionalIdeal) -> FakeFmpqMat

Returns the basis matrix of $I$ with respect to the basis of the order.

source
basis_mat_invMethod
basis_mat_inv(A::GenOrdIdl) -> FakeFracFldMat

Return the inverse of the basis matrix of $A$.

source
basisMethod
basis(I::AbsNumFieldOrderFractionalIdeal) -> Vector{AbsSimpleNumFieldElem}

Returns the $\mathbf Z$-basis of $I$.

source
normMethod
norm(I::AbsNumFieldOrderFractionalIdeal) -> QQFieldElem

Returns the norm of $I$.

source
norm(a::RelNumFieldOrderIdeal) -> AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}

Returns the norm of $a$.

source
norm(a::RelNumFieldOrderFractionalIdeal{T, S}) -> S

Returns the norm of $a$.

source
norm(a::AlgAssAbsOrdIdl, O::AlgAssAbsOrd; copy::Bool = true) -> QQFieldElem

Returns the norm of $a$ considered as an (possibly fractional) ideal of $O$.

source
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$.

source
diff --git a/previews/PR4245/Hecke/manual/orders/ideals/index.html b/previews/PR4245/Hecke/manual/orders/ideals/index.html deleted file mode 100644 index db30b89c931a..000000000000 --- a/previews/PR4245/Hecke/manual/orders/ideals/index.html +++ /dev/null @@ -1,92 +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 AbsNumFieldOrderIdeal, which is, similar to the elements above, also indexed by the type of the field and their elements: AbsNumFieldOrderIdeal{AbsSimpleNumField,AbsSimpleNumFieldElem} for ideals in simple absolute fields.

Different to elements, the parentof an ideal is the set of all ideals in the ring, of type AbsNumFieldOrderIdealSet.

Creation

idealMethod
ideal(O::AbsSimpleNumFieldOrder, a::ZZRingElem) -> AbsNumFieldOrderIdeal
-ideal(O::AbsSimpleNumFieldOrder, a::Integer) -> AbsNumFieldOrderIdeal

Returns the ideal of $\mathcal O$ which is generated by $a$.

source
idealMethod
ideal(O::AbsSimpleNumFieldOrder, M::ZZMatrix; check::Bool = false, M_in_hnf::Bool = false) -> AbsNumFieldOrderIdeal

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.

source
idealMethod
ideal(O::AbsSimpleNumFieldOrder, x::AbsSimpleNumFieldOrderElem) -> AbsNumFieldOrderIdeal

Creates the principal ideal $(x)$ of $\mathcal O$.

source
idealMethod
ideal(O::AbsSimpleNumFieldOrder, x::ZZRingElem, y::AbsSimpleNumFieldOrderElem) -> AbsNumFieldOrderIdeal
-ideal(O::AbsSimpleNumFieldOrder, x::Integer, y::AbsSimpleNumFieldOrderElem) -> AbsNumFieldOrderIdeal

Creates the ideal $(x, y)$ of $\mathcal O$.

source
idealMethod
ideal(O::AbsSimpleNumFieldOrder, x::ZZRingElem, y::AbsSimpleNumFieldOrderElem) -> AbsNumFieldOrderIdeal
-ideal(O::AbsSimpleNumFieldOrder, x::Integer, y::AbsSimpleNumFieldOrderElem) -> AbsNumFieldOrderIdeal

Creates the ideal $(x, y)$ of $\mathcal O$.

source
idealMethod
ideal(O::AbsSimpleNumFieldOrder, a::ZZRingElem) -> AbsNumFieldOrderIdeal
-ideal(O::AbsSimpleNumFieldOrder, a::Integer) -> AbsNumFieldOrderIdeal

Returns the ideal of $\mathcal O$ which is generated by $a$.

source
idealMethod
ideal(O::AbsSimpleNumFieldOrder, x::AbsSimpleNumFieldOrderElem) -> AbsNumFieldOrderIdeal

Creates the principal ideal $(x)$ of $\mathcal O$.

source
*Method
*(O::AbsSimpleNumFieldOrder, x::AbsSimpleNumFieldOrderElem) -> AbsNumFieldOrderIdeal
-*(x::AbsNumFieldOrderElem, O::AbsNumFieldOrder) -> AbsNumFieldOrderIdeal

Returns the principal ideal $(x)$ of $\mathcal O$.

source
factorMethod
factor(a::T) where T <: RingElement -> Fac{T}

Return a factorization of $a$ into irreducible elements, as a Fac{T}. The irreducible elements in the factorization are pairwise coprime.

source
factor(A::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}) -> Dict{AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}, 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).

source
factorMethod
factor(I::AbsNumFieldOrderIdealSet{AbsSimpleNumField, AbsSimpleNumFieldElem}, a::AbsSimpleNumFieldElem) -> Dict{AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}, ZZRingElem}

Factors the principal ideal generated by $a$.

source
coprime_baseMethod
coprime_base(A::Vector{AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}}) -> Vector{AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}}
-coprime_base(A::Vector{AbsSimpleNumFieldOrderElem}) -> Vector{AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}}

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.

source

Arithmetic

All the usual operations are supported:

  • ==, +, *
  • divexact, divides
  • lcm, gcd
  • in
intersectMethod
intersect(x::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}, y::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}) -> AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}

Returns $x \cap y$.

source
colonMethod
colon(a::AbsNumFieldOrderIdeal, b::AbsNumFieldOrderIdeal) -> AbsSimpleNumFieldOrderFractionalIdeal

The ideal $(a:b) = \{x \in K | xb \subseteq a\} = \hom(b, a)$ where $K$ is the number field.

source
inMethod
in(x::NumFieldOrderElem, y::NumFieldOrderIdeal)
-in(x::NumFieldElem, y::NumFieldOrderIdeal)
-in(x::ZZRingElem, y::NumFieldOrderIdeal)

Returns whether $x$ is contained in $y$.

source
is_powerMethod
is_power(A::AbsNumFieldOrderIdeal, n::Int) -> Bool, AbsNumFieldOrderIdeal
-is_power(A::AbsSimpleNumFieldOrderFractionalIdeal, n::Int) -> Bool, AbsSimpleNumFieldOrderFractionalIdeal

Computes, if possible, an ideal $B$ s.th. $B^n==A$ holds. In this case, true and $B$ are returned.

source
is_powerMethod
is_power(I::AbsNumFieldOrderIdeal) -> Int, AbsNumFieldOrderIdeal
-is_power(a::AbsSimpleNumFieldOrderFractionalIdeal) -> Int, AbsSimpleNumFieldOrderFractionalIdeal

Writes $a = r^e$ with $e$ maximal. Note: $1 = 1^0$.

source
is_invertibleMethod
is_invertible(A::AbsNumFieldOrderIdeal) -> Bool, AbsSimpleNumFieldOrderFractionalIdeal

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.

source
isoneMethod
isone(A::AbsNumFieldOrderIdeal) -> Bool
-is_unit(A::AbsNumFieldOrderIdeal) -> Bool

Tests if $A$ is the trivial ideal generated by $1$.

source

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::AbsSimpleNumFieldOrder; bound = -1,
-                      redo = false,
-                      GRH = true)   -> FinGenAbGroup, 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.

By default, the correctness is guarenteed only assuming the Generalized Riemann Hypothesis (GRH).

Keyword arguments:

  • redo: Trigger a recomputation, thus avoiding the cache.
  • bound: When specified, this is used for the bound for the factor base.
  • GRH: If false, the correctness of the result does not depend on GRH.
source
narrow_class_groupMethod
narrow_class_group(O::AbsSimpleNumFieldOrder) -> FinGenAbGroup, 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.

source
picard_groupMethod
picard_group(O::AbsSimpleNumFieldOrder) -> FinGenAbGroup, MapClassGrp

Returns the Picard group of $O$ and a map from the group in the set of (invertible) ideals of $O$.

source
ring_class_groupMethod
ring_class_group(O::AbsNumFieldOrder)

The ring class group (Picard group) of $O$.

source

julia> k, a = wildanger_field(3, 13);
julia> zk = maximal_order(k);
julia> c, mc = class_group(zk)(Z/9, ClassGroup map of -Set of ideals of Maximal order of Number field of degree 3 over QQ -with basis AbsSimpleNumFieldElem[1, _$, 1//2*_$^2 + 1//2])
julia> lp = prime_ideals_up_to(zk, 20);
julia> [ mc \ I for I = lp]10-element Vector{FinGenAbGroupElem}: - [1] - [7] - [1] - [8] - [3] - [5] - [4] - [7] - [0] - [5]
julia> mc(c[1])<2, 3//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, 16521184280351827467//2*_$^2 - 8198562999464506071*_$ + 17886756934959371397//2> -Norm: 512 -Minimum: 32 -two normal wrt: 2
julia> mc \ ansAbelian group element [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::AbsSimpleNumFieldOrderIdeal) -> Bool
-is_principal(A::AbsSimpleNumFieldOrderFractionalIdeal) -> Bool

Tests if $A$ is principal.

source
is_principal_with_dataMethod
is_principal_with_data(A::AbsSimpleNumFieldOrderIdeal) -> Bool, AbsSimpleNumFieldOrderElem
-is_principal_with_data(A::AbsSimpleNumFieldOrderFractionalIdeal) -> Bool, AbsSimpleNumFieldElem

Tests if $A$ is principal and returns $(\mathtt{true}, \alpha)$ if $A = \langle \alpha\rangle$ or $(\mathtt{false}, 1)$ otherwise.

source
is_principal_fac_elemMethod
is_principal_fac_elem(A::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}) -> Bool, FacElem{AbsSimpleNumFieldElem, 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.

source
power_classMethod
power_class(A::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}, e::ZZRingElem) -> AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}

Computes a (small) ideal in the same class as $A^e$.

source
power_product_classMethod
power_product_class(A::Vector{AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}}, e::Vector{ZZRingElem}) -> AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}

Computes a (small) ideal in the same class as $\prod A_i^{e_i}$.

source
power_reduceMethod
power_reduce(A::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}, e::ZZRingElem) -> AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}, FacElem{AbsSimpleNumFieldElem}

Computes $B$ and $\alpha$ in factored form, such that $\alpha B = A^e$ $B$ has small norm.

source
class_group_ideal_relationMethod
class_group_ideal_relation(I::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}, c::ClassGrpCtx) -> AbsSimpleNumFieldElem, SRow{ZZRingElem}

Finds a number field element $\alpha$ such that $\alpha I$ factors over the factor base in $c$.

source
factor_base_bound_grhMethod
factor_base_bound_grh(O::AbsSimpleNumFieldOrder) -> 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$.

source
factor_base_bound_bachMethod
factor_base_bound_bach(O::AbsSimpleNumFieldOrder) -> 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$.

source
prime_ideals_up_toFunction
prime_ideals_up_to(O::AbsSimpleNumFieldOrder,
-                   B::Int;
-                   degree_limit::Int = 0, index_divisors::Bool = true) -> Vector{AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}}

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.

source
prime_ideals_up_to(O::AbsSimpleNumFieldOrder,
-                   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$.

source
julia> I = mc(c[1])<2, 3//2*_$^2 + 3//2>
-Norm: 2
-Minimum: 2
-two normal wrt: 2
julia> is_principal(I)false
julia> I = I^Int(order(c[1]))<32, 16521184280351827467//2*_$^2 - 8198562999464506071*_$ + 17886756934959371397//2> -Norm: 512 -Minimum: 32 -two normal wrt: 2
julia> is_principal(I)true
julia> is_principal_fac_elem(I)(true, (-1//2*_$^2 + 6*_$ - 3//2)^2*5^2*(_$^2 + 1)^3*(_$ + 5)^-1*(_$^2 + _$ + 2)^-2*3^-3*(1//2*_$^2 + 3//2)^-1*11^-1*(_$ + 1)^-2*2^2*(_$ + 27)^1*(_$ + 2)^2*1^-1)

The computation of $S$-units is also tied to the class group:

torsion_unitsMethod
torsion_units(O::AbsSimpleNumFieldOrder) -> Vector{AbsSimpleNumFieldOrderElem}

Given an order $O$, compute the torsion units of $O$.

source
torsion_unit_groupMethod
torsion_unit_group(O::AbsSimpleNumFieldOrder) -> 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$.

source
torsion_units_generatorMethod
torsion_units_generator(O::AbsSimpleNumFieldOrder) -> AbsSimpleNumFieldOrderElem

Given an order $O$, compute a generator of the torsion units of $O$.

source
torsion_units_gen_orderMethod
torsion_units_gen_order(O::AbsSimpleNumFieldOrder) -> AbsSimpleNumFieldOrderElem

Given an order $O$, compute a generator of the torsion units of $O$ as well as its order.

source
unit_groupMethod
unit_group(O::AbsSimpleNumFieldOrder) -> FinGenAbGroup, 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.

source
unit_group_fac_elemMethod
unit_group_fac_elem(O::AbsSimpleNumFieldOrder) -> FinGenAbGroup, 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.

source
sunit_groupMethod
sunit_group(I::Vector{AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}}) -> 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$.

source
sunit_group_fac_elemMethod
sunit_group_fac_elem(I::Vector{AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}}) -> 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.

source
sunit_mod_units_group_fac_elemMethod
sunit_mod_units_group_fac_elem(I::Vector{AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}}) -> 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.

source
julia> u, mu = unit_group(zk)(Z/2 x Z, UnitGroup map of Maximal order of Number field of degree 3 over QQ
-with basis AbsSimpleNumFieldElem[1, _$, 1//2*_$^2 + 1//2]
-)
julia> mu(u[2])-_$ + 12
julia> u, mu = unit_group_fac_elem(zk)(Z/2 x Z, UnitGroup map of Factored elements over Number field of degree 3 over QQ -)
julia> mu(u[2])(-_$ + 5)^1*(_$^2 + 1)^-1*(113//2*_$^2 - 707*_$ + 767//2)^1*(31*_$^2 - 263*_$ - 533)^-1*3^1
julia> evaluate(ans)-_$ + 12
julia> lp = factor(6*zk)Dict{AbsSimpleNumFieldOrderIdeal, Int64} with 4 entries: - <3, _$ + 5> => 1 - <3, _$^2 + 1> => 1 - <2, 7//2*_$^2 + 3//2> => 2 - <2, 7//2*_$^2 + 5//2> => 1
julia> s, ms = Hecke.sunit_group(collect(keys(lp)))(Z/2 x Z^(5), SUnits map of Number field of degree 3 over QQ for AbsSimpleNumFieldOrderIdeal[<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, 7//2*_$^2 + 3//2> -Norm: 2 -Minimum: 2 -basis_matrix -[2 0 0; 1 1 0; 0 0 1] -two normal wrt: 2, <2, 7//2*_$^2 + 5//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} = BigInt, G::Group) where T

Return the order of $G$ as an instance of T. If $G$ is of infinite order, an InfiniteOrderError exception will be thrown. Use is_finite(G) to avoid this kind of exception. If the order does not fit into type T, an InexactError exception will be thrown.

source
order(::Type{T} = BigInt, g::GroupElem) where T

Return the order of $g$ as an instance of T. If $g$ is of infinite order, an InfiniteOrderError exception will be thrown. Use is_finite_order(G) to avoid this kind of exception. If the order does not fit into type T, an InexactError exception will be thrown.

source
order(I::NumFieldOrderIdeal) -> AbsSimpleNumFieldOrder

Returns the order of $I$.

source
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(::Type{T}, W::WeylGroup) where {T} -> T

Returns the order of W.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
orderMethod
order(a::AbsNumFieldOrderFractionalIdeal) -> AbsNumFieldOrder

The order that was used to define the ideal $a$.

source
orderMethod
order(::Type{T} = BigInt, G::Group) where T

Return the order of $G$ as an instance of T. If $G$ is of infinite order, an InfiniteOrderError exception will be thrown. Use is_finite(G) to avoid this kind of exception. If the order does not fit into type T, an InexactError exception will be thrown.

source
order(::Type{T} = BigInt, g::GroupElem) where T

Return the order of $g$ as an instance of T. If $g$ is of infinite order, an InfiniteOrderError exception will be thrown. Use is_finite_order(G) to avoid this kind of exception. If the order does not fit into type T, an InexactError exception will be thrown.

source
order(I::NumFieldOrderIdeal) -> AbsSimpleNumFieldOrder

Returns the order of $I$.

source
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(::Type{T}, W::WeylGroup) where {T} -> T

Returns the order of W.

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
orderMethod
order(a::RelNumFieldOrderFractionalIdeal) -> RelNumFieldOrder

Returns the order of $a$.

source
nfMethod
nf(x::NumFieldOrderIdeal) -> AbsSimpleNumField

Returns the number field, of which $x$ is an integral ideal.

source
basisMethod
basis(A::AbsNumFieldOrderIdeal) -> Vector{AbsSimpleNumFieldOrderElem}

Returns the basis of $A$.

source
basis(I::AbsNumFieldOrderFractionalIdeal) -> Vector{AbsSimpleNumFieldElem}

Returns the $\mathbf Z$-basis of $I$.

source
lll_basisMethod
lll_basis(I::NumFieldOrderIdeal) -> Vector{NumFieldElem}

A basis for $I$ that is reduced using the LLL algorithm for the Minkowski metric.

source
basis_matrixMethod
basis_matrix(A::AbsNumFieldOrderIdeal) -> ZZMatrix

Returns the basis matrix of $A$.

source
basis_mat_invMethod
basis_mat_inv(A::GenOrdIdl) -> FakeFracFldMat

Return the inverse of the basis matrix of $A$.

source
has_princ_gen_specialMethod
has_princ_gen_special(A::AbsNumFieldOrderIdeal) -> Bool

Returns whether $A$ knows if it is generated by a rational integer.

source
principal_generatorMethod
principal_generator(A::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}) -> AbsSimpleNumFieldOrderElem

For a principal ideal $A$, find a generator.

source
principal_generator_fac_elemMethod
principal_generator_fac_elem(A::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}) -> FacElem{AbsSimpleNumFieldElem, number_field}

For a principal ideal $A$, find a generator in factored form.

source
minimumMethod
minimum(A::AbsNumFieldOrderIdeal) -> ZZRingElem

Returns the smallest non-negative element in $A \cap \mathbf Z$.

source
  minimum(A::RelNumFieldOrderIdeal) -> AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}
-  minimum(A::RelNumFieldOrderIdeal) -> RelNumFieldOrderIdeal

Returns the ideal $A \cap O$ where $O$ is the maximal order of the coefficient ideals of $A$.

source
minimumMethod
  minimum(A::RelNumFieldOrderIdeal) -> AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}
-  minimum(A::RelNumFieldOrderIdeal) -> RelNumFieldOrderIdeal

Returns the ideal $A \cap O$ where $O$ is the maximal order of the coefficient ideals of $A$.

source
minimumMethod
minimum(A::AbsNumFieldOrderIdeal) -> ZZRingElem

Returns the smallest non-negative element in $A \cap \mathbf Z$.

source
has_minimumMethod
has_minimum(A::AbsNumFieldOrderIdeal) -> Bool

Returns whether $A$ knows its minimum.

source
normMethod
norm(A::AbsNumFieldOrderIdeal) -> ZZRingElem

Returns the norm of $A$, that is, the cardinality of $\mathcal O/A$, where $\mathcal O$ is the order of $A$.

source
norm(a::RelNumFieldOrderIdeal) -> AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}

Returns the norm of $a$.

source
norm(a::RelNumFieldOrderFractionalIdeal{T, S}) -> S

Returns the norm of $a$.

source
norm(a::AlgAssAbsOrdIdl, O::AlgAssAbsOrd; copy::Bool = true) -> QQFieldElem

Returns the norm of $a$ considered as an (possibly fractional) ideal of $O$.

source
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$.

source
has_normMethod
has_norm(A::AbsNumFieldOrderIdeal) -> Bool

Returns whether $A$ knows its norm.

source
idempotentsMethod
idempotents(x::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}, y::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}) -> AbsSimpleNumFieldOrderElem, AbsSimpleNumFieldOrderElem

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.

source
is_primeMethod
is_prime(A::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}) -> Bool

Returns whether $A$ is a prime ideal.

source
is_prime_knownMethod
is_prime_known(A::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}) -> Bool

Returns whether $A$ knows if it is prime.

source
is_ramifiedMethod
is_ramified(O::AbsSimpleNumFieldOrder, p::Int) -> Bool

Returns whether the integer $p$ is ramified in $\mathcal O$. It is assumed that $p$ is prime.

source
ramification_indexMethod
ramification_index(P::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}) -> Int

The ramification index of the prime-ideal $P$.

source
degreeMethod
degree(P::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}) -> Int

The inertia degree of the prime-ideal $P$.

source
valuationMethod
valuation(a::NumFieldElem, p::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}) -> ZZRingElem

Computes the $\mathfrak p$-adic valuation of $a$, that is, the largest $i$ such that $a$ is contained in $\mathfrak p^i$.

source
valuationMethod
valuation(a::AbsSimpleNumFieldElem, p::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}) -> ZZRingElem
-valuation(a::AbsSimpleNumFieldOrderElem, p::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}) -> ZZRingElem
-valuation(a::ZZRingElem, p::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}) -> ZZRingElem

Computes the $\mathfrak p$-adic valuation of $a$, that is, the largest $i$ such that $a$ is contained in $\mathfrak p^i$.

source
valuationMethod
valuation(A::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}, p::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}) -> ZZRingElem

Computes the $\mathfrak p$-adic valuation of $A$, that is, the largest $i$ such that $A$ is contained in $\mathfrak p^i$.

source
valuationMethod
valuation(a::Integer, p::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}) -> ZZRingElem

Computes the $\mathfrak p$-adic valuation of $a$, that is, the largest $i$ such that $a$ is contained in $\mathfrak p^i$.

source
valuationMethod
valuation(a::AbsSimpleNumFieldElem, p::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}) -> ZZRingElem
-valuation(a::AbsSimpleNumFieldOrderElem, p::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}) -> ZZRingElem
-valuation(a::ZZRingElem, p::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}) -> ZZRingElem

Computes the $\mathfrak p$-adic valuation of $a$, that is, the largest $i$ such that $a$ is contained in $\mathfrak p^i$.

source
valuationMethod
valuation(A::AbsNumFieldOrderFractionalIdeal, p::AbsNumFieldOrderIdeal)

The valuation of $A$ at $p$.

source
idempotentsMethod
idempotents(x::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}, y::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}) -> AbsSimpleNumFieldOrderElem, AbsSimpleNumFieldOrderElem

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.

source

Quotient Rings

quoMethod
quo(O::AbsSimpleNumFieldOrder, I::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}) -> AbsSimpleNumFieldOrderQuoRing, 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$.

source
residue_ringMethod
residue_ring(O::AbsSimpleNumFieldOrder, I::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}) -> AbsSimpleNumFieldOrderQuoRing
-residue_ring(O::AlgAssAbsOrd, I::AlgAssAbsOrdIdl) -> AbsOrdQuoRing

The quotient ring $O$ modulo $I$ as a new ring.

source
residue_fieldMethod
residue_field(O::AbsSimpleNumFieldOrder, P::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}, 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.

source
modMethod
mod(x::AbsSimpleNumFieldOrderElem, I::AbsNumFieldOrderIdeal)

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$.

source
crtMethod
crt(r1::AbsSimpleNumFieldOrderElem, i1::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}, r2::AbsSimpleNumFieldOrderElem, i2::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}) -> AbsSimpleNumFieldOrderElem

Find $x$ such that $x \equiv r_1 \bmod i_1$ and $x \equiv r_2 \bmod i_2$ using idempotents.

source
euler_phiMethod
euler_phi(A::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}) -> ZZRingElem

The ideal version of the totient function returns the size of the unit group of the residue ring modulo the ideal.

source
multiplicative_groupMethod
multiplicative_group(Q::AbsSimpleNumFieldOrderQuoRing) -> FinGenAbGroup, Map{FinGenAbGroup, AbsSimpleNumFieldOrderQuoRing}
-unit_group(Q::AbsSimpleNumFieldOrderQuoRing) -> FinGenAbGroup, Map{FinGenAbGroup, AbsSimpleNumFieldOrderQuoRing}

Returns the unit group of $Q$ as an abstract group $A$ and an isomorphism map $f \colon A \to Q^\times$.

source
multiplicative_group_generatorsMethod
multiplicative_group_generators(Q::AbsSimpleNumFieldOrderQuoRing) -> Vector{AbsSimpleNumFieldOrderQuoRingElem}

Return a set of generators for $Q^\times$.

source
diff --git a/previews/PR4245/Hecke/manual/orders/introduction/index.html b/previews/PR4245/Hecke/manual/orders/introduction/index.html deleted file mode 100644 index b7a7debe1352..000000000000 --- a/previews/PR4245/Hecke/manual/orders/introduction/index.html +++ /dev/null @@ -1,16 +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 [Coh93], [Coh00], [PZ97] or [Mar18].

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 [Coh00], 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 = equation_order(K)Maximal order of Number field of degree 2 over QQ -with basis AbsSimpleNumFieldElem[1, a]
julia> Z_K = maximal_order(K)Maximal order of Number field of degree 2 over QQ -with basis AbsSimpleNumFieldElem[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{AbsSimpleNumFieldOrderIdeal, 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
julia> fl, alpha = is_principal_with_data(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)(Prime field of characteristic 2, Map: maximal order of Number field of degree 2 over QQ
-with basis AbsSimpleNumFieldElem[1, a] -> GF(2))
julia> [ mFp(x) for x = basis(Z_K)]2-element Vector{FqFieldElem}: - 1 - 0
diff --git a/previews/PR4245/Hecke/manual/orders/orders/index.html b/previews/PR4245/Hecke/manual/orders/orders/index.html deleted file mode 100644 index 6999aaf838ab..000000000000 --- a/previews/PR4245/Hecke/manual/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{AbsSimpleNumFieldElem}; check::Bool = true, cached::Bool = true, isbasis::Bool = false) -> AbsSimpleNumFieldOrder
-Order(K::AbsSimpleNumField, a::Vector{AbsSimpleNumFieldElem}; check::Bool = true, cached::Bool = true, isbasis::Bool = false) -> AbsSimpleNumFieldOrder

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.

source
OrderMethod
Order(K::AbsSimpleNumField, A::QQMatrix; check::Bool = true) -> AbsSimpleNumFieldOrder

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.

source
Order(K::AbsSimpleNumField, A::QQMatrix; check::Bool = true) -> AbsSimpleNumFieldOrder

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.

source
OrderMethod
Order(K::AbsSimpleNumField, A::ZZMatrix, check::Bool = true) -> AbsSimpleNumFieldOrder

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.

source
Order(A::AbstractAssociativeAlgebra{<: NumFieldElem}, M::PMat{<: NumFieldElem, T})
-  -> AlgAssRelOrd

Returns the order of $A$ with basis pseudo-matrix $M$.

source
EquationOrderMethod
EquationOrder(K::number_field) -> NumFieldOrder
-equation_order(K::number_field) -> NumFieldOrder

Returns the equation order of the number field $K$.

source
MaximalOrderMethod
MaximalOrder(K::NumField{QQFieldElem}; discriminant::ZZRingElem, ramified_primes::Vector{ZZRingElem}) -> AbsNumFieldOrder

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);
source
MaximalOrderMethod
MaximalOrder(O::AbsNumFieldOrder; index_divisors::Vector{ZZRingElem}, discriminant::ZZRingElem, ramified_primes::Vector{ZZRingElem}) -> AbsNumFieldOrder

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.

source
MaximalOrder(O::AlgAssAbsOrd)

Given an order $O$, this function returns a maximal order containing $O$.

source
MaximalOrder(A::AbstractAssociativeAlgebra{QQFieldElem}) -> AlgAssAbsOrd

Returns a maximal order of $A$.

source
lllMethod
lll(M::AbsNumFieldOrder) -> AbsNumFieldOrder

The same order, but with the basis now being LLL reduced wrt. the Minkowski metric.

source
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.

source

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 AbsSimpleNumFieldOrderElem[1, a]
parentMethod
parent(O::AbsNumFieldOrder) -> AbsNumFieldOrderSet

Returns the parent of $\mathcal O$, that is, the set of orders of the ambient number field.

source
signatureMethod
signature(O::NumFieldOrder) -> Tuple{Int, Int}

Returns the signature of the ambient number field of $\mathcal O$.

source
nfMethod
nf(O::NumFieldOrder) -> NumField

Returns the ambient number field of $\mathcal O$.

source
basisMethod
basis(O::AbsNumFieldOrder) -> Vector{AbsNumFieldOrderElem}

Returns the $\mathbf Z$-basis of $\mathcal O$.

source
basis(I::AbsNumFieldOrderFractionalIdeal) -> Vector{AbsSimpleNumFieldElem}

Returns the $\mathbf Z$-basis of $I$.

source
lll_basisMethod
lll_basis(M::NumFieldOrder) -> Vector{NumFieldElem}

A basis for $M$ that is reduced using the LLL algorithm for the Minkowski metric.

source
basisMethod
basis(O::AbsSimpleNumFieldOrder, K::AbsSimpleNumField) -> Vector{AbsSimpleNumFieldElem}

Returns the $\mathbf Z$-basis elements of $\mathcal O$ as elements of the ambient number field.

source
pseudo_basisMethod
  pseudo_basis(O::RelNumFieldOrder{T, S}) -> Vector{Tuple{NumFieldElem{T}, S}}

Returns the pseudo-basis of $\mathcal O$.

source
basis_pmatrixMethod
  basis_pmatrix(O::RelNumFieldOrder) -> PMat

Returns the basis pseudo-matrix of $\mathcal O$ with respect to the power basis of the ambient number field.

source
basis_nfMethod
  basis_nf(O::RelNumFieldOrder) -> Vector{NumFieldElem}

Returns the elements of the pseudo-basis of $\mathcal O$ as elements of the ambient number field.

source
inv_coeff_idealsMethod
  inv_coeff_ideals(O::RelNumFieldOrder{T, S}) -> Vector{S}

Returns the inverses of the coefficient ideals of the pseudo basis of $O$.

source
basis_matrixMethod
basis_matrix(O::AbsNumFieldOrder) -> QQMatrix

Returns the basis matrix of $\mathcal O$ with respect to the basis of the ambient number field.

source
basis_mat_invMethod
basis_mat_inv(A::GenOrdIdl) -> FakeFracFldMat

Return the inverse of the basis matrix of $A$.

source
gen_indexMethod
gen_index(O::AbsSimpleNumFieldOrder) -> QQFieldElem

Returns the generalized index of $\mathcal O$ with respect to the equation order of the ambient number field.

source
is_index_divisorMethod
is_index_divisor(O::AbsSimpleNumFieldOrder, d::ZZRingElem) -> Bool
-is_index_divisor(O::AbsSimpleNumFieldOrder, 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.

source
minkowski_matrixMethod
minkowski_matrix(O::AbsNumFieldOrder, abs_tol::Int = 64) -> ArbMatrix

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 ArbFieldElem with radius less then 2^-abs_tol.

source
inMethod
in(a::NumFieldElem, O::NumFieldOrder) -> Bool

Checks whether $a$ lies in $\mathcal O$.

source
norm_change_constMethod
norm_change_const(O::AbsSimpleNumFieldOrder) -> (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$.

source
trace_matrixMethod
trace_matrix(O::AbsNumFieldOrder) -> 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}$.

source
+Method
+(R::AbsSimpleNumFieldOrder, S::AbsSimpleNumFieldOrder) -> AbsSimpleNumFieldOrder

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.

source
poverorderMethod
poverorder(O::AbsSimpleNumFieldOrder, p::ZZRingElem) -> AbsSimpleNumFieldOrder
-poverorder(O::AbsSimpleNumFieldOrder, p::Integer) -> AbsSimpleNumFieldOrder

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.

source
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.

source
pmaximal_overorderMethod
pmaximal_overorder(O::AbsSimpleNumFieldOrder, p::ZZRingElem) -> AbsSimpleNumFieldOrder
-pmaximal_overorder(O::AbsSimpleNumFieldOrder, p::Integer) -> AbsSimpleNumFieldOrder

This function finds a $p$-maximal order $R$ containing $\mathcal O$. That is, the index $[ \mathcal O_K : R]$ is not divisible by $p$.

source
pradicalMethod
pradical(O::AbsSimpleNumFieldOrder, p::{ZZRingElem|Integer}) -> AbsNumFieldOrderIdeal

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.

source
pradicalMethod
  pradical(O::RelNumFieldOrder, P::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}) -> RelNumFieldOrderIdeal

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.

source
ring_of_multipliersMethod
ring_of_multipliers(I::AbsNumFieldOrderIdeal) -> AbsNumFieldOrder

Computes the order $(I : I)$, which is the set of all $x \in K$ with $xI \subseteq I$.

source

Invariants

discriminantMethod
discriminant(O::AbsSimpleNumFieldOrder) -> ZZRingElem

Returns the discriminant of $\mathcal O$.

source
reduced_discriminantMethod
reduced_discriminant(O::AbsSimpleNumFieldOrder) -> ZZRingElem

Returns the reduced discriminant, that is, the largest elementary divisor of the trace matrix of $\mathcal O$.

source
degreeMethod
degree(O::NumFieldOrder) -> Int

Returns the degree of $\mathcal O$.

source
indexMethod
index(O::AbsSimpleNumFieldOrder) -> 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]$.

source
differentMethod
different(R::AbsNumFieldOrder) -> AbsNumFieldOrderIdeal

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.

source
codifferentMethod
codifferent(R::AbsNumFieldOrder) -> AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}

The codifferent ideal of $R$, i.e. the trace-dual of $R$.

source
is_gorensteinMethod
is_gorenstein(O::AbsSimpleNumFieldOrder) -> Bool

Return whether the order \mathcal{O} is Gorenstein.

source
is_bassMethod
is_bass(O::AbsSimpleNumFieldOrder) -> Bool

Return whether the order \mathcal{O} is Bass.

source
is_equation_orderMethod
is_equation_order(O::NumFieldOrder) -> Bool

Returns whether $\mathcal O$ is the equation order of the ambient number field $K$.

source
zeta_log_residueMethod
zeta_log_residue(O::AbsSimpleNumFieldOrder, error::Float64) -> ArbFieldElem

Computes the residue of the zeta function of $\mathcal O$ at $1$. The output will be an element of type ArbFieldElem with radius less then error.

source
ramified_primesMethod
ramified_primes(O::AbsNumFieldOrder) -> Vector{ZZRingElem}

Returns the list of prime numbers that divide $\operatorname{disc}(\mathcal O)$.

source

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 groups, 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.

source

Predicates

is_containedMethod
is_contained(R::AbsNumFieldOrder, S::AbsNumFieldOrder) -> Bool

Checks if $R$ is contained in $S$.

source
is_maximalMethod
is_maximal(R::AbsNumFieldOrder) -> Bool

Tests if the order $R$ is maximal. This might trigger the computation of the maximal order.

source
diff --git a/previews/PR4245/Hecke/manual/quad_forms/Zgenera/index.html b/previews/PR4245/Hecke/manual/quad_forms/Zgenera/index.html deleted file mode 100644 index ae3d38ef5e8e..000000000000 --- a/previews/PR4245/Hecke/manual/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 [CS99] 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.

source

Creation of Genera

From an integral Lattice

genusMethod
genus(L::ZZLat) -> ZZGenus

Return the genus of the lattice L.

source

From a gram matrix

genusMethod
genus(A::MatElem) -> ZZGenus

Return the genus of a $\mathbb Z$-lattice with gram matrix A.

source

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)
source

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.

source

Attributes of the genus

dimMethod
dim(G::ZZGenus) -> Int

Return the dimension of this genus.

source
rankMethod
rank(G::ZZGenus) -> Int

Return the rank of a (representative of) the genus G.

source
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.

source
detMethod
det(G::ZZGenus) -> QQFieldElem

Return the determinant of this genus.

source
isevenMethod
iseven(G::ZZGenus) -> Bool

Return if this genus is even.

source
is_definiteMethod
is_definite(G::ZZGenus) -> Bool

Return if this genus is definite.

source
levelMethod
level(G::ZZGenus) -> QQFieldElem

Return the level of this genus.

This is the denominator of the inverse gram matrix of a representative.

source
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).

source
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\}$.

source
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.

source
is_integralMethod
is_integral(G::ZZGenus) -> Bool

Return whether G is a genus of integral $\mathbb Z$-lattices.

source

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.

source
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.

source
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.

source
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.

source

local Symbol

local_symbolMethod
local_symbol(G::ZZGenus, p) -> ZZLocalGenus

Return the local symbol at p.

source

Representative(s)

quadratic_spaceMethod
quadratic_space(G::ZZGenus) -> QuadSpace{QQField, QQMatrix}

Return the quadratic space defined by this genus.

source
rational_representativeMethod
rational_representative(G::ZZGenus) -> QuadSpace{QQField, QQMatrix}

Return the quadratic space defined by this genus.

source
representativeMethod
representative(G::ZZGenus) -> ZZLat

Compute a representative of this genus && cache it.

source
representativesMethod
representatives(G::ZZGenus) -> Vector{ZZLat}

Return a list of representatives of the isometry classes in this genus.

source
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)|}$.

source
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.

source

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.

source

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: [CS99] 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
source

Creation

genusMethod
genus(L::ZZLat, p::IntegerUnion) -> ZZLocalGenus

Return the local genus symbol of L at the prime p.

source
genusMethod
genus(A::QQMatrix, p::IntegerUnion) -> ZZLocalGenus

Return the local genus symbol of a Z-lattice with gram matrix A at the prime p.

source

Attributes

primeMethod
prime(S::ZZLocalGenus) -> ZZRingElem

Return the prime p of this p-adic genus.

source
isevenMethod
iseven(S::ZZLocalGenus) -> Bool

Return if the underlying p-adic lattice is even.

If p is odd, every lattice is even.

source
symbolMethod
symbol(S::ZZLocalGenus, scale::Int) -> Vector{Int}

Return the underlying lists of integers for the Jordan block of the given scale

source
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\]

.

source
detMethod
det(S::ZZLocalGenus) -> QQFieldElem

Return an rational representing the determinant of this genus.

source
dimMethod
dim(S::ZZLocalGenus) -> Int

Return the dimension of this genus.

source
rankMethod
rank(S::ZZLocalGenus) -> Int

Return the rank of (a representative of) S.

source
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

[CS99] pp 370-371.

source
signatureMethod
signature(S::ZZLocalGenus) -> zzModRingElem

Return the $p$-signature of this $p$-adic form.

source
oddityMethod
oddity(S::ZZLocalGenus) -> zzModRingElem

Return the oddity of this even form. The oddity is also called the $2$-signature

source
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).

source
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\}$.

source
levelMethod
level(S::ZZLocalGenus) -> QQFieldElem

Return the maximal scale of a jordan component.

source

Representative

representativeMethod
representative(S::ZZLocalGenus) -> ZZLat

Return an integer lattice which represents this local genus.

source
gram_matrixMethod
gram_matrix(S::ZZLocalGenus) -> MatElem

Return a gram matrix of some representative of this local genus.

source
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.

source

Direct sums

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

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

source

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]}$.

source
diff --git a/previews/PR4245/Hecke/manual/quad_forms/basics/index.html b/previews/PR4245/Hecke/manual/quad_forms/basics/index.html deleted file mode 100644 index c25c28fc9364..000000000000 --- a/previews/PR4245/Hecke/manual/quad_forms/basics/index.html +++ /dev/null @@ -1,35 +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.

source
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.

source
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.

source
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.

source

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 = cyclotomic_real_subfield(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.

source
dimMethod
dim(V::AbstractSpace) -> Int

Return the dimension of the space V.

source
gram_matrixMethod
gram_matrix(V::AbstractSpace) -> MatElem

Return the Gram matrix of the space V.

source
involutionMethod
involution(V::AbstractSpace) -> NumFieldHom

Return the involution of the space V.

source
base_ringMethod
base_ring(V::AbstractSpace) -> NumField

Return the algebra over which the space V is defined.

source
fixed_fieldMethod
fixed_field(V::AbstractSpace) -> NumField

Return the fixed field of the space V.

source
detMethod
det(V::AbstractSpace) -> FieldElem

Return the determinant of the space V as an element of its fixed field.

source
discriminantMethod
discriminant(V::AbstractSpace) -> FieldElem

Return the discriminant of the space V as an element of its fixed field.

source

Examples

So for instance, one could get the following information about the hermitian space $H$:


julia> K, a = cyclotomic_real_subfield(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 - from relative number field of degree 2 over maximal real subfield of cyclotomic field of order 7 - to 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.

source
is_quadraticMethod
is_quadratic(V::AbstractSpace) -> Bool

Return whether the space V is quadratic.

source
is_hermitianMethod
is_hermitian(V::AbstractSpace) -> Bool

Return whether the space V is hermitian.

source
is_positive_definiteMethod
is_positive_definite(V::AbstractSpace) -> Bool

Return whether the space V is positive definite.

source
is_negative_definiteMethod
is_negative_definite(V::AbstractSpace) -> Bool

Return whether the space V is negative definite.

source
is_definiteMethod
is_definite(V::AbstractSpace) -> Bool

Return whether the space V is definite.

source

Note that the is_hermitian function tests whether the space is non-quadratic.

Examples


julia> K, a = cyclotomic_real_subfield(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), is_hermitian(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.

source
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.

source
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.

source
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.

source
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.

source
diagonal_with_transformMethod
diagonal_with_transform(V::AbstractSpace) -> Vector{FieldElem},
-                                                         MatElem{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 second output is a matrix U whose rows span an orthogonal basis of V for which the Gram matrix is given by the diagonal matrix of the $a_i$'s.

The elements are contained in the fixed field of V.

source
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$.

source

Examples


julia> K, a = cyclotomic_real_subfield(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)(AbsSimpleNumFieldElem[1, -1], AbsSimpleNumFieldElem[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, AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}}) -> 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).

source
witt_invariantMethod
witt_invariant(V::QuadSpace, p::Union{InfPlc, AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}}) -> Int

Returns the Witt invariant of the quadratic space V at p.

See [Definition 3.2.1, Kir16].

source
is_isometricMethod
is_isometric(L::AbstractSpace, M::AbstractSpace) -> Bool

Return whether the spaces L and M are isometric.

source
is_isometricMethod
is_isometric(L::AbstractSpace, M::AbstractSpace, p::Union{InfPlc, AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}}) -> Bool

Return whether the spaces L and M are isometric over the completion at p.

source
invariantsMethod
invariants(M::QuadSpace)
-      -> FieldElem, Dict{AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}, 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.

source

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 = cyclotomic_real_subfield(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{AbsSimpleNumFieldOrderIdeal, Int64}(), Tuple{InfPlc{AbsSimpleNumField, AbsSimpleNumFieldEmbedding}, 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::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}) 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$.

source
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.

source

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 = cyclotomic_real_subfield(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(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).

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

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

source
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(algebras::StructureConstantAlgebra...; task::Symbol = :sum)
-  -> StructureConstantAlgebra, Vector{AbsAlgAssMor}, Vector{AbsAlgAssMor}
-direct_product(algebras::Vector{StructureConstantAlgebra}; task::Symbol = :sum)
-  -> StructureConstantAlgebra, 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.

source
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).

source
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
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).

source

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: hermitian space -> hermitian space, Map: hermitian space -> hermitian space], AbstractSpaceMor[Map: hermitian space -> hermitian space, Map: hermitian space -> hermitian space])
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.

source
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.

source

Example


julia> K, a = cyclotomic_real_subfield(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{AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}, 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.

source

Example


julia> K, a = cyclotomic_real_subfield(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::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}) -> Bool

Return whether the completion of the hermitian space V over $E/K$ at the prime ideal p of $\mathcal O_K$ is hyperbolic.

source

Example


julia> K, a = cyclotomic_real_subfield(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/PR4245/Hecke/manual/quad_forms/discriminant_group/index.html b/previews/PR4245/Hecke/manual/quad_forms/discriminant_group/index.html deleted file mode 100644 index c8454a97ace5..000000000000 --- a/previews/PR4245/Hecke/manual/quad_forms/discriminant_group/index.html +++ /dev/null @@ -1,196 +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::RationalUnion = QQFieldElem(0),
-                                             modulus_qf::RationalUnion = 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.

One can decide on the modulus for the associated finite bilinear and quadratic forms by setting modulus and modulus_qf respectively to the desired values.

source

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)
-(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(basis_matrix(M), v; side = :left).

source

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) -> FinGenAbGroup

Return the underlying abelian group of T.

source
coverMethod
cover(T::TorQuadModule) -> ZZLat

For $T=M/N$ this returns $M$.

source
relationsMethod
relations(T::TorQuadModule) -> ZZLat

For $T=M/N$ this returns $N$.

source
value_moduleMethod
value_module(T::TorQuadModule) -> QmodnZ

Return the value module Q/nZ of the bilinear form of T.

source
gram_matrix_bilinearMethod
gram_matrix_bilinear(T::TorQuadModule) -> QQMatrix

Return the gram matrix of the bilinear form of T.

source
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.

source
modulus_bilinear_formMethod
modulus_bilinear_form(T::TorQuadModule) -> QQFieldElem

Return the modulus of the value module of the bilinear form ofT.

source
modulus_quadratic_formMethod
modulus_quadratic_form(T::TorQuadModule) -> QQFieldElem

Return the modulus of the value module of the quadratic form of T.

source

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}$.

source
inner_productMethod
inner_product(a::TorQuadModuleElem, b::TorQuadModuleElem) -> QmodnZElem

Return the inner product of a and b.

source

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$.

source
representativeMethod
representative(a::TorQuadModuleElem) -> Vector{QQFieldElem}

For $a + N \in M/N$ this returns the representative $a$. An alias for lift(a).

source

Orthogonal submodules

orthogonal_submoduleMethod
orthogonal_submodule(T::TorQuadModule, S::TorQuadModule)-> TorQuadModule

Return the orthogonal submodule to the submodule S of T.

source

Isometry

is_isometric_with_isometryMethod
is_isometric_with_isometry(T::TorQuadModule, U::TorQuadModule)
-                                               -> Bool, TorQuadModuleMap

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: finite quadratic module -> finite quadratic module)
-
-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: finite quadratic module -> finite quadratic module)
-
-julia> U2, _ = sub(T, [T[4], T[2]+T[3]+T[5]])
-(Finite quadratic module: (Z/3)^2 -> Q/2Z, Map: finite quadratic module -> finite quadratic module)
-
-julia> bool, phi = is_isometric_with_isometry(U2, T2)
-(true, Map: finite quadratic module -> finite quadratic module)
-
-julia> is_bijective(phi)
-true
source
is_anti_isometric_with_anti_isometryMethod
is_anti_isometric_with_anti_isometry(T::TorQuadModule, U::TorQuadModule)
-                                                 -> Bool, TorQuadModuleMap

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: finite quadratic module -> finite quadratic module)
-
-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: finite quadratic module -> finite quadratic module)
-
-julia> a = gens(T)[1];
-
-julia> a*a == -phi(a)*phi(a)
-true
source

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.

source
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.

source
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.

source
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.

source

Smith normal form

snfMethod
snf(T::TorQuadModule) -> TorQuadModule, TorQuadModuleMap

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$.

source
is_snfMethod
is_snf(T::TorQuadModule) -> Bool

Given a torsion quadratic module T, return whether its underlying abelian group is in Smith normal form.

source

Discriminant Groups

See [Nik79] 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}$.

source

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]
source

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.

source

Invariants

is_degenerateMethod
is_degenerate(T::TorQuadModule) -> Bool

Return true if the underlying bilinear form is degenerate.

source
radical_bilinearMethod
radical_bilinear(T::TorQuadModule) -> TorQuadModule, TorQuadModuleMap

Return the radical \{x \in T | b(x,T) = 0\} of the bilinear form b on T.

source
radical_quadraticMethod
radical_quadratic(T::TorQuadModule) -> TorQuadModule, TorQuadModuleMap

Return the radical \{x \in T | b(x,T) = 0 and q(x)=0\} of the quadratic form q on T.

source
normal_formMethod
normal_form(T::TorQuadModule; partial=false) -> TorQuadModule, TorQuadModuleMap

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.

source

Genus

genusMethod
genus(T::TorQuadModule, signature_pair::Tuple{Int, Int};
-                        parity::RationalUnion = modulus_quadratic_form(T))
-                                                                -> ZZGenus

Return the genus of an integer lattice whose discriminant group has the bilinear form of T, the given signature_pair and the given parity.

The argument parity is one of the following: either parity == 1 for genera of odd lattices, or parity == 2 for even lattices. By default, parity is set to be as the parity of the quadratic form on T

If no such genus exists, raise an error.

Reference

[Nik79] Corollary 1.9.4 and 1.16.3.

source
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
source
is_genusMethod
is_genus(T::TorQuadModule, signature_pair::Tuple{Int, Int};
-                           parity::RationalUnion = modulus_quadratic_form(T)) -> Bool

Return if there is an integral lattice whose discriminant form has the bilinear form of T, whose signatures match signature_pair and which is of parity parity.

The argument parity is one of the following: either parity == 1 for genera of odd lattices, or parity == 2 for even lattices. By default, parity is set to be as the parity of the quadratic form on T

source

Categorical constructions

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

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).

source
direct_productMethod
direct_product(x::Vararg{TorQuadModule}) -> TorQuadModule, Vector{TorQuadModuleMap}
-direct_product(x::Vector{TorQuadModule}) -> TorQuadModule, Vector{TorQuadModuleMap}

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).

source
biproductMethod
biproduct(x::Vararg{TorQuadModule}) -> TorQuadModule, Vector{TorQuadModuleMap}, Vector{TorQuadModuleMap}
-biproduct(x::Vector{TorQuadModule}) -> TorQuadModule, Vector{TorQuadModuleMap}, Vector{TorQuadModuleMap}

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).

source

Submodules

submodulesMethod
submodules(T::TorQuadModule; 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).
source
stable_submodulesMethod
stable_submodules(T::TorQuadModule, act::Vector{TorQuadModuleMap}; 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).
source
diff --git a/previews/PR4245/Hecke/manual/quad_forms/genusherm/index.html b/previews/PR4245/Hecke/manual/quad_forms/genusherm/index.html deleted file mode 100644 index 4960e5e044c6..000000000000 --- a/previews/PR4245/Hecke/manual/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::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}, 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::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}) -> 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.RelSimpleNumFieldElem{AbsSimpleNumFieldElem}}[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.

source
base_fieldMethod
base_field(g::HermLocalGenus) -> NumField

Given a local genus symbol g for hermitian lattices over $E/K$, return E.

source
primeMethod
prime(g::HermLocalGenus) -> AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}

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$.

source

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$.

source
scaleMethod
scale(g::HermLocalGenus) -> AbsSimpleNumFieldOrderFractionalIdeal

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$.

source
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$.

source
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.

source
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.

source
ranksMethod
ranks(g::HermLocalGenus) -> Vector{Int}

Given a local genus symbol g for hermitian lattices, return the ranks of the Jordan blocks of g.

source
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.

source
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.

source
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.

source
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.

source
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.

source
normMethod
norm(g::HermLocalGenus, i::Int) -> 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 $\mathfrak p$-valuation of the norm of the ith Jordan block of g.

source
normMethod
norm(g::HermLocalGenus) -> AbsSimpleNumFieldOrderFractionalIdeal

Return the norm of g, i.e. the norm of any of its representatives.

Given a local genus symbol g of hermitian lattices over $E/K$ at a prime ideal $\mathfrak p$ of $\mathcal O_K$, it norm is computed as the norm of the Jordan block of minimum $\mathfrak p$-valuation.

source
normsMethod
norms(g::HermLocalGenus) -> Vector{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 $\mathfrak p$-valuations of the norms of the Jordan blocks of g.

source

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.RelSimpleNumFieldElem{AbsSimpleNumFieldElem}}[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$.

source
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$.

source
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$.

source
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.

source

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.

source

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}$.

source
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}$.

source

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 + 10
julia> det_representative(g1,2)8*a + 10

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.

source
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.

source

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.RelSimpleNumFieldElem{AbsSimpleNumFieldElem}}[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.RelSimpleNumField{AbsSimpleNumFieldElem}, RelSimpleNumFieldEmbedding{AbsSimpleNumFieldEmbedding, Hecke.RelSimpleNumField{AbsSimpleNumFieldElem}}}}: - 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.RelSimpleNumFieldElem{AbsSimpleNumFieldElem}}[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.

source
primesMethod
primes(G::HermGenus) -> Vector{AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}}

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.

source
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.

source
rankMethod
rank(G::HermGenus) -> Int

Return the rank of any hermitian lattice with global genus symbol G.

source
is_integralMethod
is_integral(G::HermGenus) -> Bool

Return whether G defines a genus of integral hermitian lattices.

source
local_symbolsMethod
local_symbols(G::HermGenus) -> Vector{HermLocalGenus}

Given a global genus symbol of hermitian lattices, return its associated local genus symbols.

source
scaleMethod
scale(G::HermGenus) -> AbsSimpleNumFieldOrderFractionalIdeal

Return the scale ideal of any hermitian lattice with global genus symbol G.

source
normMethod
norm(G::HermGenus) -> AbsSimpleNumFieldOrderFractionalIdeal

Return the norm ideal of any hermitian lattice with global genus symbol G.

source

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.RelSimpleNumFieldElem{AbsSimpleNumFieldElem}}[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{AbsSimpleNumFieldOrderIdeal}: - <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{AbsSimpleNumField, AbsSimpleNumFieldEmbedding}, 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.

source

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.RelSimpleNumFieldElem{AbsSimpleNumFieldElem}}[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.

source
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$.

source
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.

source
inMethod
in(L::HermLat, G::HermGenus) -> Bool

Return whether G and the global genus symbol of the hermitian lattice L agree.

source
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.

source
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.

source

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.

source
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.

source

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.RelSimpleNumFieldElem{AbsSimpleNumFieldElem}}[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::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}, 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.

source
hermitian_generaMethod
hermitian_genera(E::NumField, rank::Int,
-                              signatures::Dict{InfPlc, Int},
-                              determinant::Union{Hecke.RelNumFieldOrderIdeal, Hecke.RelNumFieldOrderFractionalIdeal};
-                              min_scale::Union{Hecke.RelNumFieldOrderIdeal, Hecke.RelNumFieldOrderFractionalIdeal} = is_integral(determinant) ? inv(1*order(determinant)) : determinant,
-                              max_scale::Union{Hecke.RelNumFieldOrderIdeal, Hecke.RelNumFieldOrderFractionalIdeal} = 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.

source

Examples


julia> K, a = cyclotomic_real_subfield(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.RelSimpleNumField{AbsSimpleNumFieldElem}, AbsSimpleNumFieldOrderIdeal}}: - 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.RelSimpleNumField{AbsSimpleNumFieldElem}, AbsSimpleNumFieldOrderIdeal, HermLocalGenus{Hecke.RelSimpleNumField{AbsSimpleNumFieldElem}, AbsSimpleNumFieldOrderIdeal}, Dict{InfPlc{AbsSimpleNumField, AbsSimpleNumFieldEmbedding}, 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.

source
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.

source
diff --git a/previews/PR4245/Hecke/manual/quad_forms/integer_lattices/index.html b/previews/PR4245/Hecke/manual/quad_forms/integer_lattices/index.html deleted file mode 100644 index d4388132cc41..000000000000 --- a/previews/PR4245/Hecke/manual/quad_forms/integer_lattices/index.html +++ /dev/null @@ -1,412 +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
source

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.

source

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.

The type :I with parameter n = 1 is also allowed and denotes the odd unimodular lattice of rank 1.

source
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]
source
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.

source
leech_latticeFunction
leech_lattice() -> ZZLat

Return the Leech lattice.

source
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 [CS99].

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(Hecke.kernel(vG; side = :right)))*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
-
source
k3_latticeFunction
k3_lattice()

Return the integer lattice corresponding to the Beauville-Bogomolov-Fujiki form associated to a K3 surface.

Examples

julia> L = k3_lattice();
-
-julia> is_unimodular(L)
-true
-
-julia> signature_tuple(L)
-(3, 0, 19)
source
mukai_latticeMethod
mukai_lattice(S::Symbol = :K3; extended::Bool = false)

Return the (extended) Mukai lattice.

If S == :K3, it returns the (extended) Mukai lattice associated to hyperkaehler manifolds which are deformation equivalent to a moduli space of stable sheaves on a K3 surface.

If S == :Ab, it returns the (extended) Mukai lattice associated to hyperkaehler manifolds which are deformation equivalent to a moduli space of stable sheaves on an abelian surface.

Examples

julia> L = mukai_lattice();
-
-julia> genus(L)
-Genus symbol for integer lattices
-Signatures: (4, 0, 20)
-Local symbol:
-  Local genus symbol at 2: 1^24
-
-julia> L = mukai_lattice(; extended = true);
-
-julia> genus(L)
-Genus symbol for integer lattices
-Signatures: (5, 0, 21)
-Local symbol:
-  Local genus symbol at 2: 1^26
-
-julia> L = mukai_lattice(:Ab);
-
-julia> genus(L)
-Genus symbol for integer lattices
-Signatures: (4, 0, 4)
-Local symbol:
-  Local genus symbol at 2: 1^8
-
-julia> L = mukai_lattice(:Ab; extended = true);
-
-julia> genus(L)
-Genus symbol for integer lattices
-Signatures: (5, 0, 5)
-Local symbol:
-  Local genus symbol at 2: 1^10
source
hyperkaehler_latticeMethod
hyperkaehler_lattice(S::Symbol; n::Int = 2)

Return the integer lattice corresponding to the Beauville-Bogomolov-Fujiki form on a hyperkaehler manifold whose deformation type is determined by S and n.

  • If S == :K3 or S == :Kum, then n must be an integer bigger than 2;
  • If S == :OG6 or S == :OG10, the value of n has no effect.

Examples

julia> L = hyperkaehler_lattice(:Kum; n = 3)
-Integer lattice of rank 7 and degree 7
-with gram matrix
-[0   1   0   0   0   0    0]
-[1   0   0   0   0   0    0]
-[0   0   0   1   0   0    0]
-[0   0   1   0   0   0    0]
-[0   0   0   0   0   1    0]
-[0   0   0   0   1   0    0]
-[0   0   0   0   0   0   -8]
-
-julia> L = hyperkaehler_lattice(:OG6)
-Integer lattice of rank 8 and degree 8
-with gram matrix
-[0   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   1   0   0   0    0    0]
-[0   0   0   0   0   1    0    0]
-[0   0   0   0   1   0    0    0]
-[0   0   0   0   0   0   -2    0]
-[0   0   0   0   0   0    0   -2]
-
-julia> L = hyperkaehler_lattice(:OG10);
-
-julia> genus(L)
-Genus symbol for integer lattices
-Signatures: (3, 0, 21)
-Local symbols:
-  Local genus symbol at 2: 1^-24
-  Local genus symbol at 3: 1^-23 3^1
-
-julia> L = hyperkaehler_lattice(:K3; n = 3);
-
-julia> genus(L)
-Genus symbol for integer lattices
-Signatures: (3, 0, 20)
-Local symbol:
-  Local genus symbol at 2: 1^22 4^1_7
source

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]
source

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.

source
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$.

source
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]
source
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]
source

Invariants

rankMethod
rank(L::AbstractLat) -> Int

Return the rank of the underlying module of the lattice L.

source
detMethod
det(L::ZZLat) -> QQFieldElem

Return the determinant of the gram matrix of L.

source
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\}$.

source
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\}$.

source
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$.

source
is_integralMethod
is_integral(L::AbstractLat) -> Bool

Return whether the lattice L is integral.

source
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.

source
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.

source
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.

source
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.

source

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.

source
genus_representativesMethod
genus_representatives(L::ZZLat) -> Vector{ZZLat}

Return representatives for the isometry classes in the genus of L.

source

Real invariants

signature_tupleMethod
signature_tuple(L::ZZLat) -> Tuple{Int,Int,Int}

Return the number of (positive, zero, negative) inertia of L.

source
is_positive_definiteMethod
is_positive_definite(L::AbstractLat) -> Bool

Return whether the rational span of the lattice L is positive definite.

source
is_negative_definiteMethod
is_negative_definite(L::AbstractLat) -> Bool

Return whether the rational span of the lattice L is negative definite.

source
is_definiteMethod
is_definite(L::AbstractLat) -> Bool

Return whether the rational span of the lattice L is definite.

source

Isometries

automorphism_group_generatorsMethod
automorphism_group_generators(E::EllipticCurve) -> Vector{EllCrvIso}

Return generators of the automorphism group of $E$.

source
automorphism_group_generators(L::AbstractLat; ambient_representation::Bool = true,
-                                              depth::Int = -1, bacher_depth::Int = 0)
-                                                      -> 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.

Setting the parameters depth and bacher_depth to a positive value may improve performance. If set to -1 (default), the used value of depth is chosen heuristically depending on the rank of L. By default, bacher_depth is set to 0.

source
automorphism_group_orderMethod
automorphism_group_order(L::AbstractLat; depth::Int = -1, bacher_depth::Int = 0) -> Int

Given a definite lattice L, return the order of the automorphism group of L.

Setting the parameters depth and bacher_depth to a positive value may improve performance. If set to -1 (default), the used value of depth is chosen heuristically depending on the rank of L. By default, bacher_depth is set to 0.

source
is_isometricMethod
is_isometric(L::AbstractLat, M::AbstractLat; depth::Int = -1, bacher_depth::Int = 0) -> Bool

Return whether the lattices L and M are isometric.

Setting the parameters depth and bacher_depth to a positive value may improve performance. If set to -1 (default), the used value of depth is chosen heuristically depending on the rank of L. By default, bacher_depth is set to 0.

source
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$.

source

Root lattices

root_lattice_recognitionMethod
root_lattice_recognition(L::ZZLat)

Return the ADE type of the root sublattice of L.

The root sublattice is the lattice spanned by the vectors of squared length $1$ and $2$. The odd lattice of rank 1 and determinant $1$ is denoted by (:I, 1).

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])
-
-julia> L = integer_lattice(; gram = QQ[1 0 0  0;
-                                       0 9 3  3;
-                                       0 3 2  1;
-                                       0 3 1 11])
-Integer lattice of rank 4 and degree 4
-with gram matrix
-[1   0   0    0]
-[0   9   3    3]
-[0   3   2    1]
-[0   3   1   11]
-
-julia> root_lattice_recognition(L)
-([(:A, 1), (:I, 1)], ZZLat[Integer lattice of rank 1 and degree 4, Integer lattice of rank 1 and degree 4])
source
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.

The type (:I, 1) corresponds to the odd unimodular root lattice of rank 1.

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]
-
source
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)
source
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
-
source
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]
source

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.

source
is_sublatticeMethod
is_sublattice(L::AbstractLat, M::AbstractLat) -> Bool

Return whether M is a sublattice of the lattice L.

source
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.

source
+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.

source
*Method
*(a::RationalUnion, L::ZZLat) -> ZZLat

Return the lattice $aM$ inside the ambient space of $M$.

source
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.

source
inMethod
Base.in(v::Vector, L::ZZLat) -> Bool

Return whether the vector v lies in the lattice L.

source
inMethod
Base.in(v::QQMatrix, L::ZZLat) -> Bool

Return whether the row span of v lies in the lattice L.

source
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: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
-
source
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:1,:], bU[2: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
source
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$.

source
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)$.

source

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).

source
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).

source
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).

source

Orthogonal sublattices

orthogonal_submoduleMethod
orthogonal_submodule(L::ZZLat, S::ZZLat) -> ZZLat

Return the largest submodule of $L$ orthogonal to $S$.

source
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.\]

source

Dual lattice

dualMethod
dual(L::AbstractLat) -> AbstractLat

Return the dual lattice of the lattice L.

source

Discriminant group

See discriminant_group(L::ZZLat).

Overlattices

glue_mapMethod
glue_map(L::ZZLat, S::ZZLat, R::ZZLat; check=true)
-                       -> Tuple{TorQuadModuleMap, TorQuadModuleMap, TorQuadModuleMap}

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: finite quadratic module -> finite quadratic module, Map: finite quadratic module -> finite quadratic module, Map: finite quadratic module -> finite quadratic module)
-
-julia> is_bijective(glue)
-true
source
overlatticeMethod
overlattice(glue_map::TorQuadModuleMap) -> 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
source
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.

source
maximal_integral_latticeMethod
maximal_integral_lattice(L::AbstractLat) -> AbstractLat

Given a lattice L with integral norm, return a maximal integral overlattice M of L.

source

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$.

source
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$.

source
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$.

source

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);
-
source
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
source

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.

source

Short Vectors

short_vectorsFunction
short_vectors(L::ZZLat, [lb = 0], ub, [elem_type = ZZRingElem]; check::Bool = true)
-                                   -> Vector{Tuple{Vector{elem_type}, QQFieldElem}}

Return 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 definite.

See also short_vectors_iterator for an iterator version.

source
shortest_vectorsFunction
shortest_vectors(L::ZZLat, [elem_type = ZZRingElem]; check::Bool = true)
-                                           -> QQFieldElem, Vector{elem_type}, QQFieldElem}

Return the list of shortest non-zero vectors in absolute value. 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 definite.

See also minimum.

source
short_vectors_iteratorFunction
short_vectors_iterator(L::ZZLat, [lb = 0], ub,
-                       [elem_type = ZZRingElem]; check::Bool = true)
-                                -> Tuple{Vector{elem_type}, QQFieldElem} (iterator)

Return 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 definite.

See also short_vectors.

source
minimumMethod
minimum(L::ZZLat) -> QQFieldElem

Return the minimum absolute squared length among the non-zero vectors in L.

source
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.

source

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)
source

diff --git a/previews/PR4245/Hecke/manual/quad_forms/introduction/index.html b/previews/PR4245/Hecke/manual/quad_forms/introduction/index.html deleted file mode 100644 index c43688dca198..000000000000 --- a/previews/PR4245/Hecke/manual/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/PR4245/Hecke/manual/quad_forms/lattices/index.html b/previews/PR4245/Hecke/manual/quad_forms/lattices/index.html deleted file mode 100644 index ae181687d56a..000000000000 --- a/previews/PR4245/Hecke/manual/quad_forms/lattices/index.html +++ /dev/null @@ -1,260 +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.

source
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.

source
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.

source
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.

source

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}$.

source
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.

source
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}$.

source
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}$.

source

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.

source
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.

source
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.

source
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.

source

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{AbsSimpleNumFieldElem}[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 AbsSimpleNumFieldElem[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.RelSimpleNumFieldElem{AbsSimpleNumFieldElem}}[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.RelSimpleNumFieldElem{AbsSimpleNumFieldElem}}[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.RelSimpleNumFieldElem{AbsSimpleNumFieldElem}}[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 AbsSimpleNumFieldElem[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.

source
rational_spanMethod
rational_span(L::AbstractLat) -> AbstractSpace

Return the rational span of the lattice L.

source

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{AbsSimpleNumFieldElem}[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.RelSimpleNumFieldElem{AbsSimpleNumFieldElem}}[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{AbsSimpleNumFieldElem}: - 2 - 2 - 2

Rational equivalence

hasse_invariantMethod
hasse_invariant(L::AbstractLat, p::Union{InfPlc, AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}}) -> Int

Return the Hasse invariant of the rational span of the lattice L at the place p. The lattice must be quadratic.

source
witt_invariantMethod
witt_invariant(L::AbstractLat, p::Union{InfPlc, AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}}) -> Int

Return the Witt invariant of the rational span of the lattice L at the place p. The lattice must be quadratic.

source
is_rationally_isometricMethod
is_rationally_isometric(L::AbstractLat, M::AbstractLat, p::Union{InfPlc, AbsNumFieldOrderIdeal})
-                                                                     -> Bool

Return whether the rational spans of the lattices L and M are isometric over the completion at the place p.

source
is_rationally_isometricMethod
is_rationally_isometric(L::AbstractLat, M::AbstractLat) -> Bool

Return whether the rational spans of the lattices L and M are isometric.

source

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{AbsSimpleNumFieldElem}[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{AbsSimpleNumFieldElem}[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 AbsSimpleNumFieldElem[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.

source
degreeMethod
degree(L::AbstractLat) -> Int

Return the dimension of the ambient space of the lattice L.

source
discriminantMethod
discriminant(L::AbstractLat) -> AbsSimpleNumFieldOrderFractionalIdeal

Return the discriminant of the lattice L, that is, the generalized index ideal $[L^\# : L]$.

source
base_fieldMethod
base_field(L::AbstractLat) -> Field

Return the algebra over which the rational span of the lattice L is defined.

source
base_ringMethod
base_ring(L::AbstractLat) -> Ring

Return the order over which the lattice L is defined.

source
fixed_fieldMethod
fixed_field(L::AbstractLat) -> Field

Returns the fixed field of the involution of the lattice L.

source
fixed_ringMethod
fixed_ring(L::AbstractLat) -> Ring

Return the maximal order in the fixed field of the lattice L.

source
involutionMethod
involution(L::AbstractLat) -> Map

Return the involution of the rational span of the lattice L.

source
pseudo_matrixMethod
pseudo_matrix(L::AbstractLat) -> PMat

Return a basis pseudo-matrix of the lattice L.

source
pseudo_basisMethod
pseudo_basis(L::AbstractLat) -> Vector{Tuple{Vector, Ideal}}

Return a pseudo-basis of the lattice L.

source
coefficient_idealsMethod
coefficient_ideals(L::AbstractLat) -> Vector{AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}}

Return the coefficient ideals of a pseudo-basis of the lattice L.

source
absolute_basis_matrixMethod
absolute_basis_matrix(L::AbstractLat) -> MatElem

Return a $\mathbf{Z}$-basis matrix of the lattice L.

source
absolute_basisMethod
absolute_basis(L::AbstractLat) -> Vector

Return a $\mathbf{Z}$-basis of the lattice L.

source
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.

source
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.

source

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.RelSimpleNumFieldElem{AbsSimpleNumFieldElem}}[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 AbsSimpleNumFieldElem[1]
julia> involution(Lherm)Map - from relative number field of degree 2 over number field - to 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.RelSimpleNumFieldElem{AbsSimpleNumFieldElem}}, Hecke.RelNumFieldOrderFractionalIdeal{AbsSimpleNumFieldElem, AbsSimpleNumFieldOrderFractionalIdeal, Hecke.RelSimpleNumFieldElem{AbsSimpleNumFieldElem}}}}: - ([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.RelNumFieldOrderFractionalIdeal{AbsSimpleNumFieldElem, AbsSimpleNumFieldOrderFractionalIdeal, Hecke.RelSimpleNumFieldElem{AbsSimpleNumFieldElem}}}: - 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.RelSimpleNumFieldElem{AbsSimpleNumFieldElem}}}: - [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.RelSimpleNumFieldElem{AbsSimpleNumFieldElem}}}: - [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.

source
*Method
*(a::NumFieldElem, L::AbstractLat) -> AbstractLat

Return the lattice $aL$ inside the ambient space of the lattice L.

source
*Method
*(a::NumFieldOrderIdeal, L::AbstractLat) -> AbstractLat

Return the lattice $aL$ inside the ambient space of the lattice L.

source
*Method
*(a::NumFieldOrderFractionalIdeal, L::AbstractLat) -> AbstractLat

Return the lattice $aL$ inside the ambient space of the lattice L.

source
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.

source
dualMethod
dual(L::AbstractLat) -> AbstractLat

Return the dual lattice of the lattice L.

source
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.

source
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).

source
orthogonal_submoduleMethod
orthogonal_submodule(L::AbstractLat, M::AbstractLat) -> AbstractLat

Return the largest submodule of L orthogonal to M.

source

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{AbsSimpleNumFieldElem}[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{AbsSimpleNumFieldElem}[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 AbsSimpleNumFieldElem[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 AbsSimpleNumFieldElem[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 AbsSimpleNumFieldElem[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 AbsSimpleNumFieldElem[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(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).

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

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

source
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(algebras::StructureConstantAlgebra...; task::Symbol = :sum)
-  -> StructureConstantAlgebra, Vector{AbsAlgAssMor}, Vector{AbsAlgAssMor}
-direct_product(algebras::Vector{StructureConstantAlgebra}; task::Symbol = :sum)
-  -> StructureConstantAlgebra, 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.

source
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).

source
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
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).

source

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) -> AbsNumFieldOrderFractionalIdeal

Return the norm of the lattice L. This is a fractional ideal of the fixed field of L.

source
scaleMethod
scale(L::AbstractLat) -> AbsSimpleNumFieldOrderFractionalIdeal

Return the scale of the lattice L.

source
volumeMethod
volume(L::AbstractLat) -> AbsSimpleNumFieldOrderFractionalIdeal

Return the volume of the lattice L.

source

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.RelSimpleNumFieldElem{AbsSimpleNumFieldElem}}[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.

source
is_modularMethod
is_modular(L::AbstractLat) -> Bool, AbsSimpleNumFieldOrderFractionalIdeal

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.

source
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.

source
is_positive_definiteMethod
is_positive_definite(L::AbstractLat) -> Bool

Return whether the rational span of the lattice L is positive definite.

source
is_negative_definiteMethod
is_negative_definite(L::AbstractLat) -> Bool

Return whether the rational span of the lattice L is negative definite.

source
is_definiteMethod
is_definite(L::AbstractLat) -> Bool

Return whether the rational span of the lattice L is definite.

source
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.

source

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.RelSimpleNumFieldElem{AbsSimpleNumFieldElem}}[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::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}; 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.
source
jordan_decompositionMethod
jordan_decomposition(L::AbstractLat, p::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem})
-                            -> 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$.

source
is_isotropicMethod
is_isotropic(L::AbstractLat, p::Union{AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}, InfPlc}) -> Bool

Return whether the completion of the lattice L at the place p is isotropic.

source

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{AbsSimpleNumFieldElem}[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{AbsSimpleNumFieldElem}[[1 0 0; 0 1 0; 0 0 1]], AbstractAlgebra.Generic.MatSpaceElem{AbsSimpleNumFieldElem}[[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; depth::Int = -1, bacher_depth::Int = 0) -> Int

Given a definite lattice L, return the order of the automorphism group of L.

Setting the parameters depth and bacher_depth to a positive value may improve performance. If set to -1 (default), the used value of depth is chosen heuristically depending on the rank of L. By default, bacher_depth is set to 0.

source
automorphism_group_generatorsMethod
automorphism_group_generators(L::AbstractLat; ambient_representation::Bool = true,
-                                              depth::Int = -1, bacher_depth::Int = 0)
-                                                      -> 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.

Setting the parameters depth and bacher_depth to a positive value may improve performance. If set to -1 (default), the used value of depth is chosen heuristically depending on the rank of L. By default, bacher_depth is set to 0.

source

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{AbsSimpleNumFieldElem}[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{AbsSimpleNumFieldElem}}: - [-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; depth::Int = -1, bacher_depth::Int = 0) -> Bool

Return whether the lattices L and M are isometric.

Setting the parameters depth and bacher_depth to a positive value may improve performance. If set to -1 (default), the used value of depth is chosen heuristically depending on the rank of L. By default, bacher_depth is set to 0.

source
is_isometric_with_isometryMethod
is_isometric_with_isometry(L::AbstractLat, M::AbstractLat; ambient_representation::Bool = true
-                                                           depth::Int = -1, bacher_depth::Int = 0)
-                                                          -> (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.

Setting the parameters depth and bacher_depth to a positive value may improve performance. If set to -1 (default), the used value of depth is chosen heuristically depending on the rank of L. By default, bacher_depth is set to 0.

source
is_locally_isometricMethod
is_locally_isometric(L::AbstractLat, M::AbstractLat, p::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}) -> Bool

Return whether the completions of the lattices L and M at the prime ideal p are isometric.

source

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{AbsSimpleNumFieldElem}[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{AbsSimpleNumFieldElem}[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::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}) -> 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 has integral norm and that L has no proper overlattice satisfying this property.

If the norm of L is not integral at p, the second output is L by default. Otherwise, either L is maximal at p and the second output is L, or the second output is a lattice M in the ambient space of L whose completion at p is a minimal overlattice of $L_p$ with integral norm.

source
is_maximal_integralMethod
is_maximal_integral(L::AbstractLat) -> Bool, AbstractLat

Given a lattice L, return whether L has integral norm and has no proper overlattice satisfying this property.

If the norm of L is not integral, the second output is L by default. Otherwise, either L is maximal and the second output is L, or the second output is a minimal overlattice M of L with integral norm.

source
is_maximalMethod
is_maximal(L::AbstractLat, p::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}) -> Bool, AbstractLat

Given a lattice L and a prime ideal p in the fixed ring $\mathcal O_K$ of L such that the norm of $L_p$ is integral, return whether L is maximal integral at p.

If L is locally maximal at p, the second output is L, otherwise it is a lattice M in the same ambient space of L whose completion at p has integral norm and is a proper overlattice of $L_p$.

source
maximal_integral_latticeMethod
maximal_integral_lattice(L::AbstractLat, p::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}) -> AbstractLat

Given a lattice L and a prime ideal p of the fixed ring $\mathcal O_K$ of L such that the norm of $L_p$ is integral, 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.

source
maximal_integral_latticeMethod
maximal_integral_lattice(L::AbstractLat) -> AbstractLat

Given a lattice L with integral norm, return a maximal integral overlattice M of L.

source
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.

source

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.RelSimpleNumFieldElem{AbsSimpleNumFieldElem}}[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.RelSimpleNumFieldElem{AbsSimpleNumFieldElem}}, Hecke.RelNumFieldOrderFractionalIdeal{AbsSimpleNumFieldElem, AbsSimpleNumFieldOrderFractionalIdeal, Hecke.RelSimpleNumFieldElem{AbsSimpleNumFieldElem}}}}: - ([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.RelSimpleNumFieldElem{AbsSimpleNumFieldElem}}, Hecke.RelNumFieldOrderFractionalIdeal{AbsSimpleNumFieldElem, AbsSimpleNumFieldOrderFractionalIdeal, Hecke.RelSimpleNumFieldElem{AbsSimpleNumFieldElem}}}}: - ([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])
julia> pseudo_basis(maximal_integral_lattice(ambient_space(Lherm)))4-element Vector{Tuple{Vector{Hecke.RelSimpleNumFieldElem{AbsSimpleNumFieldElem}}, Hecke.RelNumFieldOrderFractionalIdeal{AbsSimpleNumFieldElem, AbsSimpleNumFieldOrderFractionalIdeal, Hecke.RelSimpleNumFieldElem{AbsSimpleNumFieldElem}}}}: - ([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/PR4245/Hecke/start/index.html b/previews/PR4245/Hecke/start/index.html deleted file mode 100644 index 29797d7711a9..000000000000 --- a/previews/PR4245/Hecke/start/index.html +++ /dev/null @@ -1,4 +0,0 @@ - -Getting started · Oscar.jl

Getting started

To use Hecke, a julia version of 1.0 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")

Here is a quick example of using Hecke to define a number field and compute its class group::

julia> using Hecke
julia> Qx, x = QQ["x"];
julia> f = x^2 - 2*3*5*7;
julia> K, a = number_field(f, "a");
julia> OK = maximal_order(K);
julia> C, mC = class_group(OK);
julia> C(Z/2)^2
diff --git a/previews/PR4245/Hecke/tutorials/index.html b/previews/PR4245/Hecke/tutorials/index.html deleted file mode 100644 index 27cb1059dc5a..000000000000 --- a/previews/PR4245/Hecke/tutorials/index.html +++ /dev/null @@ -1,2 +0,0 @@ - -Tutorials · Oscar.jl
diff --git a/previews/PR4245/InvariantTheory/finite_groups/index.html b/previews/PR4245/InvariantTheory/finite_groups/index.html deleted file mode 100644 index 3f692faa9ccb..000000000000 --- a/previews/PR4245/InvariantTheory/finite_groups/index.html +++ /dev/null @@ -1,506 +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 [DK15] and [DJ98] 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 [Kin13].

We discuss the relevant OSCAR functionality below.

Creating Invariant Rings

How Finite 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)
-invariant_ring(R::MPolyDecRing, G::MatrixGroup)
-invariant_ring(R::MPolyDecRing, 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.

The polynomial ring R on which G acts can be supplied as a first argument, in case an existing ring should be used.

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 = cyclotomic_field(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
-
-julia> IRp = invariant_ring(symmetric_group(3))
-Invariant ring
-  of Sym(3)
-
-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 = cyclotomic_field(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 K
-
-julia> group(IR)
-Matrix group of degree 3
-  over cyclotomic field of order 3
-
-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 K graded by
-  x[1] -> [1]
-  x[2] -> [1]
-  x[3] -> [1]
-
-julia> x = gens(R)
-3-element Vector{MPolyDecRingElem{AbsSimpleNumFieldElem, AbstractAlgebra.Generic.MPoly{AbsSimpleNumFieldElem}}}:
- x[1]
- x[2]
- x[3]
-
-julia> is_modular(IR)
-false
-

The Reynolds Operator

reynolds_operatorMethod
reynolds_operator(IR::FinGroupInvarRing{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 = cyclotomic_field(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 K
-
-julia> R = polynomial_ring(IR)
-Multivariate polynomial ring in 3 variables over K graded by
-  x[1] -> [1]
-  x[2] -> [1]
-  x[3] -> [1]
-
-julia> x = gens(R)
-3-element Vector{MPolyDecRingElem{AbsSimpleNumFieldElem, AbstractAlgebra.Generic.MPoly{AbsSimpleNumFieldElem}}}:
- 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 prime field of characteristic 3
-
-julia> IR = invariant_ring(G)
-Invariant ring
-  of matrix group of degree 3 over GF(3)
-
-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{FqFieldElem, FqMPolyRingElem}}:
- 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::FinGroupInvarRing{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 [Sta79]. 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 = cyclotomic_field(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 S2, [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::FinGroupInvarRing, 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 = cyclotomic_field(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 K
-
-julia> basis(IR, 6)
-4-element Vector{MPolyDecRingElem{AbsSimpleNumFieldElem, AbstractAlgebra.Generic.MPoly{AbsSimpleNumFieldElem}}}:
- 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 prime field of characteristic 3
-
-julia> IR = invariant_ring(G)
-Invariant ring
-  of matrix group of degree 3 over GF(3)
-
-julia> basis(IR, 2)
-2-element Vector{MPolyDecRingElem{FqFieldElem, FqMPolyRingElem}}:
- x[1]^2 + x[2]^2
- x[3]^2
-
-julia> basis(IR, 3)
-2-element Vector{MPolyDecRingElem{FqFieldElem, FqMPolyRingElem}}:
- x[1]*x[2]*x[3]
- x[1]^2*x[3] + 2*x[2]^2*x[3]
source
basisMethod
basis(IR::FinGroupInvarRing, 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 = cyclotomic_field(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{AbsSimpleNumFieldElem, AbstractAlgebra.Generic.MPoly{AbsSimpleNumFieldElem}}}:
- 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 ] ), [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::FinGroupInvarRing, 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 = cyclotomic_field(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 K
-
-julia> B = iterate_basis(IR, 6)
-Iterator over a basis of the component of degree 6
-  of invariant ring of G
-
-julia> collect(B)
-4-element Vector{MPolyDecRingElem{AbsSimpleNumFieldElem, AbstractAlgebra.Generic.MPoly{AbsSimpleNumFieldElem}}}:
- 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 prime field of characteristic 3
-
-julia> IR = invariant_ring(G)
-Invariant ring
-  of matrix group of degree 3 over GF(3)
-
-julia> B = iterate_basis(IR, 2)
-Iterator over a basis of the component of degree 2
-  of invariant ring of G
-
-julia> collect(B)
-2-element Vector{MPolyDecRingElem{FqFieldElem, FqMPolyRingElem}}:
- x[1]^2 + x[2]^2
- x[3]^2
source
iterate_basisMethod
iterate_basis(IR::FinGroupInvarRing, 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 = cyclotomic_field(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 G
-relative to a character
-
-julia> collect(B)
-4-element Vector{MPolyDecRingElem{AbsSimpleNumFieldElem, AbstractAlgebra.Generic.MPoly{AbsSimpleNumFieldElem}}}:
- 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 S2, [1, -1])
-
-julia> B = iterate_basis(R, 3, chi)
-Iterator over a basis of the component of degree 3
-  of invariant ring of S2
-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::FinGroupInvarRing, [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 [Sta79].

Examples

julia> K, a = cyclotomic_field(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 S2, [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::FinGroupInvarRing;
-  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 [Kem99].

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 cancelation 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 cancelation. However, the default value ensure_minimality = 0 corresponds to no cancelation.

Examples

julia> K, a = cyclotomic_field(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{AbsSimpleNumFieldElem, AbstractAlgebra.Generic.MPoly{AbsSimpleNumFieldElem}}}:
- 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{AbsSimpleNumFieldElem, AbstractAlgebra.Generic.MPoly{AbsSimpleNumFieldElem}}}:
- 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::FinGroupInvarRing)

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 [DK15], enhanced by ideas from [Kin07]. In the modular case, Algorithm 3.7.5 in [DK15] is used.

Examples

julia> K, a = cyclotomic_field(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{AbsSimpleNumFieldElem, AbstractAlgebra.Generic.MPoly{AbsSimpleNumFieldElem}}}:
- 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::FinGroupInvarRing)

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
module_syzygiesMethod
module_syzygies(RG::FinGroupInvarRing)

Given an invariant ring RG over a ring R, compute a presentation of RG as a module over the subalgebra generated by a system of primary invariants. Return a module M over a ring S, a map M \to R which is onto RG by mapping the generators of M to a system of secondary invariants, and a map S \to R which is onto the subalgebra generated by the primary invariants.

source

Fundamental Systems of Invariants

fundamental_invariantsFunction
fundamental_invariants(IR::FinGroupInvarRing, 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 [Kin13] 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 [DH00] and [Sez02].

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 = cyclotomic_field(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 K
-
-julia> fundamental_invariants(IR)
-4-element Vector{MPolyDecRingElem{AbsSimpleNumFieldElem, AbstractAlgebra.Generic.MPoly{AbsSimpleNumFieldElem}}}:
- 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
- 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::FinGroupInvarRing;
-  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 [KS99], 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 = cyclotomic_field(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 K
-
-julia> affine_algebra(IR)
-(Quotient of multivariate polynomial ring by ideal (9*y1^6 + y1^3*y2^3 - 6*y1^3*y2*y3 + 3*y1^3*y4 - y2*y3*y4 + y3^3 + y4^2), Hom: quotient of multivariate polynomial ring -> graded multivariate polynomial ring)
source

Semi-invariants / relative invariants

semi_invariantsMethod
semi_invariants(IR::FinGroupInvarRing, chi::GAPGroupClassFunction)
-relative_invariants(IR::FinGroupInvarRing, 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 [Gat96] and [Sta79].

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 S2, [1, -1])
-
-julia> semi_invariants(RS2, chi)
-1-element Vector{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}:
- x[1] - x[2]
-
source
diff --git a/previews/PR4245/InvariantTheory/intro/index.html b/previews/PR4245/InvariantTheory/intro/index.html deleted file mode 100644 index 6bb739a726a3..000000000000 --- a/previews/PR4245/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 groups, tori, 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 right 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 a right action of $G$ on the graded symmetric algebra

\[K[V]:=S(V^*)=\bigoplus_{d\geq 0} S^d V^*\]

which preserves the grading.

Note

In OSCAR, group actions are by convention assumed to be right actions and we follow this convention with our definition above. Note, however, that the left action given by $\pi \;\! . \;\! f := f \circ \rho(\pi^{-1})$ is quite common in the literature.

The invariants of $G$ are the fixed points of the action defined above, 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, fixing a basis of $V$ and its dual basis, say, $\{x_1, \dots, x_n\}$ of $V^*$, we may identify $\operatorname{GL}(V) \cong \operatorname{GL}_n(K)$ and $K[V]\cong K[x_1, \dots, x_n]$. Then the action of an element $\pi \in G$ with $\rho(\pi) = (a_{i, j})$ on a polynomial $f\in K[x_1,\dots, x_n]$ is given as follows:

\[(f \;\! . \;\! \pi) (x_1, \dots, x_n) = f\bigl(\sum_j a_{1, j}x_j, \dots, \sum_j a_{n, j}x_j\bigr).\]

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/PR4245/InvariantTheory/reductive_groups/index.html b/previews/PR4245/InvariantTheory/reductive_groups/index.html deleted file mode 100644 index 55b4d422cf95..000000000000 --- a/previews/PR4245/InvariantTheory/reductive_groups/index.html +++ /dev/null @@ -1,59 +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$, $\rho: G \to \text{GL}(V)\cong \text{GL}_n(K)$ will be a rational representation of $G$, and $G$ will act on $K[V]\cong K[x_1, \dots, x_n]$ by linear substitution: If $\rho(\pi) = (a_{i, j})$, then

\[(f \;\! . \;\! \pi) (x_1, \dots, x_n) = f\bigl(\sum_j a_{1, j}x_j, \dots, \sum_j a_{n, j}x_j\bigr).\]

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 is explicitly known, generators of invariant rings of linearly reductive groups can be found in two steps using Derksen's algorithm, see [Der99] :

  • First, compute generators of Hilbert's null-cone ideal.
  • Then, apply the Reynold's operator to these generators.

See also [DK15] and [DJ98].

Creating Invariant Rings

How Linearly Reductive Groups and Their Representations are Given

For the computation of invariant rings in the above setting, 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$.
Note

Proceeding as above is not a problem: Derksen's algorithms relies on Gröbner bases techniques and means to compute Reynolds operators. It does, thus, not change the initial ground field $k$. That is, all computations are performed over $k$ and computations over any extension field of $k$ would lead to the same results.

In OSCAR, the basic set-up for a linearly reductive group in the context of Derksen's algorithm is provided by the function linearly_reductive_group. At current state, this only supports rational actions of the special linear group (in characteristic zero). For the action of this group by linear substitution on, say, $n$-ary forms of degree $d$, an explicit Reynolds operator is given by Cayley's Omega-process. We show this at work later in this section.

linearly_reductive_groupMethod
linearly_reductive_group(sym::Symbol, m::Int, K::Field)

Return the linearly reductive group indicated by sym.

Currently, the supported options for sym are:

  • :SL, corresponding to the special linear group (of degree $m$ over the field $K$).

Examples

julia> G = linearly_reductive_group(:SL, 2, QQ)
-Reductive group SL2
-  over QQ
-
-julia> group_ideal(G)
-Ideal generated by
-  z[1, 1]*z[2, 2] - z[2, 1]*z[1, 2] - 1
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
linearly_reductive_groupMethod
linearly_reductive_group(sym::Symbol, m::Int, R::MPolyRing)

Return the linearly reductive group indicated by sym.

Currently, the supported options for sym are:

  • :SL, corresponding to the special linear group (of degree $m$ over the base field $K$ of $R$, where $R$ is the polynomial ring in which the defining ideal of SL$(m, K)$ lives).

Examples

julia> S, z = polynomial_ring(QQ, :c=> (1:2, 1:2));
-
-julia> G = linearly_reductive_group(:SL,2,S)
-Reductive group SL2
-  over QQ
-
-julia> group_ideal(G)
-Ideal generated by
-  c[1, 1]*c[2, 2] - c[2, 1]*c[1, 2] - 1
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
representation_on_formsMethod
representation_on_forms(G::LinearlyReductiveGroup, d::Int)

If G is the special linear group acting by linear substitution on, say, n-ary forms of degree d, return the corresponding representation.

Note

In accordance with classical papers, an $n$-ary form of degree $d$ in $K[x_1, \dots, x_n]$ is written as a $K$-linear combination of the $K$-basis with elements $\binom{n}{I}x^I$. Here, $I = (i_1, \dots, i_n)\in\mathbb Z_{\geq 0}^n$ with $i_1+\dots +i_n =d$.

Examples

julia> G = linearly_reductive_group(:SL, 2, QQ);
-
-julia> r = representation_on_forms(G, 2)
-Representation of SL2
-  on symmetric forms of degree 2
-
-julia> representation_matrix(r)
-[      z[1, 1]^2                   2*z[1, 1]*z[2, 1]         z[2, 1]^2]
-[z[1, 1]*z[1, 2]   z[1, 1]*z[2, 2] + z[2, 1]*z[1, 2]   z[2, 1]*z[2, 2]]
-[      z[1, 2]^2                   2*z[1, 2]*z[2, 2]         z[2, 2]^2]
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source

Constructors for Invariant Rings

invariant_ringMethod
invariant_ring(r::RepresentationLinearlyReductiveGroup)

Return the invariant ring under the action defined by the representation r on an implicitly generated polynomial ring of appropriate dimension.

Examples

julia> G = linearly_reductive_group(:SL, 2, QQ);
-
-julia> r = representation_on_forms(G, 2);
-
-julia> RG = invariant_ring(r)
-Invariant Ring of
-graded multivariate polynomial ring in 3 variables over QQ
-  under group action of SL2
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
invariant_ringMethod
invariant_ring(R::MPolyDecRing, r::RepresentationLinearlyReductiveGroup)

Return the invariant subring of R under the action induced by the representation of r on R.

Examples

julia> G = linearly_reductive_group(:SL, 3, QQ);
-
-julia> r = representation_on_forms(G, 3);
-
-julia> S, x = graded_polynomial_ring(QQ, :x => 1:10);
-
-julia> RG = invariant_ring(S, r)
-Invariant Ring of
-graded multivariate polynomial ring in 10 variables over QQ
-  under group action of SL3
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source

The Reynolds Operator

reynolds_operatorMethod
reynolds_operator(RG::RedGroupInvarRing, f::MPolyRingElem)

Return the image of f under the Reynolds operator corresponding to RG.

Examples

julia> G = linearly_reductive_group(:SL, 3, QQ);
-
-julia> r = representation_on_forms(G, 3);
-
-julia> S, x = graded_polynomial_ring(QQ, :x => 1:10);
-
-julia> RG = invariant_ring(S, r);
-
-julia> 75*reynolds_operator(RG, x[5]^4)
-x[1]*x[4]*x[8]*x[10] - x[1]*x[4]*x[9]^2 - x[1]*x[5]*x[7]*x[10] + x[1]*x[5]*x[8]*x[9] + x[1]*x[6]*x[7]*x[9] - x[1]*x[6]*x[8]^2 - x[2]^2*x[8]*x[10] + x[2]^2*x[9]^2 + x[2]*x[3]*x[7]*x[10] - x[2]*x[3]*x[8]*x[9] + x[2]*x[4]*x[5]*x[10] - x[2]*x[4]*x[6]*x[9] - 2*x[2]*x[5]^2*x[9] + 3*x[2]*x[5]*x[6]*x[8] - x[2]*x[6]^2*x[7] - x[3]^2*x[7]*x[9] + x[3]^2*x[8]^2 - x[3]*x[4]^2*x[10] + 3*x[3]*x[4]*x[5]*x[9] - x[3]*x[4]*x[6]*x[8] - 2*x[3]*x[5]^2*x[8] + x[3]*x[5]*x[6]*x[7] + x[4]^2*x[6]^2 - 2*x[4]*x[5]^2*x[6] + x[5]^4
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source

Fundamental Systems of Invariants

fundamental_invariantsMethod
fundamental_invariants(RG::RedGroupInvarRing)

Return a system of fundamental invariants for RG.

Examples

julia> G = linearly_reductive_group(:SL, 2, QQ);
-
-julia> r = representation_on_forms(G, 2);
-
-julia> RG = invariant_ring(r);
-
-julia> fundamental_invariants(RG)
-1-element Vector{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}:
- -X[1]*X[3] + X[2]^2
-
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
diff --git a/previews/PR4245/InvariantTheory/tori/index.html b/previews/PR4245/InvariantTheory/tori/index.html deleted file mode 100644 index 69847db0c476..000000000000 --- a/previews/PR4245/InvariantTheory/tori/index.html +++ /dev/null @@ -1,50 +0,0 @@ - -Invariants of Tori · Oscar.jl

Invariants of Tori

In this section, with notation as in the introduction to this chapter, $T =(K^{\ast})^m$ will be a torus of rank $m$ over a field $K$. To compute invariants of diagonal torus actions, OSCAR makes use of Algorithm 4.3.1 in [DK15] which, in particular, relies on algorithmic means from polyhedral geometry.

Creating Invariant Rings

How Tori and Their Representations are Given

torus_groupMethod
torus_group(K::Field, m::Int)

Return the torus $(K^{\ast})^m$.

Note

In the context of computing invariant rings, there is no need to deal with the group structure of a torus: The torus $(K^{\ast})^m$ is specified by just giving $K$ and $m$.

Examples

julia> T = torus_group(QQ,2)
-Torus of rank 2
-  over QQ
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
rankMethod
rank(T::TorusGroup)

Return the rank of T.

Examples

julia> T = torus_group(QQ,2);
-
-julia> rank(T)
-2
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
fieldMethod
field(T::TorusGroup)

Return the field over which T is defined.

Examples

julia> T = torus_group(QQ,2);
-
-julia> field(T)
-Rational field
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
representation_from_weightsMethod
representation_from_weights(T::TorusGroup, W::Union{ZZMatrix, Matrix{<:Integer}, Vector{<:Int}})

Return the diagonal action of T with weights given by W.

Examples

julia> T = torus_group(QQ,2);
-
-julia> r = representation_from_weights(T, [-1 1; -1 1; 2 -2; 0 -1])
-Representation of torus of rank 2
-  over QQ and weights 
-  Vector{ZZRingElem}[[-1, 1], [-1, 1], [2, -2], [0, -1]]
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
groupMethod
group(r::RepresentationTorusGroup)

Return the torus group represented by r.

Examples

julia> T = torus_group(QQ,2);
-
-julia> r = representation_from_weights(T, [-1 1; -1 1; 2 -2; 0 -1]);
-
-julia> group(r)
-Torus of rank 2
-  over QQ
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source

Constructor for Invariant Rings

invariant_ringMethod
invariant_ring(r::RepresentationTorusGroup)

Return the invariant ring of the torus group represented by r.

Note

The creation of invariant rings is lazy in the sense that no explicit computations are done until specifically invoked (for example, by the fundamental_invariants function).

Examples

julia> T = torus_group(QQ,2);
-
-julia> r = representation_from_weights(T, [-1 1; -1 1; 2 -2; 0 -1]);
-
-julia> RT = invariant_ring(r)
-Invariant Ring of
-graded multivariate polynomial ring in 4 variables over QQ under group action of torus of rank2
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source

Fundamental Systems of Invariants

fundamental_invariantsMethod
fundamental_invariants(RT::TorGroupInvarRing)

Return a system of fundamental invariants for RT.

Examples

julia> T = torus_group(QQ,2);
-
-julia> r = representation_from_weights(T, [-1 1; -1 1; 2 -2; 0 -1]);
-
-julia> RT = invariant_ring(r);
-
-julia> fundamental_invariants(RT)
-3-element Vector{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}:
- X[1]^2*X[3]
- X[1]*X[2]*X[3]
- X[2]^2*X[3]
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source

Invariant Rings as Affine Algebras

affine_algebraMethod
affine_algebra(RT::TorGroupInvarRing)

Return the invariant ring RT as an affine algebra (this amounts to compute the algebra syzygies among the fundamental invariants of RT).

In addition, if A is this algebra, and R is the polynomial ring of which RT is a subalgebra, return the inclusion homomorphism A $\hookrightarrow$ R whose image is RT.

Examples

julia> T = torus_group(QQ,2);
-
-julia> r = representation_from_weights(T, [-1 1; -1 1; 2 -2; 0 -1]);
-
-julia> RT = invariant_ring(r);
-
-julia> fundamental_invariants(RT)
-3-element Vector{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}:
- X[1]^2*X[3]
- X[1]*X[2]*X[3]
- X[2]^2*X[3]
-
-julia> affine_algebra(RT)
-(Quotient of multivariate polynomial ring by ideal (-t[1]*t[3] + t[2]^2), Hom: quotient of multivariate polynomial ring -> graded multivariate polynomial ring)
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
diff --git a/previews/PR4245/LinearAlgebra/intro/index.html b/previews/PR4245/LinearAlgebra/intro/index.html deleted file mode 100644 index dee9d3f484dc..000000000000 --- a/previews/PR4245/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/PR4245/Nemo/about/index.html b/previews/PR4245/Nemo/about/index.html deleted file mode 100644 index 05a85da464e9..000000000000 --- a/previews/PR4245/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/PR4245/Nemo/acb/index.html b/previews/PR4245/Nemo/acb/index.html deleted file mode 100644 index 27ef2f7ef57d..000000000000 --- a/previews/PR4245/Nemo/acb/index.html +++ /dev/null @@ -1,204 +0,0 @@ - -Fixed precision complex balls · Oscar.jl

Fixed 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 ArbFieldElem 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)AcbFieldElemAcbField

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.

source

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{AcbFieldElem})

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::AcbFieldElem, a::AcbFieldElem, b::AcbFieldElem)

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.

deepcopy(a::AcbFieldElem)

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::ArbFieldElem)

Coerce the given Arb real ball into the Arb complex field.

R(f::AcbFieldElem)

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::AcbFieldElem) to return the parent object of a complex field element.

Basic manipulation

isfiniteMethod
isfinite(x::AcbFieldElem)

Return true if $x$ is finite, i.e. its real and imaginary parts have finite midpoint and radius, otherwise return false.

source
is_exactMethod
is_exact(x::AcbFieldElem)

Return true if $x$ is exact, i.e. has its real and imaginary parts have zero radius, otherwise return false.

source
isintegerMethod
isinteger(x::AcbFieldElem)

Return true if $x$ is an exact integer, otherwise return false.

source
accuracy_bitsMethod
accuracy_bits(x::AcbFieldElem)

Return the relative accuracy of $x$ measured in bits, capped between typemax(Int) and -typemax(Int).

source

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::AcbFieldElem, y::AcbFieldElem)

Returns true if any part of the box $x$ overlaps any part of the box $y$, otherwise return false.

source
containsMethod
contains(x::AcbFieldElem, y::AcbFieldElem)

Returns true if the box $x$ contains the box $y$, otherwise return false.

source
containsMethod
contains(x::AcbFieldElem, y::Integer)

Returns true if the box $x$ contains the given integer value, otherwise return false.

source
containsMethod
contains(x::AcbFieldElem, y::ZZRingElem)

Returns true if the box $x$ contains the given integer value, otherwise return false.

source
containsMethod
contains(x::AcbFieldElem, y::QQFieldElem)

Returns true if the box $x$ contains the given rational value, otherwise return false.

source

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::AcbFieldElem)

Returns true if the box $x$ contains zero, otherwise return false.

source

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::AcbFieldElem, y::AcbFieldElem)

Return true if the boxes $x$ and $y$ are precisely equal, i.e. their real and imaginary parts have the same midpoints and radii.

source

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::AcbFieldElem, y::Integer)
==(x::Integer, y::AcbFieldElem)
==(x::AcbFieldElem, y::ZZRingElem)
==(x::ZZRingElem, y::AcbFieldElem)
==(x::ArbFieldElem, y::ZZRingElem)
==(x::ZZRingElem, y::ArbFieldElem)
==(x::AcbFieldElem, y::Float64)
==(x::Float64, y::AcbFieldElem)

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::AcbFieldElem)

Return an AcbFieldElem box containing $x$ but which may be more economical, by rounding off insignificant bits from midpoints.

source
unique_integerMethod
unique_integer(x::AcbFieldElem)

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.

source

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$.

source

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::AcbFieldElem)

Return the reciprocal of the square root of $x$, i.e. $1/\sqrt{x}$.

source
cispiMethod
cispi(x::AcbFieldElem)

Return the exponential of $\pi i x$.

source
log_sinpiMethod
log_sinpi(x::AcbFieldElem)

Return $\log\sin(\pi x)$, constructed without branch cuts off the real line.

source
gammaMethod
gamma(x::AcbFieldElem)

Return the Gamma function evaluated at $x$.

source
lgammaMethod
lgamma(x::AcbFieldElem)

Return the logarithm of the Gamma function evaluated at $x$.

source
rgammaMethod
rgamma(x::AcbFieldElem)

Return the reciprocal of the Gamma function evaluated at $x$.

source
digammaMethod
digamma(x::AcbFieldElem)

Return the logarithmic derivative of the gamma function evaluated at $x$, i.e. $\psi(x)$.

source
zetaMethod
zeta(x::AcbFieldElem)

Return the Riemann zeta function evaluated at $x$.

source
barnes_gMethod
barnes_g(x::AcbFieldElem)

Return the Barnes $G$-function, evaluated at $x$.

source
log_barnes_gMethod
log_barnes_g(x::AcbFieldElem)

Return the logarithm of the Barnes $G$-function, evaluated at $x$.

source
erfMethod
erf(x::AcbFieldElem)

Return the error function evaluated at $x$.

source
erfiMethod
erfi(x::AcbFieldElem)

Return the imaginary error function evaluated at $x$.

source
exp_integral_eiMethod
exp_integral_ei(x::AcbFieldElem)

Return the exponential integral evaluated at $x$.

source
sin_integralMethod
sin_integral(x::AcbFieldElem)

Return the sine integral evaluated at $x$.

source
cos_integralMethod
cos_integral(x::AcbFieldElem)

Return the exponential cosine integral evaluated at $x$.

source
sinh_integralMethod
sinh_integral(x::AcbFieldElem)

Return the hyperbolic sine integral evaluated at $x$.

source
cosh_integralMethod
cosh_integral(x::AcbFieldElem)

Return the hyperbolic cosine integral evaluated at $x$.

source
dedekind_etaMethod
dedekind_eta(x::AcbFieldElem)

Return the Dedekind eta function $\eta(\tau)$ at $\tau = x$.

source
modular_weber_fMethod
modular_weber_f(x::AcbFieldElem)

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.

source
modular_weber_f1Method
modular_weber_f1(x::AcbFieldElem)

Return the modular Weber function $\mathfrak{f}_1(\tau) = \frac{\eta(\tau/2)}{\eta(\tau)},$ at $x$ in the complex upper half plane.

source
modular_weber_f2Method
modular_weber_f2(x::AcbFieldElem)

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.

source
j_invariantMethod
j_invariant(x::AcbFieldElem)

Return the $j$-invariant $j(\tau)$ at $\tau = x$.

source
modular_lambdaMethod
modular_lambda(x::AcbFieldElem)

Return the modular lambda function $\lambda(\tau)$ at $\tau = x$.

source
modular_deltaMethod
modular_delta(x::AcbFieldElem)

Return the modular delta function $\Delta(\tau)$ at $\tau = x$.

source
eisenstein_gMethod
eisenstein_g(k::Int, x::AcbFieldElem)

Return the non-normalized Eisenstein series $G_k(\tau)$ of $\mathrm{SL}_2(\mathbb{Z})$. Also defined for $\tau = i \infty$.

source
elliptic_kMethod
elliptic_k(x::AcbFieldElem)

Return the complete elliptic integral $K(x)$.

source
elliptic_eMethod
elliptic_e(x::AcbFieldElem)

Return the complete elliptic integral $E(x)$.

source
agmMethod
agm(x::AcbFieldElem)

Return the arithmetic-geometric mean of $1$ and $x$.

source
agmMethod
agm(x::AcbFieldElem, y::AcbFieldElem)

Return the arithmetic-geometric mean of $x$ and $y$.

source
polygammaMethod
polygamma(s::AcbFieldElem, a::AcbFieldElem)

Return the generalised polygamma function $\psi(s,z)$.

source
zetaMethod
zeta(s::AcbFieldElem, a::AcbFieldElem)

Return the Hurwitz zeta function $\zeta(s,a)$.

source
rising_factorialMethod
rising_factorial(x::AcbFieldElem, n::Int)

Return the rising factorial $x(x + 1)\ldots (x + n - 1)$ as an Acb.

source
rising_factorial2Method
rising_factorial2(x::AcbFieldElem, n::Int)

Return a tuple containing the rising factorial $x(x + 1)\ldots (x + n - 1)$ and its derivative.

source
polylogMethod
polylog(s::Union{AcbFieldElem,Int}, a::AcbFieldElem)

Return the polylogarithm Li$_s(a)$.

source
log_integralMethod
log_integral(x::AcbFieldElem)

Return the logarithmic integral, evaluated at $x$.

source
log_integral_offsetMethod
log_integral_offset(x::AcbFieldElem)

Return the offset logarithmic integral, evaluated at $x$.

source
exp_integral_eMethod
exp_integral_e(s::AcbFieldElem, x::AcbFieldElem)

Return the generalised exponential integral $E_s(x)$.

source
gammaMethod
gamma(s::AcbFieldElem, x::AcbFieldElem)

Return the upper incomplete gamma function $\Gamma(s,x)$.

source
gamma_regularizedMethod
gamma_regularized(s::AcbFieldElem, x::AcbFieldElem)

Return the regularized upper incomplete gamma function $\Gamma(s,x) / \Gamma(s)$.

source
gamma_lowerMethod
gamma_lower(s::AcbFieldElem, x::AcbFieldElem)

Return the lower incomplete gamma function $\gamma(s,x) / \Gamma(s)$.

source
gamma_lower_regularizedMethod
gamma_lower_regularized(s::AcbFieldElem, x::AcbFieldElem)

Return the regularized lower incomplete gamma function $\gamma(s,x) / \Gamma(s)$.

source
airy_aiMethod
airy_ai(x::AcbFieldElem)

Return the Airy function $\operatorname{Ai}(x)$.

source
airy_ai_primeMethod
airy_ai_prime(x::AcbFieldElem)

Return the derivative of the Airy function $\operatorname{Ai}^\prime(x)$.

source
airy_biMethod
airy_bi(x::AcbFieldElem)

Return the Airy function $\operatorname{Bi}(x)$.

source
airy_bi_primeMethod
airy_bi_prime(x::AcbFieldElem)

Return the derivative of the Airy function $\operatorname{Bi}^\prime(x)$.

source
bessel_jMethod
bessel_j(nu::AcbFieldElem, x::AcbFieldElem)

Return the Bessel function $J_{\nu}(x)$.

source
bessel_yMethod
bessel_y(nu::AcbFieldElem, x::AcbFieldElem)

Return the Bessel function $Y_{\nu}(x)$.

source
bessel_iMethod
bessel_i(nu::AcbFieldElem, x::AcbFieldElem)

Return the Bessel function $I_{\nu}(x)$.

source
bessel_kMethod
bessel_k(nu::AcbFieldElem, x::AcbFieldElem)

Return the Bessel function $K_{\nu}(x)$.

source
hypergeometric_1f1Method
hypergeometric_1f1(a::AcbFieldElem, b::AcbFieldElem, x::AcbFieldElem)

Return the confluent hypergeometric function ${}_1F_1(a,b,x)$.

source
hypergeometric_1f1_regularizedMethod
hypergeometric_1f1_regularized(a::AcbFieldElem, b::AcbFieldElem, x::AcbFieldElem)

Return the regularized confluent hypergeometric function ${}_1F_1(a,b,x) / \Gamma(b)$.

source
hypergeometric_uMethod
hypergeometric_u(a::AcbFieldElem, b::AcbFieldElem, x::AcbFieldElem)

Return the confluent hypergeometric function $U(a,b,x)$.

source
hypergeometric_2f1Method
hypergeometric_2f1(a::AcbFieldElem, b::AcbFieldElem, c::AcbFieldElem, x::AcbFieldElem; flags=0)

Return the Gauss hypergeometric function ${}_2F_1(a,b,c,x)$.

source
jacobi_thetaMethod
jacobi_theta(z::AcbFieldElem, tau::AcbFieldElem)

Return a tuple of four elements containing the Jacobi theta function values $\theta_1, \theta_2, \theta_3, \theta_4$ evaluated at $z, \tau$.

source
weierstrass_pMethod
weierstrass_p(z::AcbFieldElem, tau::AcbFieldElem)

Return the Weierstrass elliptic function $\wp(z,\tau)$.

source

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{AcbFieldElem}, 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.

source
lindepMethod
lindep(A::Matrix{AcbFieldElem}, 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.

source

Examples

julia> CC = AcbField(128)
-Complex Field with 128 bits of precision and error bounds
-
-julia> # These are two of the roots of x^5 + 3x + 1
-
-julia> a = CC(1.0050669478588622428791051888364775253, -0.93725915669289182697903585868761513585)
-[1.00506694785886230292248910700436681509 +/- 1.80e-40] - [0.937259156692891837181491609953809529543 +/- 7.71e-41]*im
-
-julia> b = CC(-0.33198902958450931620250069492231652319)
--[0.331989029584509320880414406929048709571 +/- 3.62e-40]
-
-julia> V1 = [CC(1), a, a^2, a^3, a^4, a^5]; # We recover the polynomial from one root....
-
-julia> W = lindep(V1, 20)
-6-element Vector{ZZRingElem}:
- 1
- 3
- 0
- 0
- 0
- 1
-
-julia> V2 = [CC(1), b, b^2, b^3, b^4, b^5]; # ...or from two
-
-julia> Vs = [transpose(V1); transpose(V2)];
-
-julia> X = lindep(Vs, 20)
-6-element Vector{ZZRingElem}:
- 1
- 3
- 0
- 0
- 0
- 1
diff --git a/previews/PR4245/Nemo/algebraic/index.html b/previews/PR4245/Nemo/algebraic/index.html deleted file mode 100644 index f4dddd02534a..000000000000 --- a/previews/PR4245/Nemo/algebraic/index.html +++ /dev/null @@ -1,121 +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 can be constructed using QQBar = algebraic_closure(QQ). We will leave out this line from all code blocks on this page for brevity.

LibraryElement typeParent type
CalciumQQBarFieldElemQQBarField

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 a 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{QQBarFieldElem}:
- 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(QQBar, ZZ[1 1 0; 0 1 1; 1 0 1])
-3-element Vector{QQBarFieldElem}:
- 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::QQBarField, 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.

source
rootsMethod
roots(R::QQBarField, 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.

source
eigenvaluesMethod
eigenvalues(R::QQBarField, A::ZZMatrix)
-eigenvalues(R::QQBarField, A::QQMatrix)

Return the eigenvalues A in the field of algebraic numbers R. The output array is sorted in the default sort order for algebraic numbers.

source
eigenvalues(L::Field, M::MatElem{T}) where T <: RingElem

Return the eigenvalues of M over the field L.

source
eigenvalues_with_multiplicitiesMethod
eigenvalues_with_multiplicities(R::QQBarField, A::ZZMatrix)
-eigenvalues_with_multiplicities(R::QQBarField, A::QQMatrix)

Return the eigenvalues A in the field of algebraic numbers R together with their algebraic multiplicities as a vector of tuples. The output array is sorted in the default sort order for algebraic numbers.

source
eigenvalues_with_multiplicities(L::Field, M::MatElem{T}) where T <: RingElem

Return the eigenvalues of M over the field L together with their algebraic multiplicities as a vector of tuples.

source
eigenvaluesMethod
eigenvalues(R::QQBarField, A::ZZMatrix)
-eigenvalues(R::QQBarField, A::QQMatrix)

Return the eigenvalues A in the field of algebraic numbers R. The output array is sorted in the default sort order for algebraic numbers.

source
eigenvalues(L::Field, M::MatElem{T}) where T <: RingElem

Return the eigenvalues of M over the field L.

source
eigenvalues_with_multiplicitiesMethod
eigenvalues_with_multiplicities(R::QQBarField, A::ZZMatrix)
-eigenvalues_with_multiplicities(R::QQBarField, A::QQMatrix)

Return the eigenvalues A in the field of algebraic numbers R together with their algebraic multiplicities as a vector of tuples. The output array is sorted in the default sort order for algebraic numbers.

source
eigenvalues_with_multiplicities(L::Field, M::MatElem{T}) where T <: RingElem

Return the eigenvalues of M over the field L together with their algebraic multiplicities as a vector of tuples.

source
randMethod
rand(R::QQBarField; 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.

source

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{QQBarFieldElem}:
- 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::QQBarFieldElem)

Return whether x is the number 0.

source
isoneMethod
isone(x::QQBarFieldElem)

Return whether x is the number 1.

source
isintegerMethod
isinteger(x::QQBarFieldElem)

Return whether x is an integer.

source
is_rationalMethod
is_rational(x::QQBarFieldElem)

Return whether x is a rational number.

source
isrealMethod
isreal(x::QQBarFieldElem)

Return whether x is a real number.

source
degreeMethod
degree(x::QQBarFieldElem)

Return the degree of the minimal polynomial of x.

source
minpolyMethod
minpoly(R::ZZPolyRing, x::QQBarFieldElem)

Return the minimal polynomial of x as an element of the polynomial ring R.

source
minpolyMethod
minpoly(R::ZZPolyRing, x::QQBarFieldElem)

Return the minimal polynomial of x as an element of the polynomial ring R.

source
conjugatesMethod
conjugates(a::QQBarFieldElem)

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.

source
denominatorMethod
denominator(x::QQBarFieldElem)

Return the denominator of x, defined as the leading coefficient of the minimal polynomial of x. The result is returned as an ZZRingElem.

source
numeratorMethod
numerator(x::QQBarFieldElem)

Return the numerator of x, defined as x multiplied by its denominator. The result is an algebraic integer.

source
heightMethod
height(x::QQBarFieldElem)

Return the height of the algebraic number x. The result is an ZZRingElem integer.

source
height_bitsMethod
height_bits(x::QQBarFieldElem)

Return the height of the algebraic number x measured in bits. The result is a Julia integer.

source

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::QQBarFieldElem)

Return the real part of a.

source
imagMethod
imag(a::QQBarFieldElem)

Return the imaginary part of a.

source
absMethod
abs(a::QQBarFieldElem)

Return the absolute value of a.

source
abs2Method
abs2(a::QQBarFieldElem)

Return the squared absolute value of a.

source
conjMethod
conj(a::QQBarFieldElem)

Return the complex conjugate of a.

source
signMethod
sign(a::QQBarFieldElem)

Return the complex sign of a, defined as zero if a is zero and as $a / |a|$ otherwise.

source
csgnMethod
csgn(a::QQBarFieldElem)

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.

source
sign_realMethod
sign_real(a::QQBarFieldElem)

Return the sign of the real part of a as a Julia integer.

source
sign_imagMethod
sign_imag(a::QQBarFieldElem)

Return the sign of the imaginary part of a as a Julia integer.

source

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::QQBarFieldElem, b::QQBarFieldElem)

Compares the real parts of a and b.

source
is_equal_imagMethod
is_equal_imag(a::QQBarFieldElem, b::QQBarFieldElem)

Compares the imaginary parts of a and b.

source
is_equal_absMethod
is_equal_abs(a::QQBarFieldElem, b::QQBarFieldElem)

Compares the absolute values of a and b.

source
is_equal_abs_realMethod
is_equal_abs_real(a::QQBarFieldElem, b::QQBarFieldElem)

Compares the absolute values of the real parts of a and b.

source
is_equal_abs_imagMethod
is_equal_abs_imag(a::QQBarFieldElem, b::QQBarFieldElem)

Compares the absolute values of the imaginary parts of a and b.

source
is_less_realMethod
is_less_real(a::QQBarFieldElem, b::QQBarFieldElem)

Compares the real parts of a and b.

source
is_less_imagMethod
is_less_imag(a::QQBarFieldElem, b::QQBarFieldElem)

Compares the imaginary parts of a and b.

source
is_less_absMethod
is_less_abs(a::QQBarFieldElem, b::QQBarFieldElem)

Compares the absolute values of a and b.

source
is_less_abs_realMethod
is_less_abs_real(a::QQBarFieldElem, b::QQBarFieldElem)

Compares the absolute values of the real parts of a and b.

source
is_less_abs_imagMethod
is_less_abs_imag(a::QQBarFieldElem, b::QQBarFieldElem)

Compares the absolute values of the imaginary parts of a and b.

source
is_less_root_orderMethod
is_less_root_order(a::QQBarFieldElem, b::QQBarFieldElem)

Compares the a and b in root sort order.

source

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::QQBarFieldElem; check::Bool=true)

Return the principal square root of a.

source
rootMethod
root(a::QQBarFieldElem, n::Int)

Return the principal n-th root of a. Requires positive n.

source
root_of_unityMethod
root_of_unity(C::QQBarField, n::Int)

Return the root of unity $e^{2 \pi i / n}$ as an element of the field of algebraic numbers C.

source
root_of_unityMethod
root_of_unity(C::QQBarField, 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.

source
is_root_of_unityMethod
is_root_of_unity(a::QQBarFieldElem)

Return whether the given algebraic number is a root of unity.

source
root_of_unity_as_argsMethod
root_of_unity_as_args(a::QQBarFieldElem)

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.

source
exp_pi_iMethod
exp_pi_i(a::QQBarFieldElem)

Return $e^{\pi i a}$ as an algebraic number. Throws if this value is transcendental.

source
log_pi_iMethod
log_pi_i(a::QQBarFieldElem)

Return $\log(a) / (\pi i)$ as an algebraic number. Throws if this value is transcendental or undefined.

source
sinpiMethod
sinpi(a::QQBarFieldElem)

Return $\sin(\pi a)$ as an algebraic number. Throws if this value is transcendental.

Examples

julia> QQBar = algebraic_closure(QQ);
-
-julia> x = sinpi(QQBar(1//3))
-Root 0.866025 of 4x^2 - 3
-
-julia> sinpi(x)
-ERROR: DomainError with Root 0.866025 of 4x^2 - 3:
-nonrational algebraic number
source
cospiMethod
cospi(a::QQBarFieldElem)

Return $\cos(\pi a)$ as an algebraic number. Throws if this value is transcendental.

Examples

julia> QQBar = algebraic_closure(QQ);
-
-julia> x = cospi(QQBar(1//6))
-Root 0.866025 of 4x^2 - 3
-
-julia> cospi(x)
-ERROR: DomainError with Root 0.866025 of 4x^2 - 3:
-nonrational algebraic number
source
sincospiMethod
sincospi(a::QQBarFieldElem)

Return $\sin(\pi a)$ and $\cos(\pi a)$ as a pair of algebraic numbers. Throws if either value is transcendental.

Examples

julia> QQBar = algebraic_closure(QQ);
-
-julia> s, c = sincospi(QQBar(1//3))
-(Root 0.866025 of 4x^2 - 3, Root 0.500000 of 2x - 1)
-
-julia> sincospi(s)
-ERROR: DomainError with Root 0.866025 of 4x^2 - 3:
-nonrational algebraic number
source
tanpiMethod
tanpi(a::QQBarFieldElem)

Return $\tan(\pi a)$ as an algebraic number. Throws if this value is transcendental or undefined.

source
asinpiMethod
asinpi(a::QQBarFieldElem)

Return $\operatorname{asin}(a) / \pi$ as an algebraic number. Throws if this value is transcendental.

source
acospiMethod
acospi(a::QQBarFieldElem)

Return $\operatorname{acos}(a) / \pi$ as an algebraic number. Throws if this value is transcendental.

source
atanpiMethod
atanpi(a::QQBarFieldElem)

Return $\operatorname{atan}(a) / \pi$ as an algebraic number. Throws if this value is transcendental or undefined.

source

Guessing

Examples

An algebraic number can be recovered from a numerical value:

julia> RR = RealField(); 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, at best the only algebraic number that can be guessed is the binary floating-point number itself, at worst no guess is possible.

julia> RR = RealField();
-
-julia> x = RR(0.1)       # note: 53-bit binary approximation of 1//10 without radius
-[0.10000000000000000555 +/- 1.12e-21]
-
-julia> guess(QQBar, x, 1)
-ERROR: No suitable algebraic number found
-
-julia> guess(QQBar, x + RR("+/- 1e-10"), 1)
-Root 0.100000 of 10x - 1

Interface

guessFunction
guess(R::QQBarField, x::AcbFieldElem, maxdeg::Int, maxbits::Int=0)
-guess(R::QQBarField, x::ArbFieldElem, maxdeg::Int, maxbits::Int=0)
-guess(R::QQBarField, x::ComplexFieldElem, maxdeg::Int, maxbits::Int=0)
-guess(R::QQBarField, x::RealFieldElem, 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.

source
diff --git a/previews/PR4245/Nemo/arb/index.html b/previews/PR4245/Nemo/arb/index.html deleted file mode 100644 index 85e02ed1dde3..000000000000 --- a/previews/PR4245/Nemo/arb/index.html +++ /dev/null @@ -1,244 +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)ArbFieldElemArbField

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

julia> RR = ArbField(64)
-Real Field with 64 bits of precision and error bounds
-
-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

ballMethod
ball(x::ArbFieldElem, y::ArbFieldElem)

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)$.

source

Examples

julia> RR = ArbField(64)
-Real Field with 64 bits of precision and error bounds
-
-julia> c = ball(RR(3), RR("0.0001"))
-[3.000 +/- 1.01e-4]

Conversions

julia> RR = ArbField(64)
-Real Field with 64 bits of precision and error bounds
-
-julia> convert(Float64, RR(1//3))
-0.3333333333333333

Basic manipulation

is_nonzeroMethod
is_nonzero(x::ArbFieldElem)

Return true if $x$ is certainly not equal to zero, otherwise return false.

source
isfiniteMethod
isfinite(x::ArbFieldElem)

Return true if $x$ is finite, i.e. having finite midpoint and radius, otherwise return false.

source
is_exactMethod
is_exact(x::ArbFieldElem)

Return true if $x$ is exact, i.e. has zero radius, otherwise return false.

source
isintegerMethod
isinteger(x::ArbFieldElem)

Return true if $x$ is an exact integer, otherwise return false.

source
is_positiveMethod
is_positive(x::ArbFieldElem)

Return true if $x$ is certainly positive, otherwise return false.

source
is_nonnegativeMethod
is_nonnegative(x::ArbFieldElem)

Return true if $x$ is certainly non-negative, otherwise return false.

source
is_negativeMethod
is_negative(x::ArbFieldElem)

Return true if $x$ is certainly negative, otherwise return false.

source
is_nonpositiveMethod
is_nonpositive(x::ArbFieldElem)

Return true if $x$ is certainly nonpositive, otherwise return false.

source
midpointMethod
midpoint(x::ArbFieldElem)

Return the midpoint of the ball $x$ as an Arb ball.

source
radiusMethod
radius(x::ArbFieldElem)

Return the radius of the ball $x$ as an Arb ball.

source
accuracy_bitsMethod
accuracy_bits(x::ArbFieldElem)

Return the relative accuracy of $x$ measured in bits, capped between typemax(Int) and -typemax(Int).

source

Examples

julia> RR = ArbField(64)
-Real Field with 64 bits of precision and error bounds
-
-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:

julia> RR = ArbField(64)
-Real Field with 64 bits of precision and error bounds
-
-julia> a = RR(1)
-1.0000000000000000000
-
-julia> b = RR(2)
-2.0000000000000000000
-
-julia> c = RR(12)
-12.000000000000000000
-
-julia> x = ball(a, b)
-[+/- 3.01]
-
-julia> y = ball(c, b)
-[1e+1 +/- 4.01]
-
-julia> mid = midpoint(x)
-1.0000000000000000000
-
-julia> rad = radius(x)
-[2.0000000037252902985 +/- 3.81e-20]
-
-julia> print(x, "\n", y, "\n", mid, "\n", rad)
-[+/- 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::ArbFieldElem, y::ArbFieldElem)

Returns true if any part of the ball $x$ overlaps any part of the ball $y$, otherwise return false.

source
containsMethod
contains(x::ArbFieldElem, y::ArbFieldElem)

Returns true if the ball $x$ contains the ball $y$, otherwise return false.

source
containsMethod
contains(x::ArbFieldElem, y::Integer)

Returns true if the ball $x$ contains the given integer value, otherwise return false.

source
containsMethod
contains(x::ArbFieldElem, y::ZZRingElem)

Returns true if the ball $x$ contains the given integer value, otherwise return false.

source
containsMethod
contains(x::ArbFieldElem, y::QQFieldElem)

Returns true if the ball $x$ contains the given rational value, otherwise return false.

source
containsMethod
contains(x::ArbFieldElem, y::Rational{T}) where {T <: Integer}

Returns true if the ball $x$ contains the given rational value, otherwise return false.

source
containsMethod
contains(x::ArbFieldElem, y::BigFloat)

Returns true if the ball $x$ contains the given floating point value, otherwise return false.

source

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::ArbFieldElem)

Returns true if the ball $x$ contains zero, otherwise return false.

source
contains_negativeMethod
contains_negative(x::ArbFieldElem)

Returns true if the ball $x$ contains any negative value, otherwise return false.

source
contains_positiveMethod
contains_positive(x::ArbFieldElem)

Returns true if the ball $x$ contains any positive value, otherwise return false.

source
contains_nonnegativeMethod
contains_nonnegative(x::ArbFieldElem)

Returns true if the ball $x$ contains any non-negative value, otherwise return false.

source
contains_nonpositiveMethod
contains_nonpositive(x::ArbFieldElem)

Returns true if the ball $x$ contains any nonpositive value, otherwise return false.

source

Examples

julia> RR = ArbField(64)
-Real Field with 64 bits of precision and error bounds
-
-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::ArbFieldElem, y::ArbFieldElem)

Return true if the balls $x$ and $y$ are precisely equal, i.e. have the same midpoints and radii.

source

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::ArbFieldElem, y::Integer)
==(x::Integer, y::ArbFieldElem)
==(x::ArbFieldElem, y::ZZRingElem)
==(x::ZZRingElem, y::ArbFieldElem)
==(x::ArbFieldElem, y::Float64)
==(x::Float64, y::ArbFieldElem)
isless(x::ArbFieldElem, y::Integer)
isless(x::Integer, y::ArbFieldElem)
isless(x::ArbFieldElem, y::ZZRingElem)
isless(x::ZZRingElem, y::ArbFieldElem)
isless(x::ArbFieldElem, y::Float64)
isless(x::Float64, y::ArbFieldElem)
isless(x::ArbFieldElem, y::BigFloat)
isless(x::BigFloat, y::ArbFieldElem)
isless(x::ArbFieldElem, y::QQFieldElem)
isless(x::QQFieldElem, y::ArbFieldElem)

Examples

julia> RR = ArbField(64)
-Real Field with 64 bits of precision and error bounds
-
-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
-
-julia> 3 == y
-true

Absolute value

Examples

julia> RR = ArbField(64)
-Real Field with 64 bits of precision and error bounds
-
-julia> x = RR("-1 +/- 0.001")
-[-1.00 +/- 1.01e-3]
-
-julia> a = abs(x)
-[1.00 +/- 1.01e-3]

Shifting

Examples

julia> RR = ArbField(64)
-Real Field with 64 bits of precision and error bounds
-
-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::ArbFieldElem, y::ArbFieldElem)

Adds the absolute values of the midpoint and radius of $y$ to the radius of $x$.

source
trimMethod
trim(x::ArbFieldElem)

Return an ArbFieldElem interval containing $x$ but which may be more economical, by rounding off insignificant bits from the midpoint.

source
unique_integerMethod
unique_integer(x::ArbFieldElem)

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.

source
setunionMethod
setunion(x::ArbFieldElem, y::ArbFieldElem)

Return an ArbFieldElem containing the union of the intervals represented by $x$ and $y$.

source

Examples

julia> RR = ArbField(64)
-Real Field with 64 bits of precision and error bounds
-
-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::ArbField)

Return $\pi = 3.14159\ldots$ as an element of $r$.

source
const_eMethod
const_e(r::ArbField)

Return $e = 2.71828\ldots$ as an element of $r$.

source
const_log2Method
const_log2(r::ArbField)

Return $\log(2) = 0.69314\ldots$ as an element of $r$.

source
const_log10Method
const_log10(r::ArbField)

Return $\log(10) = 2.302585\ldots$ as an element of $r$.

source
const_eulerMethod
const_euler(r::ArbField)

Return Euler's constant $\gamma = 0.577215\ldots$ as an element of $r$.

source
const_catalanMethod
const_catalan(r::ArbField)

Return Catalan's constant $C = 0.915965\ldots$ as an element of $r$.

source
const_khinchinMethod
const_khinchin(r::ArbField)

Return Khinchin's constant $K = 2.685452\ldots$ as an element of $r$.

source
const_glaisherMethod
const_glaisher(r::ArbField)

Return Glaisher's constant $A = 1.282427\ldots$ as an element of $r$.

source

Examples

julia> RR = ArbField(200)
-Real Field with 200 bits of precision and error bounds
-
-julia> a = const_pi(RR)
-[3.14159265358979323846264338327950288419716939937510582097494 +/- 5.73e-60]
-
-julia> b = const_e(RR)
-[2.71828182845904523536028747135266249775724709369995957496697 +/- 7.06e-60]
-
-julia> c = const_euler(RR)
-[0.577215664901532860606512090082402431042159335939923598805767 +/- 5.37e-61]
-
-julia> d = const_glaisher(RR)
-[1.28242712910062263687534256886979172776768892732500119206374 +/- 2.18e-60]

Mathematical and special functions

rsqrtMethod
rsqrt(x::ArbFieldElem)

Return the reciprocal of the square root of $x$, i.e. $1/\sqrt{x}$.

source
sqrt1pm1Method
sqrt1pm1(x::ArbFieldElem)

Return $\sqrt{1+x}-1$, evaluated accurately for small $x$.

source
sqrtposMethod
sqrtpos(x::ArbFieldElem)

Return the sqrt root of $x$, assuming that $x$ represents a non-negative number. Thus any negative number in the input interval is discarded.

source
gammaMethod
gamma(x::ArbFieldElem)

Return the Gamma function evaluated at $x$.

source
lgammaMethod
lgamma(x::ArbFieldElem)

Return the logarithm of the Gamma function evaluated at $x$.

source
rgammaMethod
rgamma(x::ArbFieldElem)

Return the reciprocal of the Gamma function evaluated at $x$.

source
digammaMethod
digamma(x::ArbFieldElem)

Return the logarithmic derivative of the gamma function evaluated at $x$, i.e. $\psi(x)$.

source
gammaMethod
gamma(s::ArbFieldElem, x::ArbFieldElem)

Return the upper incomplete gamma function $\Gamma(s,x)$.

source
gamma_regularizedMethod
gamma_regularized(s::ArbFieldElem, x::ArbFieldElem)

Return the regularized upper incomplete gamma function $\Gamma(s,x) / \Gamma(s)$.

source
gamma_lowerMethod
gamma_lower(s::ArbFieldElem, x::ArbFieldElem)

Return the lower incomplete gamma function $\gamma(s,x) / \Gamma(s)$.

source
gamma_lower_regularizedMethod
gamma_lower_regularized(s::ArbFieldElem, x::ArbFieldElem)

Return the regularized lower incomplete gamma function $\gamma(s,x) / \Gamma(s)$.

source
zetaMethod
zeta(x::ArbFieldElem)

Return the Riemann zeta function evaluated at $x$.

source
atan2Method
atan2(y::ArbFieldElem, x::ArbFieldElem)

Return $\operatorname{atan2}(y,x) = \arg(x+yi)$. Same as atan(y, x).

source
agmMethod
agm(x::ArbFieldElem, y::ArbFieldElem)

Return the arithmetic-geometric mean of $x$ and $y$

source
zetaMethod
zeta(s::ArbFieldElem, a::ArbFieldElem)

Return the Hurwitz zeta function $\zeta(s,a)$.

source
rootMethod
root(x::ArbFieldElem, n::Int)

Return the $n$-th root of $x$. We require $x \geq 0$.

source
factorialMethod
factorial(x::ArbFieldElem)

Return the factorial of $x$.

source
factorialMethod
factorial(n::Int, r::ArbField)

Return the factorial of $n$ in the given Arb field.

source
binomialMethod
binomial(x::ArbFieldElem, n::UInt)

Return the binomial coefficient ${x \choose n}$.

source
binomialMethod
binomial(n::UInt, k::UInt, r::ArbField)

Return the binomial coefficient ${n \choose k}$ in the given Arb field.

source
fibonacciMethod
fibonacci(n::ZZRingElem, r::ArbField)

Return the $n$-th Fibonacci number in the given Arb field.

source
fibonacciMethod
fibonacci(n::Int, r::ArbField)

Return the $n$-th Fibonacci number in the given Arb field.

source
gammaMethod
gamma(x::ZZRingElem, r::ArbField)

Return the Gamma function evaluated at $x$ in the given Arb field.

source
gammaMethod
gamma(x::QQFieldElem, r::ArbField)

Return the Gamma function evaluated at $x$ in the given Arb field.

source
zetaMethod
zeta(n::Int, r::ArbField)

Return the Riemann zeta function $\zeta(n)$ as an element of the given Arb field.

source
bernoulliMethod
bernoulli(n::Int, r::ArbField)

Return the $n$-th Bernoulli number as an element of the given Arb field.

source
rising_factorialMethod
rising_factorial(x::ArbFieldElem, n::Int)

Return the rising factorial $x(x + 1)\ldots (x + n - 1)$ as an Arb.

source
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.

source
rising_factorial2Method
rising_factorial2(x::ArbFieldElem, n::Int)

Return a tuple containing the rising factorial $x(x + 1)\ldots (x + n - 1)$ and its derivative.

source
polylogMethod
polylog(s::Union{ArbFieldElem,Int}, a::ArbFieldElem)

Return the polylogarithm Li$_s(a)$.

source
chebyshev_tMethod
chebyshev_t(n::Int, x::ArbFieldElem)

Return the value of the Chebyshev polynomial $T_n(x)$.

source
chebyshev_uMethod
chebyshev_u(n::Int, x::ArbFieldElem)

Return the value of the Chebyshev polynomial $U_n(x)$.

source
chebyshev_t2Method
chebyshev_t2(n::Int, x::ArbFieldElem)

Return the tuple $(T_{n}(x), T_{n-1}(x))$.

source
chebyshev_u2Method
chebyshev_u2(n::Int, x::ArbFieldElem)

Return the tuple $(U_{n}(x), U_{n-1}(x))$

source
bellMethod
bell(n::ZZRingElem, r::ArbField)

Return the Bell number $B_n$ as an element of $r$.

source
bellMethod
bell(n::Int, r::ArbField)

Return the Bell number $B_n$ as an element of $r$.

source
numpartMethod
numpart(n::ZZRingElem, r::ArbField)

Return the number of partitions $p(n)$ as an element of $r$.

source
numpartMethod
numpart(n::Int, r::ArbField)

Return the number of partitions $p(n)$ as an element of $r$.

source
airy_aiMethod
airy_ai(x::ArbFieldElem)

Return the Airy function $\operatorname{Ai}(x)$.

source
airy_ai_primeMethod
airy_ai_prime(x::ArbFieldElem)

Return the derivative of the Airy function $\operatorname{Ai}^\prime(x)$.

source
airy_biMethod
airy_bi(x::ArbFieldElem)

Return the Airy function $\operatorname{Bi}(x)$.

source
airy_bi_primeMethod
airy_bi_prime(x::ArbFieldElem)

Return the derivative of the Airy function $\operatorname{Bi}^\prime(x)$.

source

Examples

julia> RR = ArbField(64)
-Real Field with 64 bits of precision and error bounds
-
-julia> a = floor(exp(RR(1)))
-2.0000000000000000000
-
-julia> b = sinpi(QQ(5,6), RR)
-0.50000000000000000000
-
-julia> c = gamma(QQ(1,3), ArbField(256))
-[2.6789385347077476336556929409746776441286893779573011009504283275904176101677 +/- 6.71e-77]
-
-julia> d = bernoulli(1000, ArbField(53))
-[-5.318704469415522e+1769 +/- 8.20e+1753]
-
-julia> f = polylog(3, RR(-10))
-[-5.92106480375697 +/- 6.68e-15]

Linear dependence

lindepMethod
lindep(A::Vector{ArbFieldElem}, 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{ArbFieldElem}:
- 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
source

Examples

julia> RR = ArbField(128)
-Real Field with 128 bits of precision and error bounds
-
-julia> a = RR(-0.33198902958450931620250069492231652319) # real root of x^5 + 3x + 1
-[-0.331989029584509320880414406929048709571 +/- 3.62e-40]
-
-julia> V = [RR(1), a, a^2, a^3, a^4, a^5]
-6-element Vector{ArbFieldElem}:
- 1.00000000000000000000000000000000000000
- [-0.331989029584509320880414406929048709571 +/- 3.62e-40]
- [0.110216715764464205102727554344054759368 +/- 3.32e-40]
- [-0.0365907405106361618384680031506015710184 +/- 8.30e-41]
- [0.0121477244339046924274232580429164920524 +/- 2.83e-41]
- [-0.00403291124647205167662794872826031818905 +/- 7.87e-42]
-
-julia> W = lindep(V, 20)
-6-element Vector{ZZRingElem}:
- 1
- 3
- 0
- 0
- 0
- 1
simplest_rational_insideMethod
  simplest_rational_inside(x::ArbFieldElem)

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
source

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 ArbFieldElem 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 ArbFieldElem 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.

source

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/PR4245/Nemo/complex/index.html b/previews/PR4245/Nemo/complex/index.html deleted file mode 100644 index 9e8107d0b1fa..000000000000 --- a/previews/PR4245/Nemo/complex/index.html +++ /dev/null @@ -1,175 +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 ArbFieldElem 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()

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 = ComplexField()
-Complex field
-
-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::ComplexField)

Return exact one times $i$ in the given Arb complex field.

source

Examples

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{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.

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::ArbFieldElem)

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.

julia> RR = RealField()
-Real field
-
-julia> CC = ComplexField()
-Complex field
-
-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::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.

source
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.

source
isintegerMethod
isinteger(x::ComplexFieldElem)

Return true if $x$ is an exact integer, otherwise return false.

source
accuracy_bitsMethod
accuracy_bits(x::ComplexFieldElem)

Return the relative accuracy of $x$ measured in bits, capped between typemax(Int) and -typemax(Int).

source

Examples

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::ComplexFieldElem, y::ComplexFieldElem)

Returns true if any part of the box $x$ overlaps any part of the box $y$, otherwise return false.

source
containsMethod
contains(x::ComplexFieldElem, y::ComplexFieldElem)

Returns true if the box $x$ contains the box $y$, otherwise return false.

source
containsMethod
contains(x::ComplexFieldElem, y::Integer)

Returns true if the box $x$ contains the given integer value, otherwise return false.

source
containsMethod
contains(x::ComplexFieldElem, y::ZZRingElem)

Returns true if the box $x$ contains the given integer value, otherwise return false.

source
containsMethod
contains(x::ComplexFieldElem, y::QQFieldElem)

Returns true if the box $x$ contains the given rational value, otherwise return false.

source

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.

source

Examples

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::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.

source

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::ArbFieldElem, y::ZZRingElem)
==(x::ZZRingElem, y::ArbFieldElem)
==(x::ComplexFieldElem, y::Float64)
==(x::Float64, y::ComplexFieldElem)

Examples

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) == y
-true
-
-julia> z != 1.23
-true

Absolute value

Examples

julia> x = CC("-1 +/- 0.001")
-[-1.00 +/- 1.01e-3]
-
-julia> a = abs(x)
-[1.00 +/- 1.01e-3]

Shifting

Examples

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::ComplexFieldElem)

Return an ComplexFieldElem box containing $x$ but which may be more economical, by rounding off insignificant bits from midpoints.

source
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.

source

Examples

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::ComplexField)

Return $\pi = 3.14159\ldots$ as an element of $r$.

source

Examples

CC = ComplexField()
-set_precision!(ComplexField, 200) do
-  a = const_pi(CC)
-end

Mathematical and special functions

rsqrtMethod
rsqrt(x::ComplexFieldElem)

Return the reciprocal of the square root of $x$, i.e. $1/\sqrt{x}$.

source
cispiMethod
cispi(x::ComplexFieldElem)

Return the exponential of $\pi i x$.

source
log_sinpiMethod
log_sinpi(x::ComplexFieldElem)

Return $\log\sin(\pi x)$, constructed without branch cuts off the real line.

source
gammaMethod
gamma(x::ComplexFieldElem)

Return the Gamma function evaluated at $x$.

source
lgammaMethod
lgamma(x::ComplexFieldElem)

Return the logarithm of the Gamma function evaluated at $x$.

source
rgammaMethod
rgamma(x::ComplexFieldElem)

Return the reciprocal of the Gamma function evaluated at $x$.

source
digammaMethod
digamma(x::ComplexFieldElem)

Return the logarithmic derivative of the gamma function evaluated at $x$, i.e. $\psi(x)$.

source
zetaMethod
zeta(x::ComplexFieldElem)

Return the Riemann zeta function evaluated at $x$.

source
barnes_gMethod
barnes_g(x::ComplexFieldElem)

Return the Barnes $G$-function, evaluated at $x$.

source
log_barnes_gMethod
log_barnes_g(x::ComplexFieldElem)

Return the logarithm of the Barnes $G$-function, evaluated at $x$.

source
erfMethod
erf(x::ComplexFieldElem)

Return the error function evaluated at $x$.

source
erfiMethod
erfi(x::ComplexFieldElem)

Return the imaginary error function evaluated at $x$.

source
exp_integral_eiMethod
exp_integral_ei(x::ComplexFieldElem)

Return the exponential integral evaluated at $x$.

source
sin_integralMethod
sin_integral(x::ComplexFieldElem)

Return the sine integral evaluated at $x$.

source
cos_integralMethod
cos_integral(x::ComplexFieldElem)

Return the exponential cosine integral evaluated at $x$.

source
sinh_integralMethod
sinh_integral(x::ComplexFieldElem)

Return the hyperbolic sine integral evaluated at $x$.

source
cosh_integralMethod
cosh_integral(x::ComplexFieldElem)

Return the hyperbolic cosine integral evaluated at $x$.

source
dedekind_etaMethod
dedekind_eta(x::ComplexFieldElem)

Return the Dedekind eta function $\eta(\tau)$ at $\tau = x$.

source
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.

source
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.

source
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.

source
j_invariantMethod
j_invariant(x::ComplexFieldElem)

Return the $j$-invariant $j(\tau)$ at $\tau = x$.

source
j_invariant(E::EllipticCurve) -> FieldElem

Compute the j-invariant of $E$.

source
modular_lambdaMethod
modular_lambda(x::ComplexFieldElem)

Return the modular lambda function $\lambda(\tau)$ at $\tau = x$.

source
modular_deltaMethod
modular_delta(x::ComplexFieldElem)

Return the modular delta function $\Delta(\tau)$ at $\tau = x$.

source
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$.

source
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$.

source
elliptic_kMethod
elliptic_k(x::ComplexFieldElem)

Return the complete elliptic integral $K(x)$.

source
elliptic_eMethod
elliptic_e(x::ComplexFieldElem)

Return the complete elliptic integral $E(x)$.

source
agmMethod
agm(x::ComplexFieldElem)

Return the arithmetic-geometric mean of $1$ and $x$.

source
agmMethod
agm(x::ComplexFieldElem, y::ComplexFieldElem)

Return the arithmetic-geometric mean of $x$ and $y$.

source
polygammaMethod
polygamma(s::ComplexFieldElem, a::ComplexFieldElem)

Return the generalised polygamma function $\psi(s,z)$.

source
zetaMethod
zeta(s::ComplexFieldElem, a::ComplexFieldElem)

Return the Hurwitz zeta function $\zeta(s,a)$.

source
rising_factorialMethod
rising_factorial(x::ComplexFieldElem, n::Int)

Return the rising factorial $x(x + 1)\ldots (x + n - 1)$ as an Acb.

source
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.

source
polylogMethod
polylog(s::Union{ComplexFieldElem,Int}, a::ComplexFieldElem)

Return the polylogarithm Li$_s(a)$.

source
log_integralMethod
log_integral(x::ComplexFieldElem)

Return the logarithmic integral, evaluated at $x$.

source
log_integral_offsetMethod
log_integral_offset(x::ComplexFieldElem)

Return the offset logarithmic integral, evaluated at $x$.

source
exp_integral_eMethod
exp_integral_e(s::ComplexFieldElem, x::ComplexFieldElem)

Return the generalised exponential integral $E_s(x)$.

source
gammaMethod
gamma(s::ComplexFieldElem, x::ComplexFieldElem)

Return the upper incomplete gamma function $\Gamma(s,x)$.

source
gamma_regularizedMethod
gamma_regularized(s::ComplexFieldElem, x::ComplexFieldElem)

Return the regularized upper incomplete gamma function $\Gamma(s,x) / \Gamma(s)$.

source
gamma_lowerMethod
gamma_lower(s::ComplexFieldElem, x::ComplexFieldElem)

Return the lower incomplete gamma function $\gamma(s,x) / \Gamma(s)$.

source
gamma_lower_regularizedMethod
gamma_lower_regularized(s::ComplexFieldElem, x::ComplexFieldElem)

Return the regularized lower incomplete gamma function $\gamma(s,x) / \Gamma(s)$.

source
airy_aiMethod
airy_ai(x::ComplexFieldElem)

Return the Airy function $\operatorname{Ai}(x)$.

source
airy_ai_primeMethod
airy_ai_prime(x::ComplexFieldElem)

Return the derivative of the Airy function $\operatorname{Ai}^\prime(x)$.

source
airy_biMethod
airy_bi(x::ComplexFieldElem)

Return the Airy function $\operatorname{Bi}(x)$.

source
airy_bi_primeMethod
airy_bi_prime(x::ComplexFieldElem)

Return the derivative of the Airy function $\operatorname{Bi}^\prime(x)$.

source
bessel_jMethod
bessel_j(nu::ComplexFieldElem, x::ComplexFieldElem)

Return the Bessel function $J_{\nu}(x)$.

source
bessel_yMethod
bessel_y(nu::ComplexFieldElem, x::ComplexFieldElem)

Return the Bessel function $Y_{\nu}(x)$.

source
bessel_iMethod
bessel_i(nu::ComplexFieldElem, x::ComplexFieldElem)

Return the Bessel function $I_{\nu}(x)$.

source
bessel_kMethod
bessel_k(nu::ComplexFieldElem, x::ComplexFieldElem)

Return the Bessel function $K_{\nu}(x)$.

source
hypergeometric_1f1Method
hypergeometric_1f1(a::ComplexFieldElem, b::ComplexFieldElem, x::ComplexFieldElem)

Return the confluent hypergeometric function ${}_1F_1(a,b,x)$.

source
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)$.

source
hypergeometric_uMethod
hypergeometric_u(a::ComplexFieldElem, b::ComplexFieldElem, x::ComplexFieldElem)

Return the confluent hypergeometric function $U(a,b,x)$.

source
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)$.

source
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$.

source
weierstrass_pMethod
weierstrass_p(z::ComplexFieldElem, tau::ComplexFieldElem)

Return the Weierstrass elliptic function $\wp(z,\tau)$.

source

Examples

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{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.

source
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.

source

Examples

julia> # These are two of the roots of x^5 + 3x + 1
-
-julia> a = CC(1.0050669478588622428791051888364775253, -0.93725915669289182697903585868761513585)
-[1.0050669478588623029 +/- 2.25e-20] - [0.93725915669289183718 +/- 1.50e-21]*im
-
-julia> b = CC(-0.33198902958450931620250069492231652319)
--[0.33198902958450932088 +/- 4.15e-22]
-
-julia> V1 = [CC(1), a, a^2, a^3, a^4, a^5]; # We recover the polynomial from one root....
-
-julia> W = lindep(V1, 20)
-6-element Vector{ZZRingElem}:
- 1
- 3
- 0
- 0
- 0
- 1
-
-julia> V2 = [CC(1), b, b^2, b^3, b^4, b^5]; # ...or from two
-
-julia> Vs = [transpose(V1); transpose(V2)];
-
-julia> X = lindep(Vs, 20)
-6-element Vector{ZZRingElem}:
- 1
- 3
- 0
- 0
- 0
- 1
diff --git a/previews/PR4245/Nemo/constructors/index.html b/previews/PR4245/Nemo/constructors/index.html deleted file mode 100644 index f0ee19e94ee8..000000000000 --- a/previews/PR4245/Nemo/constructors/index.html +++ /dev/null @@ -1,12 +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:

julia> BigInt(1234567898765434567898765434567876543456787654567890)
-1234567898765434567898765434567876543456787654567890

Julia also uses constructors to convert between types. For example, to convert an Int to a BigInt:

julia> m = BigInt(123)
-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:

julia> n = ZZ(12345678765456787654567890987654567898765678909876567890)
-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.

julia> R, x = polynomial_ring(ZZ, "x")
-(Univariate polynomial ring in x over ZZ, x)
-
-julia> f = x^3 + 3x + 1
-x^3 + 3*x + 1
-
-julia> g = R(12)
-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 = finite_field(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}$S = RealField()
$S = \mathbb{C}$S = ComplexField()
diff --git a/previews/PR4245/Nemo/developer/conventions/index.html b/previews/PR4245/Nemo/developer/conventions/index.html deleted file mode 100644 index e8be0d8174df..000000000000 --- a/previews/PR4245/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.

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!, 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/PR4245/Nemo/developer/img/types.svg b/previews/PR4245/Nemo/developer/img/types.svg deleted file mode 100644 index 7ab749164ef6..000000000000 --- a/previews/PR4245/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
MatRingElem{T}
MatRingElem{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/PR4245/Nemo/developer/img/types2.svg b/previews/PR4245/Nemo/developer/img/types2.svg deleted file mode 100644 index 6bf5a2ab5031..000000000000 --- a/previews/PR4245/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
MatRing{T}
MatRing{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/PR4245/Nemo/developer/interfaces/index.html b/previews/PR4245/Nemo/developer/interfaces/index.html deleted file mode 100644 index ce3df75ef534..000000000000 --- a/previews/PR4245/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 add! 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/PR4245/Nemo/developer/introduction/index.html b/previews/PR4245/Nemo/developer/introduction/index.html deleted file mode 100644 index 7508b82edf48..000000000000 --- a/previews/PR4245/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 PadicFieldElem 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, AbsSimpleNumFieldElem is for elements of a number field.

The AnticTypes.jl file contains the Antic types.

In the ArbFieldElem directory the ArbFieldElem prefix is for arbitrary precision ball arithmetic over the reals. The AcbFieldElem prefix is similar but for complex numbers.

The ArbTypes.jl file contains the Arb types.

In the calcium directory the CalciumFieldElem prefix is for Calcium's type. There is also a QQBarFieldElem 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/PR4245/Nemo/developer/parents/index.html b/previews/PR4245/Nemo/developer/parents/index.html deleted file mode 100644 index d3bbd604efe4..000000000000 --- a/previews/PR4245/Nemo/developer/parents/index.html +++ /dev/null @@ -1,2 +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, ZZ 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 only be used with great care in library code. There are a number of reasons for this.

One issue is that parent objects are allowed to be arbitrarily large, and they are frequently cached by the system. They can also perform arbitrary precomputations for the ring/field/module etc. that is being constructed. This can lead to excessive memory usage. It can also have odd effects when a behavior affecting change is applied to a cached parent and thus has effects in places where one might not expect it.

Secondly, those parent caches are global objects. This is problematic for any future attempts to parallelise library code. And if the caches are not regularly emptied, in the worst case memory usage can balloon excessively.

To deal with this, most parent object constructors take a cached keyword which specifies whether the parent object should be cached which library code should generally set to false. That said it is better overall to simply eschew the use of parent object constructors in library code and instead let parents be passed in via arguments (directly or indirectly, e.g. the parent or base ring of some argument might be a suitable parent for some return values or intermediate objects).

One may also use, where applicable, functions such as similar, zero, zero_matrix, identity_matrix, change_base_ring, map, etc. for constructing polynomials and matrices directly without a parent object.

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. 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.

Forcing the creation 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/PR4245/Nemo/developer/topics/index.html b/previews/PR4245/Nemo/developer/topics/index.html deleted file mode 100644 index 1fa62bfa6844..000000000000 --- a/previews/PR4245/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!, 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 = add(a, b)

i.e. one must have an explicit assignment to the left of the add call and indeed all the unsafe operator calls.

In the case of a mutable type (and the existence of a specialized method), add 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, add 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, 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.

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 AbsSimpleNumFieldElem type:

mul_red!(z::AbsSimpleNumFieldElem, x::AbsSimpleNumFieldElem, y::AbsSimpleNumFieldElem, 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::AbsSimpleNumFieldElem)

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 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 add! where delayed reduction or addmul! are not available.

diff --git a/previews/PR4245/Nemo/developer/typesystem/index.html b/previews/PR4245/Nemo/developer/typesystem/index.html deleted file mode 100644 index 1e4f2f3f42b0..000000000000 --- a/previews/PR4245/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/PR4245/Nemo/exact/index.html b/previews/PR4245/Nemo/exact/index.html deleted file mode 100644 index a433fc93a19c..000000000000 --- a/previews/PR4245/Nemo/exact/index.html +++ /dev/null @@ -1,176 +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
CalciumCalciumFieldElemCalciumField

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 CalciumFieldElem 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 (algebraic_closure(QQ)), 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> algebraic_closure(QQ)(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)
-Complex Field with 64 bits of precision and error bounds
-
-julia> CC(exp(C(1im)))
-[0.54030230586813971740 +/- 9.37e-22] + [0.84147098480789650665 +/- 2.51e-21]*im

The constructor

(R::AcbField)(a::CalciumFieldElem; 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::CalciumFieldElem; 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{CalciumFieldElem}:
- 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::CalciumFieldElem)

Return whether a is the number 0.

source
isoneMethod
isone(a::CalciumFieldElem)

Return whether a is the number 1.

source
is_algebraicMethod
is_algebraic(a::CalciumFieldElem)

Return whether a is an algebraic number.

source
is_rationalMethod
is_rational(a::CalciumFieldElem)

Return whether a is a rational number.

source
isintegerMethod
isinteger(a::CalciumFieldElem)

Return whether a is an integer.

source
isrealMethod
isreal(a::CalciumFieldElem)

Return whether a is a real number. This returns false if a is a pure real infinity.

source
is_imaginaryMethod
is_imaginary(a::CalciumFieldElem)

Return whether a is an imaginary number. This returns false if a is a pure imaginary infinity.

source

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.

source
infinityMethod
infinity(C::CalciumField)

Return positive infinity ($+\infty$) as an element of C. This throws an exception if C does not allow special values.

source
infinityMethod
infinity(a::CalciumFieldElem)

Return the signed infinity ($a \cdot \infty$). This throws an exception if the parent of a does not allow special values.

source
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.

source
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.

source
is_numberMethod
is_number(a::CalciumFieldElem)

Return whether a is a number, i.e. not an infinity or undefined.

source
is_undefinedMethod
is_undefined(a::CalciumFieldElem)

Return whether a is the special value Undefined.

source
isinfMethod
isinf(a::CalciumFieldElem)

Return whether a is any infinity (signed or unsigned).

source
is_uinfMethod
is_uinf(a::CalciumFieldElem)

Return whether a is unsigned infinity.

source
is_signed_infMethod
is_signed_inf(a::CalciumFieldElem)

Return whether a is any signed infinity.

source
is_unknownMethod
is_unknown(a::CalciumFieldElem)

Return whether a is the special value Unknown. This is a representation property and not a mathematical predicate.

source

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::CalciumFieldElem)

Return the real part of a.

source
imagMethod
imag(a::CalciumFieldElem)

Return the imaginary part of a.

source
angleMethod
angle(a::CalciumFieldElem)

Return the complex argument of a.

source
csgnMethod
csgn(a::CalciumFieldElem)

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.

source
signMethod
sign(a::CalciumFieldElem)

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.

source
absMethod
abs(a::CalciumFieldElem)

Return the absolute value of a.

source
conjMethod
conj(a::CalciumFieldElem; 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.

source
floorMethod
floor(a::CalciumFieldElem)

Return the floor function of a.

source
ceilMethod
ceil(a::CalciumFieldElem)

Return the ceiling function of a.

source

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.

source
const_eulerMethod
const_euler(C::CalciumField)

Return Euler's constant $\gamma$ as an element of C.

source
oneiMethod
onei(C::CalciumField)

Return the imaginary unit $i$ as an element of C.

source
sqrtMethod
Base.sqrt(a::CalciumFieldElem; check::Bool=true)

Return the principal square root of a.

source
expMethod
exp(a::CalciumFieldElem)

Return the exponential function of a.

source
logMethod
log(a::CalciumFieldElem)

Return the natural logarithm of a.

source
powMethod
pow(a::CalciumFieldElem, 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.

source
sinMethod
sin(a::CalciumFieldElem; 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.

source
cosMethod
cos(a::CalciumFieldElem; 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.

source
tanMethod
tan(a::CalciumFieldElem; 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.

source
atanMethod
atan(a::CalciumFieldElem; 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.

source
asinMethod
asin(a::CalciumFieldElem; 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.

source
acosMethod
acos(a::CalciumFieldElem; 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.

source
gammaMethod
gamma(a::CalciumFieldElem)

Return the gamma function of a.

source
erfMethod
erf(a::CalciumFieldElem)

Return the error function of a.

source
erfiMethod
erfi(a::CalciumFieldElem)

Return the imaginary error function of a.

source
erfcMethod
erfc(a::CalciumFieldElem)

Return the complementary error function of a.

source

Rewriting and simplification

complex_normal_formMethod
complex_normal_form(a::CalciumFieldElem, 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.

source
diff --git a/previews/PR4245/Nemo/factor/index.html b/previews/PR4245/Nemo/factor/index.html deleted file mode 100644 index ae542c0b4bd0..000000000000 --- a/previews/PR4245/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$.

source
getindexMethod
getindex(a::Fac, b) -> Int

If $b$ is a factor of $a$, the corresponding exponent is returned. Otherwise an error is thrown.

source
lengthMethod
length(a::Fac) -> Int

Return the number of factors of $a$, not including the unit.

source
unitMethod
unit(a::Fac{T}) -> T

Return the unit of the factorization.

source
diff --git a/previews/PR4245/Nemo/ff_embedding/index.html b/previews/PR4245/Nemo/ff_embedding/index.html deleted file mode 100644 index 79a3cd9df7fd..000000000000 --- a/previews/PR4245/Nemo/ff_embedding/index.html +++ /dev/null @@ -1,34 +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.

source

Examples

julia> k2, x2 = finite_field(19, 2, "x2")
-(Finite field of degree 2 and characteristic 19, x2)
-
-julia> k4, x4 = finite_field(19, 4, "x4")
-(Finite field of degree 4 and characteristic 19, x4)
-
-julia> f = embed(k2, k4)
-Morphism of finite fields
-  from finite field of degree 2 and characteristic 19
-  to finite field of degree 4 and characteristic 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$.

source
preimage_mapMethod
preimage_map(f::FinFieldMorphism)

Compute the preimage map corresponding to the embedding $f$.

source
preimage_map(f::FinFieldPreimage)

Compute the preimage map corresponding to the preimage of the embedding $f$, i.e. return the embedding $f$.

source

Examples

julia> k7, x7 = finite_field(13, 7, "x7")
-(Finite field of degree 7 and characteristic 13, x7)
-
-julia> k21, x21 = finite_field(13, 21, "x21")
-(Finite field of degree 21 and characteristic 13, x21)
-
-julia> s = preimage_map(k7, k21)
-Preimage of a morphism
-  from finite field of degree 7 and characteristic 13
-  to finite field of degree 21 and characteristic 13
-
-julia> y = k21(x7);
-
-julia> z = s(y)
-x7
-
-julia> t = k7(y)
-x7
diff --git a/previews/PR4245/Nemo/finitefield/index.html b/previews/PR4245/Nemo/finitefield/index.html deleted file mode 100644 index de19eeac333b..000000000000 --- a/previews/PR4245/Nemo/finitefield/index.html +++ /dev/null @@ -1,47 +0,0 @@ - -Finite fields · Oscar.jl

Finite fields

A finite field $K$ is represented as simple extension $K = k(\alpha) = k[x]/(f)$, where $k$ can be

  • a prime field $\mathbf{F}_p$ ($K$ is then an absolute finite field), or
  • an arbitrary finite field $k$ ($K$ is then a relative finite field).

In both cases, we call $k$ the base field of $K$, $\alpha$ a generator and $f$ the defining polynomial of $K$.

Note that all field theoretic properties (like basis, degree or trace) are defined with respect to the base field. Methods with prefix absolute_ return

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

finite_fieldFunction
finite_field(p::IntegerUnion, d::Int, s::VarName = :o; cached::Bool = true, check::Bool = true)
-finite_field(q::IntegerUnion, s::VarName = :o; cached::Bool = true, check::Bool = true)
-finite_field(f::FqPolyRingElem, s::VarName = :o; cached::Bool = true, check::Bool = true)

Return a tuple $(K, x)$ of a finite field $K$ of order $q = p^d$, where $p$ is a prime, and a generator $x$ of $K$ (see gen for a definition). The identifier $s$ is used to designate how the finite field generator will be printed.

If a polynomial $f \in k[X]$ over a finite field $k$ is specified, the finite field $K = k[X]/(f)$ will be constructed as a finite field with base field $k$.

See also GF which only returns $K$.

Examples

julia> K, a = finite_field(3, 2, "a")
-(Finite field of degree 2 and characteristic 3, a)
-
-julia> K, a = finite_field(9, "a")
-(Finite field of degree 2 and characteristic 3, a)
-
-julia> Kx, x = K["x"];
-
-julia> L, b = finite_field(x^3 + x^2 + x + 2, "b")
-(Finite field of degree 3 over GF(3, 2), b)
source
GFFunction
GF(p::IntegerUnion, d::Int, s::VarName = :o; cached::Bool = true, check::Bool = true)
-GF(q::IntegerUnion, s::VarName = :o; cached::Bool = true, check::Bool = true)
-GF(f::FqPolyRingElem, s::VarName = :o; cached::Bool = true, check::Bool = true)

Return a finite field $K$ of order $q = p^d$, where $p$ is a prime. The identifier $s$ is used to designate how the finite field generator will be printed.

If a polynomial $f \in k[X]$ over a finite field $k$ is specified, the finite field $K = k[X]/(f)$ will be constructed as a finite field with base field $k$.

See also finite_field which additionally returns a finite field generator of $K$.

Examples

julia> K = GF(3, 2, "a")
-Finite field of degree 2 and characteristic 3
-
-julia> K = GF(9, "a")
-Finite field of degree 2 and characteristic 3
-
-julia> Kx, x = K["x"];
-
-julia> L = GF(x^3 + x^2 + x + 2, "b")
-Finite field of degree 3 over GF(3, 2)
source

Field functionality

degreeMethod
degree(K::FqField) -> Int

Return the degree of the given finite field over the base field.

Examples

julia> K, a = finite_field(3, 2, "a");
-
-julia> degree(K)
-2
-
-julia> Kx, x = K["x"];
-
-julia> L, b = finite_field(x^3 + x^2 + x + 2, "b");
-
-julia> degree(L)
-3
source
absolute_degreeMethod
absolute_degree(a::FqField)

Return the degree of the given finite field over the prime field.

source
is_absoluteMethod
is_absolute(F::FqField)

Return whether the base field of $F$ is a prime field.

source
defining_polynomialMethod
defining_polynomial([R::FqPolyRing], K::FqField)

Return the defining polynomial of K as a polynomial over the base field of K.

If the polynomial ring R is specified, the polynomial will be an element of R.

Examples

julia> K, a = finite_field(9, "a");
-
-julia> defining_polynomial(K)
-x^2 + 2*x + 2
-
-julia> Ky, y = K["y"];
-
-julia> L, b = finite_field(y^3 + y^2 + y + 2, "b");
-
-julia> defining_polynomial(L)
-y^3 + y^2 + y + 2
source

Element functionality

genMethod
gen(L::FqField)

Return a $K$-algebra generator a of the finite field $L$, where $K$ is the base field of $L$. The element a satisfies defining_polyomial(a) == 0.

Note that this is in general not a multiplicative generator and can be zero, if $L/K$ is an extension of degree one.

source
is_genMethod
is_gen(a::FqFieldElem)

Return true if the given finite field element is the generator of the finite field over its base field, otherwise return false.

source
trMethod
tr(x::FqFieldElem)

Return the trace of $x$. This is an element of the base field.

source
absolute_trMethod
absolute_tr(x::FqFieldElem)

Return the absolute trace of $x$. This is an element of the prime field.

source
normMethod
norm(x::FqFieldElem)

Return the norm of $x$. This is an element of the base field.

source
absolute_normMethod
absolute_norm(x::FqFieldElem)

Return the absolute norm of $x$. This is an element of the prime field.

source
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.

source
liftMethod
lift(::ZZRing, x::FqFieldElem) -> ZZRingElem

Given an element $x$ of a prime field $\mathbf{F}_p$, return a preimage under the canonical map $\mathbf{Z} \to \mathbf{F}_p$.

Examples

julia> K = GF(19);
-
-julia> lift(ZZ, K(3))
-3
source
diff --git a/previews/PR4245/Nemo/fraction/index.html b/previews/PR4245/Nemo/fraction/index.html deleted file mode 100644 index 022165b0e1d1..000000000000 --- a/previews/PR4245/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.FracFieldElem{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.

source
heightMethod
height(a::QQFieldElem)

Return the height of the fraction $a$, namely the largest of the absolute values of the numerator and denominator.

source
height_bitsMethod
height_bits(a::QQFieldElem)

Return the number of bits of the height of the fraction $a$.

source
<<Method
<<(a::QQFieldElem, b::Int)

Return $a \times 2^b$.

source
>>Method
>>(a::QQFieldElem, b::Int)

Return $a/2^b$.

source
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$.

source
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$.

source

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
source

Rational Reconstruction

Rational reconstruction is available for rational numbers.

reconstructMethod
reconstruct(a::ZZRingElem, m::ZZRingElem)
-reconstruct(a::ZZRingElem, m::Integer)
-reconstruct(a::Integer, m::ZZRingElem)
-reconstruct(a::Integer, m::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
source
reconstructMethod
reconstruct(a::ZZRingElem, m::ZZRingElem, N::ZZRingElem, D::ZZRingElem)

Attempt to return a rational number $n/d$ such that $0 \leq |n| \leq N$ and $0 < d \leq D$ such that $2 N D < m$, gcd$(n, d) = 1$, and $a \equiv nd^{-1} \pmod{m}$.

Returns a tuple (success, n/d), where success signals the success of reconstruction.

source

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 non-negative 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
source
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
source
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 non-negative 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
source
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
source

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.

source

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
source
bernoulliMethod
bernoulli(n::Int)

Return the Bernoulli number $B_n$ for non-negative $n$.

See also bernoulli_cache.

Examples

julia> d = bernoulli(12)
--691//2730
source
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
source
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
source
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
source
diff --git a/previews/PR4245/Nemo/gfp/index.html b/previews/PR4245/Nemo/gfp/index.html deleted file mode 100644 index 5b1cf0076cf6..000000000000 --- a/previews/PR4245/Nemo/gfp/index.html +++ /dev/null @@ -1,13 +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.

julia> R = GF(7)
-Prime field of characteristic 7

Elements of the field are then created in the usual way.

julia> a = R(3)
-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)
-Prime field of characteristic 3
-
-julia> a = characteristic(F)
-3
-
-julia> b = order(F)
-3
diff --git a/previews/PR4245/Nemo/img/types.dia b/previews/PR4245/Nemo/img/types.dia deleted file mode 100644 index 266aa996ea512ade75f40583ab76c07a2c200a81..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3033 zcmV;~3nug*iwFP!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!OjRELt$)VX?1NzX=Q9=MQmklGh+CKbfZ1hFcud0H*>{r6Az5d1KY5e zXy6EGAP-JWNf-$_EHlM+7!sBVYGy-|v8OQeOpvO`Ot8(xmR6>LO_?#{W21vKfDVe2 z&_NLlTX(e#d6F?t8Lo!0y1Bf|y`LK>!7xZSp{yQTA z310)EFq+!nNAurA3ZoYXTj7{!;ajGK?Zc}Ij!YV1R}A4%1Cy}=)(Yk`FtGE}Zc%G4 z!Hyj`#KQ9tR*E#l9+%$eU?5AAX@s!)!+HW2pl=!G z*zy|@kl(1t`Ayf9G43G*bLMI^G;RpCRtz`PGXNwBIBFuq`Mfn*aNRYUiEN8}` zOIlGD0qKlNHip{Er@a2Ffm#|}D5l+aFV5N&0?})_$6OqMPTnlH2YAt3a zhs2m_`<@fdVvDodeB5s)tV-H88{L$gp;^c0tc0CpQjP>mT>SMiBr2-T*;sK#zzMZ5 zcjPdxTtC>cL=Ok0hdf-Y#XM7s8ic=D!Nkh7ctZ}=7^*K$sg>yAFlwz9FeY~Rmf7LI z*QAt9vbV8s^Gtf7a@DYme!!x(x9{K)yNTXRw_50Go^de_nh9+}~x1M+b! zj)kx|c^VcME=z%i?WoAwD#xg})mC{D2T^B!1HDQNZcqlNdJtEc48e_>5LsR2?3jS5 zoVZ&$8CK@-!B3}=>lvlBr<06x=98NhyMA8{iNNWrYhlA*< zlsyky8ks|4z7QzKSL2fb>=5ut*dc`LQv4;ucFH0qcokBfASx#gY|4Cb#eu=D9Y_-S z7Dtp(Ng{|XN-FItjvnJAS_3*EYk_B5=9(HWYvPk#1KbX z=mQuFO9V}wAVTuIBGHRvoP>QJS(HvTJJOP(G&7K-S``~ig@+zewb2-ba z!15}`<%~^+Kt(5WVZNn`UlcOeLt$)VX?1NzX=Q9=MQmklX4VIol?9fPk+Dpj6>v~C z76k$s8_7YAB_Iz8WZnmmrG=Hov7<6rGm87DY-}pK7B4oI!+c9%9yG-kJ*3#mCN&gE z5;w(e%wTC#Y&Q!-kz!-Wv27BOQtW|J>=rbp6#Ffw*j=GX_OZm$)|ELDI`TUA#tyba zEg-JIy;U%dWgu0NZ&G|3YMo^ZBvXJI-%3jemaqUDWU9@Wc{bIi5ph~98Z{3HckQq| zfZ(k>fDM=j5cUU3YIPr2Ru)(q;zHS0X8g>mrVF}cG|+A4 z6R8$z1~%(y<`V^%Zw9)`%_(aB=fbW&5q6=c*&S}Tp@}>jPAT}=aOHOL!b~{BChkVx z$*a}L-gN;d1aJ4s=GQN%VMBqJjzz~orC&QmfH>q*Fcd-}!9c$iwXd`X#MPfm>&s8G z2_0p9Oy1a4QxeI@yU;aeu-k?Xv~=&(DE6WIn2MvrP2TLIG1W##IC(>ZRT3tzkbcvo zsPoECX6(GOLX`MLT;rHn{!nG}6q|;KP3>?@v1yF4N%Rn#0KCc|>csMs9bzYz6_T#b zqDL{U{Glk*+L9sTQyU~xfEwxI5-P{DH9pqVKLpmTE+JU3GmZ#Q6?t{Z!Q0|fF3)V4 zniBa&x3Q<{G>>iVp}nE9_x-{PG#7IRN(n8*OWT>gZ6}%E5)MAAND+KO$A+0H^0=; z*gxG=oI1@cFoV7rgUL&1Y3^5>79Q&m57|+x5Yz0d?zAze6 zjbO1iFMFZz#aJqQrNUSIP|4G9pN9L95BDMs_i4Bv!EoPE%94F7I?M4}~aUA4WS~)pr`BnE5 zjqQVEc;o^sYYMQeDZpa?;CqEd^z~V{GbUvRm72BUQn7=Svm_ArQb$07Q!th(;4uU#zX@mxQ$sxm zs1=qeOpP&2^|1?wX4ptN1){;V8HCzga0%Mu-QE;h`DMk%PrCKqWV$?}vlz+d< b9`fq_JO9S~EUWD1{k#7IAYCGjfFRPLh;(;{4kC>rAPk)%-5sI`DBT@`ba!*^ zaewDO|G&>#=geMfySFg&zVGwgaoyK-JrnRmQTiGV84d!0xF#zjp@KkMw$5qH{SS@S`0Io7r%rrKhr~FoEh5^`C4{ke4(|U2dl&-58U3h>yA4jw08)%=R5b? z-tvWRx4o?i_Ymdp+)kJ@QC0mo&&ymH7>J`}Wp%jq$JEp`VJszDMnR#yqhoKDq_?Lh zid}!LmDLS9EM9mvF79OU+^|3R6Q6C0Dk?80=c8G#-OQm85}9Vn!pOvgf0IM(ORoD+ zj%Kk?y|Qdx8be>cetoU`{#i_%;bF?#~~06%eVP2AbbWN+QGi;&+v5^6!LNP zW@Iohh0bu3DRA-h3dQ-%_`lZ@Alwipq-txV&Y$Xvj0>87V$CS9gv6}T{$kc$+ZPuV zVSHvp7V^V{duxzV$fXN|{Bq^yEOv_pPwyMe{K4Xr@7pyhSvwk66PQ*deK0$c^+G8f zg*r(|Nvq4hkO;e>;^K@t6XGKyUkN8tUSo_1Xup5+szb)t=NvJQEn*1_3N?n92bx2g z4DQ~&+ig~A5o%J7!z&#o8Y$N==dG|hZOu-DJk`~y`DC^_=ExE8Bh>i)_wN$ZWhSoO zj5*ns{l*%yY!`*>@hlw|d=_-Zz z-3z;J3G?kn#fq6Px8>#K7u$k^gHKL8codeCuhFG;%PbSCFh`n|j!d{dE#Y@N>82~n zqHcC~Ss69wxXH=MIaFTmygre;|8btynX)ada7L5<-o0OQ`D%WsBzqMV6%&r!qoJrJ zTCs}cC_(=+shF6Ul_Z1Ai_;hKyG>M{K8+XMSn)KMkVo0y-0q-3erh*@YtCexbEDcD z$@+N#=crtaeYy@jY8Y*vicuVb2a&ofpcBITw-uTLu zD{tSv?OE*V>S|~Z6QI0xE9=P}EE+E_uj|*ZI~dv6*r0eU7aTM+G{nSw-aH>-s43X? z)w4>=%+zKf+1qU0T{ahpprUmU5EhQtsYec)l`=-iR*<~nLG_!J*0SNb2{(z`Jqg3Q z)@sPP=uidGr+hl_@(m9+w@!u4*Q$i0qa)aj6>(xF z2Uh%f&e%cOX;iG4rD{jvJlk^pMRaLIKabgXmE)d>yQAZ7f42H+uFLLH|I*Tu5lgMz zpTLMh1_p*#uU-{iNH?h$K7HM5MHta4vELeei)-O=cS(~$vNxqx@L6;&1HDBh4(2z< z0_E-=snV2;8^TKz#8Z5s3C1nEos#>-yIOl+>`rp8>&@}Va{03tS!D`}xN6?Jd$*9^ z@~NAfo0Qbsjj{2*cFok6Sp5S7dQ}bq9hGjo%*Pkqy^v~3Uhb=!m39pANy1begO9!? zUCs%6&Q47?w)-ZA`;Q9`s+~EKnTKZ}rd~c(|C-r+M?5mze!jzUxTq;+D`EaH2!YzB zv?y_%e=>df9u2*a(Aea8XT%rry&DZCis}{8atT71*Y(n^E z+_4k2?#9N(u&2{8BZi!X%bq9{ouba|cN$@JZhwA8nh)l6FMj#*<><)GZsx%m6wRUZ z-+z8Zo12*}>>O^-FH%dnOtaUh)w*mN=;~4y_P-@qBMS3$zq?n5fvWB}bX&=7(wNl0 zUMB5_R8XSnE|12>!otGEC2AildL*F}S1V6t>x%6(6zD0)+s=~%!7g4-2 zpHS9yF$(oNJ@Vh)UL(3e5Pu6*qB@j%duye*vj{g<%JqP@fyz1l5hfl*#j9T=%ilU{ zwFLOFk1dAoOXa_Xrm~Ryi*d#FBsZC;gW^XS|Kyw2DqKltH;rddsj3QgOWL)`%t~W- zQ9+9K1MjhTo7Y_V4)4aDx2(NdFYXc+TlXf=-Y3t&9gVZvne%tF<~+{ar5>!JLTQt> z6OTXHJjt`_5oQut{r$CVv{I5uC_%D19`0S#zujzDSIp@--$4s;vn{pf&ih{XUkn|S z_9?wP@|K=&r1J*_hp$O8Ao3*twK4rIJ3BjmT(kZ6 zZ{C*8iKL;{rw+k|bU!EJnJ1R44cE12W?!^*xhqOEa+Rvq@bGU^9qwghWE7=Jm!#Y= z9nSIhav!dYEEl*$epkAvU@r4nwwmkhv`-70RYu?i?&-Ko;$9>I2f<<^rB^++T#O!SP8miBjU`NRhSTKzY^`WI@V z3zU0IraR&Vix*K=Rawc&GmbCQBzZsl$7-9S5$kvp!$-H$F&bcK4A-^ zpYY{nWHf5sN)r<&v-9h!Ak4GAZQhkpoMNWJ zh<5cyUxul1(qp@wPCB#%-cncR_5Iy-L8p~)9v-H4;jkxR{8(%S1{AUCK zXLvL>_+l(dNJ>g7Dt1hN^QWVuTV7gvdyTxzd0o%+<@SrG8ILuK46!@60V_cYMhZ|+ z`_5jP5=1Ix)tntI^Nu_8!js=5Bh%8>c3-dEUz@DgZyfT_c5^$DXRlS&*B5o&npHsY z$Wn%~i`iY=pp=!BwPu_Gl&Pfz6rb;T_@qvF+9J$t#$c>gwv~1O*f_ zUhOSeZPW6bmC&z}dT1-jH_E}Oq`N!fBV3V$d2Q;k$Pn(OGqX@9Yl zoN24-PHbHaVy_G5!P6|HBA^^&V@JP~mhRAp$HpGPReF4>z0Xhgq4I=Mi;D2@IIU0A z?vL3kLF0gnd7o@HQwh6Om1l6Ky^ZS0jgBjxJqx;@vvJxfyieW>uIzU!YzXpImiRaI56zvr-n zNbIF{Pyh|KD7wT$v9g@cT*6lKR$Jx`~I5XdX4>PndRzed9*;v0A?$8!ypUf zhp_PYe80sPl9mDK3YbyZ`bBpUWV}5E6pb{2~U%qUQnR#JJmXE;8IW!BtA*`N76C z0EOfys;a7YBIRZ?NqW-dqf=5+Ajd7BxBvbguoIFxMNiL!pyqbnG8Audp7boY80Hjj zfjp6OQBzE)h&asa( zHa0etL{C-wke4yhx%xy#25YsecX`*LWCgZg>zvv3Yo ztSS$D{1c5$v$?tHzPDogq_Wk}AeFW?P%Zlb zSqPgNr~OC8&NlZe5M*cPq%y=1|JziQ4M+XL@dn>5%v8`kszZXz+zLeBN+NRZaw(NRAC@#EE*J z!8MACiy^;GcL((+?K_2eg5WM&_dKOcV3muY?|Jlpc}6MVaEG0p2`M2ZrS|Mu$j$rW zd`a(1N%cM6izxGW9N4(4ua*3njWUujpPmRC>+0fwdfh2*r6oMhu^I0gnTY)5hq?$W0+p=QSO1tkV|}GdB{w&s?j1L(Q`w zNn$d|Ra-tws*M~KwNp?~FfgE{NrTU-KRe2Hyf9KsMoqn*$6AI1%Xz8Z{^EvZVPPTU zDg%;5qriuN6PCEE>q)}A<=LF9Nq355Nn3^jipp()1|P}%=)#467ZZJt%_a=V9fkKSftHpQ2N&0UcWL(B-qh6hd=F+>Gi|B426c&bm?HW9% zPDMCD%9A?@9$T{FEf9+Fw}L$Y^1>D{Akk^$AZb&LM=1cM<*;njYP8aR9=b!mZZ)H$ zM9(95G*1XkQ5r+2T04o*-mc=|<>lum@>s@lWzWyeh2G+NOYk8+{&c5Tsaz+H$Ckpl zP(!FjxicsA4L&ZC#j%oAb)h{Ug1H-rnbT zpJotGkI4;Bm!Bp@I<`D`)oTgIQZ(|qu-af$wHPRZ77)HCdsxn!>EK|4T*2u zh(w_T9hX!m6zaFHuQG&4&A6OvL^G+Zs6b(zv(S5kXj=XYEsf9`v1wqa%{ae$^=jJ8$9%2QpNE5d zmXmd-6YlE_$Tk%3dW4dQt-3`(KmaB_6+Kdeg~aJATb1IV2{%h|>|@5|A0($=37XXA z`8u9+bm0syHRig!AUB_C@ZI^Nbmh%-YM6*wfC83iX}fOU0`tdK!y-+UzHmz_cv#J( z{lGROE_umcQLNkh`}w)Kp3{D$arv2PX@(6x{|;k`@Od4`ss3tbYw>q->6~OCLY?Fx zQju~DEL^s~zsJQ<2*f8QS_^+xf*RdUZ5h8%g=1T=&Cn=&v?)mfEG=`hMn=J57 zcU7J|d17gqyS>{tFi_NX-(_QJ?lPSaZhA(>)?l+f0ZCFopw9ZMBL1&kjTXAfvOJcx zH(roNy`-Wdo`Dp|U}v+nMPhaHCuZ1mTU}Swjy4WjP*E$^$|X4q0rsTC+K)s0l26T; z=l(b{9DraEKlBKg_y_ZJQ4h?cws#MXkIx~C9BS;3!ritDxYV7Tc;ZvlvWHcsxg%p^ zwVphA&KU!QOZEBJ4_)u+q~pf&9NQ-r3!ACjm$EX)R3bTK3u?!Mx42IWLaRS~Anew% z3WyT7yBHpn^)!=E99@;Wy2R!sBqW4RHohUl%O|~1?GA6nlQqgLZqa<-)y5TXjEG{mW4db07zPuvzrfk8d@T-nmf(`Rct+|uix04AjB`K2WXEY$ZQ5S)yQ}mG$+x3aC#46LJyx zuVGo}e0_a)bRJV1KUd4sX|)}LOYOSVN+dt%m|%~I_1%+ObPy0Y`FHfY&_Ket9>N$P zhc#Sk9&Kaf;J{63KOMq55zffMWN2(GxP7yPYqx-ke$f043Hn0pkoPRjw*CG6C|+xl zj`M}oFuu_2oE(qi)$;VfYd+8d!lU24d$%@T9kGmW$tCQzlQctE3p31zOIL2AcTjNV zM+hAfdLD1eA+^^54NY22jSgSnB_DbKUxxm8Y7UD%4BhdWdbMs%O-+Rt5rlTz)-@Lz zjvax4256C~7_SBG99k=lPKiNNU^P@P06;*ctsZR7kmr6WD=RB1Dr%zLWmByCbbah1 z>}se~7*#x!=6-ekfVt+Trg7K#cz--fx3$XoI9WyQGK+w~K(m;e(@N0UQ_Qg@rP!U} zW@Z=CqxF7vbO0rNayXv|K+kD91#sl^uB3-dig7KSol0_YMe2_L#KFb2L{##L0Pjq* zMny(yhB+>8^9e2D-&O(yBILej0p((MSq-`@y3c+3^eI(3Ozt|_NmfqINxXiWP>Q2ekF2^J12_`6lX$6VAbTh43{D-KAqu_(>I*fw<_i&fkKo=}U_3?VWH=sFqQb5V!?HB)nkbv4r>R!DBR9Wr3 zzNZ?jH@jB74kL4YpYnl7a4zO;XC>j?KDZ_Cv%`6q-GC5Xz6fyA72?5ZWyluYi&MnK zWgb5K3dmlFJWKtPushF(2uu(QTE_LywxXc`=9HE32nrs@7$+36Z2(0D9s0b+X1b9` zNeEyY$uzCz13JS|jgOZ;5Fx@VDk@-L&etexG_s>b)*So}%CFh_IS2qBp1^r+ET&!Q z@#8o_=e*3uj~Yfsj2|MJr+l#xx0Qr8FVW2UQ+t`1m=tJE{fXAcyLRo5D^8A;&&NRmLD7^i9SY>!vG z1u|9n>C@gm1)GZsOXRa?jfLC#5k>QZYN~JoSe%o^_tI1}NIt4ZO8JABSFQ~7_un8U z=FYMUk$TBZcDM{(WZ|SrsPkUrPe#iQP*koh?z%-K#wz2>T!!nO?LY^!r*MWQ0C0Br z9?{L4e18W?;HBd8hYbp07K2L9lUY&mNuiiA6s8FK$Babg`&imS1AdyasB1-NspPGR zFh%pNt5>Q5zdnEd5NA}|P<<~5k#RctGI_3PyHboG?>Cu6!wmRk1W zGQR}iF}?hG*9i-rWd{KsQ7*0s9#0C=G7T1i_|VdboaIgc@Cpj03Hn-Ea?8nKEkxpI z1?107+dgs#r-pNSCMF{BGnjS+?hp|Ya=vK1B(Ulcn4-X-T#YRI3?Qv__tKA%NB7k8 zi2J9K3WhB*h@gu*h^MP`UxVSUFh(45FKM?cR)LWyo1*3ddPO@yE5o7zo_(y`I`NGG zR4$%Xn`5AT;__=?8OAYHvQ%f?R9@W5PD}g#b%_V}UZh-V_vhY42~W=wR!J<|GX-iO zO%FRSvR*^4K_(26JN+xTBrG;ha$uEVOhVAmv$5sf(oVic?DW*1lwcydsI{s}F-eTYiL)r{jH3)o7+$cKpag74zs9HsZS;Os@~j z2jWCLj{x?-5D+Cm(Rn?TfyR>FCyEI1Zg*{5ke2o}!H39521k~Ji1_&S1dNXYB~O+5G;FT~mck55ypXXAEc(AoPSf1*wejll&l(d@Oe` za}z!HV)}f2D1ZR)v2>_dgD#_{t}aiB+k!{MfQc9-BqDnA`Zd6cGU&39nB7J(>-Fb) zBK7LyAoTXpv|vH_4E2M)3ZNeN<6(J4snl*0ZZ|&Wa18W)m_x=xTTV|;2R`oXj5m%A zY9?+fWP2%J#;cCriCB1jK%Q#kh``YSDEbhv1sQDnN9g zA5%I*F&>ady?6b#wIQYrWz{aC;XMrFK*a$e2ZE32RtueqKZczzEEwPK^>y!NN@oJ` z3D~Ce@XTi3q8%`y;2JakF##^5x3{@rp|}VkFQk ze57Dd{r>$sf%uMFZC{~}4y>8j45LD<1QyVl?_r^F9hTv5fawCk?ANx3t?hlvT#6*g z@@VZ@TM+qx-4Z~@T~`@o!p zW)>)(`jf37c)Bq3#f@7nUL5~#TS1oUm(QQ?h_`@nlooo~g90|1`=Pk_MH)kx*i|qu zir_(}$D&&dBQj3F@k>UA)RIO+G(?gZ(U{|)?)3CDG8{;68A{v(P6!2)SWGGx9|F6j zzPswo(^j*2{rsWD8Z3F2uIK^eLc|))wZ$OAp=?!XgbiEFxhBlJ*6K|LpBUOZCd@<5 z2l@K)!h`u_RKn&#RL%UrAtEC3J2zaV0Tpll(_=;+E>_m|uS+?90Cj(To|JtPs&k(~ zAr`teyK`+=a=9}{1}feRk;+w*$12odfyxSDjwJY7 z=Aj(18u6e^y>*?O%4+*1joLmvTuy#~YBy5jcM&a#LnO8S2)>ny)>E6qsI8qCO72Ts z!as{?H=VqIB6;5#Ybcs?!%&pu>o&(xD3HYhAvqMJ>agvet`#phj5{UTSIIJ01ib= zId0tHM{w(_sSPakXQziYJ_5?0)e(ym<_$!Ky#NYz|^Fsl*{7-vF{+s{zUHpIEpx3)b1A(UEe>>#Ur<+-i5IzI`?vRl9 zR6=(gZxU+MdwBwXCtSuKIwMrZn*V!RomDB0uR8*@O$CFXia%mX@eHV9lo0z8a7uHB zAwR#|qG`3=Z6eio@k+I`2XZ6%k-r?JA2%~IGkgO7x^ZLGuFzO;_`s+8FVoCeK=x4m zuqr3s_#-7J_IiRf3jn2OYHDsSshsrNrzggCfzV?*B|V=!3Gbs3`xOhCM<2~WU7hDK z3<=Mc?g%k4Gs}Hg{b?y0v0P1tFM$xVhxxx8ZHu|%k!Z2ch3*iD|FKG;q-Y}yL|dP7 z3$c^eudj8NO|Ga%5HSH2H&;P_9B9YOdGjjU+iCf$S1?AozyPzl`*L2JXq9OCBxCNz ziXLxK{7|1=#zDh?KWv^X|b7GxjP!)Y52FIX?2pWT@YYmVDMYJH{Xn3QtAGu*gDs?%C8%c7b#(w`c2$A}RM_N3bqsnX=6u5>L+W-SWfv+UC zQkGQe`x`a|NB?DzF#XXq7{#hB@uq$g&Fi}^e*lFrnoYMT!TYb#!fg2vKx9sKwz-*5 zh}K_^!z6c=(t@|;+Ka%oJ5?XgeBT*6i&PVVmxPv%ZrB6(%Z&}2z0QV)24Iu-I;WFS7QFiKWHJ+!}+GKmm&P z!!!_9vG-eML5b)Kw&a)Ub#im7YBEsHQcdybj3UhRZz@u!sU=S0diwO~a7jewI5@%x z#fS0@a+zvKnr-1x^$0hG*vCQ|UnaCG{q>$XWoRigP&C8%;O3Y@abTFBx=^D2r5od2{GHr+!Q!fAqxRVT9+Zuwme$DDpI-s-lz>z%6$Njz%(ccV ziTdrQ9wTQepeGLf+M(UstD$dp0zy_RMQfih!*aT^bMr>7P1YM6Vf&ELe0@<&dHzuI z(X!kbY^O*g;pzE#((Bj1GKNwL4wwijh`Z}AaH9wqtzq-d*g~moQneOveC$RyB%ua3 zhSHJhf1L8&X9)&j!J+V5DAju(AD@B(j^#tkkrHe?ys`xLs=Um&LwS&ffF3$xXzf71 z%A9Hcx>#0yBAVV+JBtYZn*n<8*Pi3so}Zmv?XpRGJP)#Ko=#=s*{1%^eD3_s zzM2x&8riIsc4y!Th>nL9&)GzgOi0)Zm4jeLuoAYPTh}yLVr_8sb&| zqL(+v#1zy7n7B#Ar`0fJU*6;+>XZqLljjO*nJ zchEDXtHi(@|KY>$im*>-hl^~4PMgq`s{C^WyZo9c23Pjtt+&qzk5Pq|@cVuE$`>KF){0K&$eWeS71={V+NLgj8cx~bc5q`D9Y$`-Kx zXa^VkjHg_tn7Ep_IN@`CK8T}sLJ!%;J76wBp+;-?$c24O=TQZjAB`NAOX-*Yq%bWA zyYFo%Ff9!buo-amn>~mJprUzS`RWeI{p(|{#d^9WeRCxdI)^RoMzujJF9d&1G|%Vn z$E#R~RM$Q{m(Y7^^YDYE|U3!!9-Q~ok$ znT@^kxZ@yjJ3{&J}{j1VquHw5gdNUIyiN zC9GTgcJwq7=_;q2&D07<2kl)or)|7t#s|yQ$|dipHagT9zI>l!W~1!+5SNwy=TB>E zExD!HoYVS%w!EF)FQ@d8eip9Fmo5>AU%{i$c=oJ6McX1^_PbyWv)z_J!yyjkW5IWc z1S;@@dT(!W8K7qF-Mfb>!HoU#=R?Fsqx`3JSe07I@7qH08yhze_X1{T`DGOA%9ZyX z@Q{V9?99715;;I+!lEGynFB_MwYfe*AI9WS`cqmC#yQ+)NmuDT3*dEtk?GBys% z+og8^dXq>TavKdXLFxvDMgcT01}|$&WH<=3AbsqScwIL!pD&;5$1zi% zaal!r7WeG2A`D&cJD+Bv@s%pd>PD*lkxu{-lN{yiOHv_ZH>jw*U^SgqM^;BlvtbB= z!I_3;y0}vW#qpx?7kfR$&6@{6B2}B)8+RsHvZfxniGdtJ?R|0|o0|SFJyoXYC2fuN%9)*k9*Z}p>-rBl2S$_^2z{SM{Tn-iuxNz>N z<;cj&#@v4?<>FGYoJtAUc04BfZcBSx3>TyTDT@XNSe@EYywzKQqRFSn`_ht!hnvf4P zz|a}BT&>-~`m<*}&pk;xx0N6kV2we|sCHZ)sHosmH#1NEcS<;E^>?$>$v1RE5O21^Vv)R7P6>QAg2)fh24+|?k=a6aGKrST|wtHkKX}I@1D&B%z*VU zN+DjL^vf5szR$`K*R>Mwk1ASPV32D}5Ozl!Puf1+-||>%yMdN=-|nqI{pg6}=i=bt z;N{&1y8toC6yF*UBk|m(J>aNB$27P(0%&(_(PjluiYIE1ff){Y_#1_TcKgsXFaTo! zc2NdyZf?MW^RCJ>0R+G2=l7vhi|%wi0)Gc!knckbtZCqQ0Fuoi{D3LJ_22Bz|`2aOsmN2*TX_hL~LjY{& z2Qy*!vGTWJI`SY`9u5i!h!JwN^YlCg9w8^_@|7!jaLtXWuQ2#3$;iMjiwaR?vHUlC zOzrMK{n;*i);Cj1H1m%y0L};2@-adR3LQN?;M?jay^dFL{CACG8xm<|bP zDV_WTZC#sfjo`s`Ug(+ziF|Ficpg|CASl>%t7f}3Ud?n%Q-jOP6qs~5Ik|@qefy?e z9>C;$z!=n&qLS74?OSIYKe({t;1wOs>v`k=gSvGjxa-CsSHY993>FVijR`0yEb?c4 zF)-iaQI2r>x|jYluJt#`>3N^-qGf*ocz0P?4C%H<9Kc6$DDs(hx=R+(m9kc~%=VXh zbWK1z*7!ql@$j64Mo_~RYh#sMG_%0==4E9Ss$0N9sw7sWT?hY1lxRB`SfsH6-n|VgUg&UG~SF zO4o~+d)$b6)MmX5rD4#+LH6=Q(`Gk~|x~i&uu&5#AyoxcLemwTCfGcchE=&;K zqad~vsy&=Tspsj~X1oQd1$x1j(0SieCC{x^ro2nvu)zi~cyF4o<7;Q2_IuzkEFhkl zna$uyVX`afn;uf!3(ZH2xqJG+qoNPpKtMp~tMB!Uf~T^%xj7M#3EY`;(Ff4Q%^>%$ zUAqQ;S?CqE3{>D(NxTVu6$8+-f+9DB*16V`7kV@CJ!Q7QujUG1hw>wFx^ak9ugOS3 z9g7V^w9C{H0)6*)i37pCNbsd@H{eTW^jd@NkG?(o6PAqSIlEYo-z%~{~Xs@d2GfRQ&Zgk;9tP0<)Q2gH#Ro5 zIkb;PKtF+?XMs7ibY~Zo8lUx4VRx9gUfF|$FbMny^pjICx7gJsz;btdx}ORI*c=Zj z@J=8Xpa`I{1WVC%ZUdW`u7dpwjP&mx^nvRD)aW6TQnC=K{K0LsJ;hOg5{1^AjExKp zXXodOO$SBaxq~Uq0ID7MKiKOIQnpDiG}f^F{H~ZsD>t9=;p28<hz-IA z4<3M$iVT0`k5?Fzt(HrR1V1b**hcK@m`ChVjKhqsM&A}X?DEAAmP*}_kibd?qe?wb zIX?|O3tZl>6oxNlOBgJ+He`EV}(uvI}ZoY`-i*k0a^!W&1hN zTV-b?3SXYwjJzYRER5Es@4xyHf;2>dq_Do+tzuycMA1A@| z0H_nNs)*+H%EDPMy?jyX9F2=x z=}ko%3&cumr-IYO5}FAz90-o(^hTm8t~b%6_mu3hm;H!Vy_dfm6^l-HJspt!G#b^H*fKeiX~c>va+p!)#59c z^ZLzTBB~B~!EsY-JuDH6hKTX;M%&w!bo*{rvB7%|Xc3;}(&fwDnHb2BOdlV_h|ABm zwvQYBi925}h0XwX+%CThk33@E^jVeJz4JbtHR~PW3;hLY^T(H)-zKhOaUzxU8c$-R ziJ4yq+E{?QoFFXTGI@Ts4-*Q2rMv9xof!8w%Bb|!m?Kx1QLHx;o_fptWcj7B^3cprvltMA;S)S^U zi7XB)6QUB1l90os+PS?vm`~aPv`#I!WA@f3^`AVs{mcRn%3r|Iju;+#?G0hNLWTq6 z#Wn`|sf(A#b>96x@PF~HWY;{d!tw>PUGZ+@8ep)^BemAOVmA9F;1!9NmLcEKm=v z)864uU4c;E;&fWkfZ7bkRB%<}%u7p2DWZ5nk~S|*TmWZ^9*k^Bf5BO9V!JzNX#gYP z=-N={8${acNw6Cz+SzTv9oX61LmnwlpMYy2Gd&$$a={QZS@7af>h8*9eIlL{8zvxC z70arc8V}&1RV;Ox<7%nJF8Ji5L2s4gGRa@S#YU#O104>K)+p#}U_BoPX3G7+%6RqQ zR~2d!YHB5aru|?z@WXrj>T50~+K53!Nh$oi!3R)Q%;OB`z__H2OMRv=P+0@CL&J1- zCSq{5!(e4{C{r7nn3%}KI|%0ag98^Ot8RBtI&Mn?rUNI%99@`D5wxoA6v#;+YJswW z;|Op&(jPVu8)BDyD7u~RTZ~l{R#j=0e1>fRVNR$Mj0pOHT?nj)zp%y1K$gU#;4845 z0ndv>cM2GN0CaB&d4o3y{zHzCs)YjXnNxByiH6KLEbxD$Rbeuv+c!XyFkFIz5YS4k zK=K7tIK9s9#RI~~*#Cf_^w(dP=&@}jL^ucqI+-;H*y#^AYh=|CYJD+oMa-jYv;Nu(O(n%m%v{Y1jJ}}5b5Lhy1 z{&#eS_O!N(qKz9bn}u#>l>g_DZhELVTJj7ph2=U1?+fUZtoQE0@z$ya$i*wy$cV|v zjv$&HR)*epd|drx4LHihxW*X0SLVP!SpU<52SFR2nB%a5O`;I-H~^1yDagjqnQ%y3 zLA)6Kk)n!DG==0RFr(CNcL-KiR_^_{35*Pnf?}uWxd+Ug!zZ(|hKJmLtuQzV0~q0g z0;y(g8c$Pz@d)CqR!(x~~f>{g}h~kJuq*5A+BE8wV%F z+R?7d%<|xpLIZNZ zT@D$F|INeVA%ym@$j$#E5(k6os2UtTiWs6j=+fsZ1-1Sp80Fx zV2sG>#sT%>ze^qFzYD%BaL3D9S@3I;8ZpFMhYydXfN6!5RgFnYcLKl-+KWR^ZwS3d zs1v08iHC(iV?h&zGacMo$>9CS?&tAe=>=K87F1avbbA+vPTJZYkF4413>g$II0y_V z+RgP2j~bYo-i?oW|NebqVrNEt7LgVSKB8e8K2)nTkN~Cug61Ze95LMXJ_$IQr8<7; zH*+dWUi@ysgWD+t&E4trJ^AsU1yM_q3@$&)w>8fK2?rM2NLCfN99V+;`ue0qIV&!| zWxwbn8uH&OaV3=Wl^ZA^7jW5Yo@i<=CSioX&~?4?=3%kbi3T%Orl74Rt6eoPH zr(c_<<#`Hk<{#LPqaZdix!)ZVB68Mc!cZ|kTWZsZ_SgW}0xQb|47}hw0}!}mVA*Kg zEa{T%KpRVUVw~z{*?arTsA%T|f&wV>U7P1B{9Y#&;4;BQyG-D)oDdwD8XMDbZw06U zug-7EzK{P}Sy=d?w`k)uT`Na`9r7kMHT$#Ygl0WrD^oalsWKOQguz#O=ia^1!k7N- zq$3wgD9|Pdrw~fPsHwq<+vq8$An4i+UpA5r4z!%D3nK&29N>`egDx@a8iAb#qbOo1 z{mGrKV$8q(3Tczh37Fy1@h;6?23R;HYF3Q82v2pePE{tV0GU#6^}Ya%h8G948bd_!%If!dY(k zJwSz~sav1m;59vyQX|@!^AXA+CMG7@2nGCyO7q1!eDoU$si;JNb@?ZYRKN|gj}DXK z4Rf81o3O+-YAPxp>g&&eHG{6g=*TiPgN_kR813t!0-Bqfhf#~NIkFf~G;6YuWThg? z(T*L)Bw=^7N#$Oo4X>T8BUrxVIHuy^jY-(BAem3@C?*Ik8VG|xJP)3cT{lmzEh6ps z`NN$Z2huke{#IHA8=%+m;cQx7UWe|D9_8bk15}(bj~&q7J}x*29GBHwML5!6@J~h5 zL)-XbfrzV=S5qT7X2=Ie)AFuRC)hXQ6{XQ5-Cw6(Tvk^V;g^zK?9C2?@#N)J)cF1!bMjs^(_{GFN$Wm3i=e>rEl5~g8z?A#PQ#Bu6f7D3+(<7 z;@p}*J8Lh!xJC!O)ZdZ9T^znu0uEe6w0@t1$)HqgwL%;fS;3&X!2x?3{^9?&i&XyG zE>aaGmtM3l$h0h%cAzoEjLxvkfU0ruDh^vm=D5$s#n8nry4+}HfNBh;kpGAC1GfF& zCJpN8i(*_*F~Eu~OX=soGEyqPL@ -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 = finite_field(7, 11, "x")
-(Finite field of degree 11 and characteristic 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, Map: univariate polynomial ring -> residue ring)
-
-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 the FLINT C library which is installed using binaries by default. With Julia version >= 1.3, the use of this binary can be overridden by putting the following into the file ~/.julia/artifacts/Overrides.toml:

[e134572f-a0d5-539d-bddf-3cad8db41a82]
-FLINT = "/prefix/for/libflint"

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/PR4245/Nemo/integer/index.html b/previews/PR4245/Nemo/integer/index.html deleted file mode 100644 index cb46d99b46c2..000000000000 --- a/previews/PR4245/Nemo/integer/index.html +++ /dev/null @@ -1,183 +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 ZZ.

For convenience we define

ZZ = ZZ

so that integers can be constructed using ZZ instead of ZZ. 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$.

source
sizeMethod
size(a::ZZRingElem)

Return the number of limbs required to store the absolute value of $a$.

source
fitsMethod
fits(::Type{UInt}, a::ZZRingElem)

Return true if $a$ fits into a UInt, otherwise return false.

source
fitsMethod
fits(::Type{Int}, a::ZZRingElem)

Return true if $a$ fits into an Int, otherwise return false.

source
denominatorMethod
denominator(a::ZZRingElem)

Return the denominator of $a$ thought of as a rational. Always returns $1$.

source
numeratorMethod
numerator(a::ZZRingElem)

Return the numerator of $a$ thought of as a rational. Always returns $a$.

source

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 non-negative 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$.

source
>>Method
>>(x::ZZRingElem, c::Int)

Return $x/2^c$, discarding any remainder, where $c \geq 0$.

source

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
source
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
source

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
-
source
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
-
source

Integer roots

isqrtMethod
isqrt(x::ZZRingElem)

Return the floor of the square root of $x$.

Examples

julia> isqrt(ZZ(13))
-3
-
source
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)
-
source
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
source
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
source

Number theoretic functionality

is_divisible_byMethod
is_divisible_by(x::ZZRingElem, y::ZZRingElem)

Return true if $x$ is divisible by $y$, otherwise return false.

source
is_divisible_byMethod
is_divisible_by(x::ZZRingElem, y::ZZRingElem)

Return true if $x$ is divisible by $y$, otherwise return false.

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

Return true if $f$ is a perfect square.

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

Return true if $a$ is a square.

source
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
source
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.

source
factorMethod
factor(a::T) where T <: RingElement -> Fac{T}

Return a factorization of $a$ into irreducible elements, as a Fac{T}. The irreducible elements in the factorization are pairwise coprime.

source
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.

source
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
source
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().

source
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().

source
rising_factorialMethod
rising_factorial(x::RingElement, n::Integer)

Return the rising factorial of $x$, i.e. $x(x + 1)(x + 2)\cdots (x + n - 1)$. If $n < 0$ we throw a DomainError().

Examples

julia> R, x = ZZ[:x];
-
-julia> rising_factorial(x, 1)
-x
-
-julia> rising_factorial(x, 2)
-x^2 + x
-
-julia> rising_factorial(4, 2)
-20
source
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().

source
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().

source
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$.

source
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$.

source
bellMethod
bell(x::ZZRingElem)

Return the Bell number $B_x$.

source
bellMethod
bell(x::Int)

Return the Bell number $B_x$.

source
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.

source
binomialMethod
binomial(n::UInt, k::UInt, ::ZZRing)

Return the binomial coefficient $\frac{n!}{(n - k)!k!}$ as an ZZRingElem.

source
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().

source
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().

source
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.

source
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.

source
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.

source
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
source
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
source
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
source
is_perfect_powerMethod
is_perfect_power(a::IntegerUnion)

Return whether $a$ is a perfect power, that is, whether $a = m^r$ for some integer $m$ and $r > 1$.

source
is_prime_powerMethod
is_prime_power(q::IntegerUnion) -> Bool

Returns whether $q$ is a prime power.

source
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.

source

Digits and bases

binMethod
bin(n::ZZRingElem)

Return $n$ as a binary string.

Examples

julia> bin(ZZ(12))
-"1100"
source
octMethod
oct(n::ZZRingElem)

Return $n$ as a octal string.

Examples

julia> oct(ZZ(12))
-"14"
source
decMethod
dec(n::ZZRingElem)

Return $n$ as a decimal string.

Examples

julia> dec(ZZ(12))
-"12"
source
hexMethod
hex(n::ZZRingElem) = base(n, 16)

Return $n$ as a hexadecimal string.

Examples

julia> hex(ZZ(12))
-"c"
source
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"
source
number_of_digitsMethod
number_of_digits(x::ZZRingElem, b::Integer)

Return the number of digits of $x$ in the base $b$ (default is $b = 10$).

Examples

julia> number_of_digits(ZZ(12), 3)
-3
source
nbitsMethod
nbits(x::ZZRingElem)

Return the number of binary bits of $x$. We return zero if $x = 0$.

Examples

julia> nbits(ZZ(12))
-4
source

Bit twiddling

popcountMethod
popcount(x::ZZRingElem)

Return the number of ones in the binary representation of $x$.

Examples

julia> popcount(ZZ(12))
-2
source
prevpow2Method
prevpow2(x::ZZRingElem)

Return the previous power of $2$ up to including $x$.

source
nextpow2Method
nextpow2(x::ZZRingElem)

Return the next power of $2$ that is at least $x$.

Examples

julia> nextpow2(ZZ(12))
-16
source
trailing_zerosMethod
trailing_zeros(x::ZZRingElem)

Return the number of trailing zeros in the binary representation of $x$.

source
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
source
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
source
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
source
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
source

Random generation

rand_bitsMethod
rand_bits(::ZZRing, b::Int)

Return a random signed integer whose absolute value has $b$ bits.

source
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.

source

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/PR4245/Nemo/mathjaxhelper.js b/previews/PR4245/Nemo/mathjaxhelper.js deleted file mode 100644 index 1bd5394af59d..000000000000 --- a/previews/PR4245/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/PR4245/Nemo/matrix/index.html b/previews/PR4245/Nemo/matrix/index.html deleted file mode 100644 index d04a334a9b26..000000000000 --- a/previews/PR4245/Nemo/matrix/index.html +++ /dev/null @@ -1,239 +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$)FlintFqPolyRepMatrixFqPolyRepMatrixSpace
$\mathbb{R}$ (arbitrary precision)ArbRealMatrixRealMatrixSpace
$\mathbb{C}$ (arbitrary precision)ArbComplexMatrixComplexMatrixSpace
$\mathbb{R}$ (fixed precision)ArbArbMatrixArbMatrixSpace
$\mathbb{C}$ (fixed precision)ArbAcbMatrixAcbMatrixSpace

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::RealMatrix, y::RealMatrix)

Returns true if all entries of $x$ overlap with the corresponding entry of $y$, otherwise return false.

source
overlapsMethod
overlaps(x::ComplexMatrix, y::ComplexMatrix)

Returns true if all entries of $x$ overlap with the corresponding entry of $y$, otherwise return false.

source
containsMethod
contains(x::RealMatrix, y::RealMatrix)

Returns true if all entries of $x$ contain the corresponding entry of $y$, otherwise return false.

source
containsMethod
contains(x::ComplexMatrix, y::ComplexMatrix)

Returns true if all entries of $x$ contain the corresponding entry of $y$, otherwise return false.

source

In addition we have the following ad hoc comparison operators.

Examples

julia> C = RR[1 2; 3 4]
-[1.0000000000000000000   2.0000000000000000000]
-[3.0000000000000000000   4.0000000000000000000]
-
-julia> D = RR["1 +/- 0.1" "2 +/- 0.1"; "3 +/- 0.1" "4 +/- 0.1"]
-[[1e+0 +/- 0.101]   [2e+0 +/- 0.101]]
-[[3e+0 +/- 0.101]   [4e+0 +/- 0.101]]
-
-julia> overlaps(C, D)
-true
-
-julia> contains(D, C)
-true

Scaling

<<Method
<<(x::ZZMatrix, y::Int)

Return $2^yx$.

source
>>Method
>>(x::ZZMatrix, y::Int)

Return $x/2^y$ where rounding is towards zero.

source

Examples

julia> A = ZZ[2 3 5; 1 4 7; 9 6 3]
-[2   3   5]
-[1   4   7]
-[9   6   3]
-
-julia> B = A<<5
-[ 64    96   160]
-[ 32   128   224]
-[288   192    96]
-
-julia> C = B>>2
-[16   24   40]
-[ 8   32   56]
-[72   48   24]

Determinant

det_divisorMethod
det_divisor(x::ZZMatrix)

Return some positive divisor of the determinant of $x$, if the determinant is nonzero, otherwise return zero.

source
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.

source
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.

source

Examples

julia> A = ZZ[2 3 5; 1 4 7; 9 6 3]
-[2   3   5]
-[1   4   7]
-[9   6   3]
-
-julia> c = det_divisor(A)
-3
-
-julia> d = det_given_divisor(A, c)
--30

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

julia> A = ZZ[1 0 1; 2 3 1; 5 6 7]
-[1   0   1]
-[2   3   1]
-[5   6   7]
-
-julia> B, d = pseudo_inv(A)
-([15 6 -3; -9 2 1; -3 -6 3], 12)
source

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}$.

source

Modular reduction

reduce_modMethod
reduce_mod(x::ZZMatrix, y::Integer)

Reduce the entries of $x$ modulo $y$ and return the result.

source
reduce_modMethod
reduce_mod(x::ZZMatrix, y::ZZRingElem)

Reduce the entries of $x$ modulo $y$ and return the result.

source

Examples

julia> A = ZZ[2 3 5; 1 4 7; 9 2 2]
-[2   3   5]
-[1   4   7]
-[9   2   2]
-
-julia> reduce_mod(A, ZZ(5))
-[2   3   0]
-[1   4   2]
-[4   2   2]
-
-julia> reduce_mod(A, 2)
-[0   1   1]
-[1   0   1]
-[1   0   0]

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}$.

source
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).

source
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.

source
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).

source
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.

source
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}$.

source
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).

source
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.

source
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).

source
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.

source

Examples

julia> R, = residue_ring(ZZ, 7)
-(Integers modulo 7, Map: ZZ -> ZZ/(7))
-
-julia> a = R[4 5 6; 7 3 2; 1 4 5]
-[4   5   6]
-[0   3   2]
-[1   4   5]
-
-julia> b = lift(a)
-[-3   -2   -1]
-[ 0    3    2]
-[ 1   -3   -2]

Special matrices

hadamardMethod
hadamard(R::ZZMatrixSpace)

Return the Hadamard matrix for the given matrix space. The number of rows and columns must be equal.

source
is_hadamardMethod
is_hadamard(x::ZZMatrix)

Return true if the given matrix is Hadamard, otherwise return false.

source
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)$.

source

Examples

julia> hadamard(matrix_space(ZZ, 3, 3))
-ERROR: Unable to create Hadamard matrix
-[...]
-
-julia> A = hadamard(matrix_space(ZZ, 4, 4))
-[1    1    1    1]
-[1   -1    1   -1]
-[1    1   -1   -1]
-[1   -1   -1    1]
-
-julia> is_hadamard(A)
-true
-
-julia> B = hilbert(matrix_space(QQ, 3, 3))
-[   1   1//2   1//3]
-[1//2   1//3   1//4]
-[1//3   1//4   1//5]

Hermite Normal Form

hnfMethod
hnf(x::ZZMatrix)

Return the Hermite Normal Form of $x$.

source
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$.

source
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$.

source
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.

source
is_hnfMethod
is_hnf(x::ZZMatrix)

Return true if the given matrix is in Hermite Normal Form, otherwise return false.

source

Examples

julia> A = ZZ[2 3 5; 1 4 7; 19 3 7]
-[ 2   3   5]
-[ 1   4   7]
-[19   3   7]
-
-julia> B = hnf(A)
-[1   0   16]
-[0   1   18]
-[0   0   27]
-
-julia> H, T = hnf_with_transform(A)
-([1 0 16; 0 1 18; 0 0 27], [-43 30 3; -44 31 3; -73 51 5])
-
-julia> M = hnf_modular(A, ZZ(27))
-[1   0   16]
-[0   1   18]
-[0   0   27]
-
-julia> N = hnf_modular_eldiv(A, ZZ(27))
-[1   0   16]
-[0   1   18]
-[0   0   27]
-
-julia> is_hnf(M)
-true

Lattice basis reduction

Nemo provides LLL lattice basis reduction. Optionally one can specify the setup using a context object created by the following function.

LLLContext(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::LLLContext = LLLContext(0.99, 0.51))

Return a matrix $L$ whose rows form an LLL-reduced basis of the $\mathbb{Z}$-lattice generated by the rows of $x$. $L$ may contain additional zero rows.

By default, the LLL is performed with reduction parameters $\delta = 0.99$ and $\eta = 0.51$. These defaults can be overridden by specifying an optional context object.

See lll_gram for a function taking the Gram matrix as input.

source
lll_with_transformMethod
lll_with_transform(x::ZZMatrix, ctx::LLLContext = LLLContext(0.99, 0.51))

Return a tuple $(L, T)$ where the rows of $L$ form an LLL-reduced basis of the $\mathbb{Z}$-lattice generated by the rows of $x$ and $T$ is a transformation matrix so that $L = Tx$. $L$ may contain additional zero rows. See lll for the used default parameters which can be overridden by supplying an optional context object.

See lll_gram_with_transform for a function taking the Gram matrix as input.

source
lll_gramMethod
lll_gram(x::ZZMatrix, ctx::LLLContext = LLLContext(0.99, 0.51, :gram))

Return the Gram matrix $L$ of an LLL-reduced basis of the lattice given by the Gram matrix $x$. The matrix $x$ must be symmetric and non-singular.

By default, the LLL is performed with reduction parameters $\delta = 0.99$ and $\eta = 0.51$. These defaults can be overridden by specifying an optional context object.

source
lll_gram_with_transformMethod
lll_gram_with_transform(x::ZZMatrix, ctx::LLLContext = LLLContext(0.99, 0.51, :gram))

Return a tuple $(L, T)$ where $L$ is the Gram matrix of an LLL-reduced basis of the lattice given by the Gram matrix $x$ and $T$ is a transformation matrix with $L = T^\top x T$. The matrix $x$ must be symmetric and non-singular.

See lll_gram for the used default parameters which can be overridden by supplying an optional context object.

source
lll_with_removalMethod
lll_with_removal(x::ZZMatrix, b::ZZRingElem, ctx::LLLContext = LLLContext(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.

source
lll_with_removal_transformMethod
lll_with_removal_transform(x::ZZMatrix, b::ZZRingElem, ctx::LLLContext = LLLContext(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$.

source
lll!Method
lll!(x::ZZMatrix, ctx::LLLContext = LLLContext(0.99, 0.51))

Compute an LLL-reduced basis of the $\mathbb{Z}$-lattice generated by the rows of $x$ inplace.

By default, the LLL is performed with reduction parameters $\delta = 0.99$ and $\eta = 0.51$. These defaults can be overridden by specifying an optional context object.

See lll_gram! for a function taking the Gram matrix as input.

source
lll_gram!Method
lll_gram!(x::ZZMatrix, ctx::LLLContext = LLLContext(0.99, 0.51, :gram))

Compute the Gram matrix of an LLL-reduced basis of the lattice given by the Gram matrix $x$ inplace. The matrix $x$ must be symmetric and non-singular.

By default, the LLL is performed with reduction parameters $\delta = 0.99$ and $\eta = 0.51$. These defaults can be overridden by specifying an optional context object.

source

Examples

julia> A = ZZ[2 3 5; 1 4 7; 19 3 7]
-[ 2   3   5]
-[ 1   4   7]
-[19   3   7]
-
-julia> L = lll(A, LLLContext(0.95, 0.55, :zbasis, :approx))
-[-1    1   2]
-[-1   -2   2]
-[ 4    1   1]
-
-julia> L, T = lll_with_transform(A)
-([-1 1 2; -1 -2 2; 4 1 1], [-1 1 0; -15 10 1; 3 -2 0])
-
-julia> G = lll_gram(gram(A))
-[ 6    3   -1]
-[ 3    9   -4]
-[-1   -4   18]
-
-julia> G, T = lll_gram_with_transform(gram(A))
-([6 3 -1; 3 9 -4; -1 -4 18], [-1 1 0; -15 10 1; 3 -2 0])
-
-julia> r, L = lll_with_removal(A, ZZ(100))
-(3, [-1 1 2; -1 -2 2; 4 1 1])
-
-julia> r, L, T = lll_with_removal_transform(A, ZZ(100))
-(3, [-1 1 2; -1 -2 2; 4 1 1], [-1 1 0; -15 10 1; 3 -2 0])

Smith Normal Form

snfMethod
snf(x::ZZMatrix)

Compute the Smith normal form of $x$.

source
snf_diagonalMethod
snf_diagonal(x::ZZMatrix)

Given a diagonal matrix $x$ compute the Smith normal form of $x$.

source
is_snfMethod
is_snf(x::ZZMatrix)

Return true if $x$ is in Smith normal form, otherwise return false.

source

Examples

julia> A = ZZ[2 3 5; 1 4 7; 19 3 7]
-[ 2   3   5]
-[ 1   4   7]
-[19   3   7]
-
-julia> B = snf(A)
-[1   0    0]
-[0   1    0]
-[0   0   27]
-
-julia> is_snf(B) == true
-true
-
-julia> B = ZZ[2 0 0; 0 4 0; 0 0 7]
-[2   0   0]
-[0   4   0]
-[0   0   7]
-
-julia> C = snf_diagonal(B)
-[1   0    0]
-[0   2    0]
-[0   0   28]

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.

source
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.

source

Examples

julia> R, = residue_ring(ZZ, 12);
-
-julia> A = R[4 1 0; 0 0 5; 0 0 0 ]
-[4   1   0]
-[0   0   5]
-[0   0   0]
-
-julia> B = strong_echelon_form(A)
-[4   1   0]
-[0   3   0]
-[0   0   1]

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.

source
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.

source

Examples

julia> R, = residue_ring(ZZ, 12);
-
-julia> A = R[4 1 0; 0 0 5; 0 0 0 ]
-[4   1   0]
-[0   0   5]
-[0   0   0]
-
-julia> B = howell_form(A)
-[4   1   0]
-[0   3   0]
-[0   0   1]

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]
source

Exponential

Examples

julia> A = RR[2 0 0; 0 3 0; 0 0 1]
-[2.0000000000000000000                       0                       0]
-[                    0   3.0000000000000000000                       0]
-[                    0                       0   1.0000000000000000000]
-
-julia> B = exp(A)
-[[7.389056098930650227 +/- 4.72e-19]                                     0                                     0]
-[                                  0   [20.08553692318766774 +/- 1.94e-18]                                     0]
-[                                  0                                     0   [2.718281828459045235 +/- 4.30e-19]]

Norm

bound_inf_normMethod
bound_inf_norm(x::RealMatrix)

Returns a non-negative element $z$ of type ArbFieldElem, such that $z$ is an upper bound for the infinity norm for every matrix in $x$

source
bound_inf_normMethod
bound_inf_norm(x::ComplexMatrix)

Returns a non-negative element $z$ of type AcbFieldElem, such that $z$ is an upper bound for the infinity norm for every matrix in $x$

source

Examples

julia> A = RR[1 2 3; 4 5 6; 7 8 9]
-[1.0000000000000000000   2.0000000000000000000   3.0000000000000000000]
-[4.0000000000000000000   5.0000000000000000000   6.0000000000000000000]
-[7.0000000000000000000   8.0000000000000000000   9.0000000000000000000]
-
-julia> d = bound_inf_norm(A)
-[24.000000059604644775 +/- 3.91e-19]

Shifting

Examples

julia> A = RR[1 2 3; 4 5 6; 7 8 9]
-[1.0000000000000000000   2.0000000000000000000   3.0000000000000000000]
-[4.0000000000000000000   5.0000000000000000000   6.0000000000000000000]
-[7.0000000000000000000   8.0000000000000000000   9.0000000000000000000]
-
-julia> B = ldexp(A, 4)
-[16.000000000000000000   32.000000000000000000   48.000000000000000000]
-[64.000000000000000000   80.000000000000000000   96.000000000000000000]
-[112.00000000000000000   128.00000000000000000   144.00000000000000000]
-
-julia> overlaps(16*A, B)
-true

Predicates

Examples

julia> A = CC[1 2 3; 4 5 6; 7 8 9]
-[1.0000000000000000000   2.0000000000000000000   3.0000000000000000000]
-[4.0000000000000000000   5.0000000000000000000   6.0000000000000000000]
-[7.0000000000000000000   8.0000000000000000000   9.0000000000000000000]
-
-julia> isreal(A)
-true
-
-julia> isreal(onei(CC)*A)
-false

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)

eigenvaluesMethod
eigenvalues(A::ComplexMatrix)

Return the eigenvalues of A.

This function is experimental.

source
eigenvalues_with_multiplicitiesMethod
eigenvalues_with_multiplicities(A::ComplexMatrix)

Return the eigenvalues of A with their algebraic multiplicities as a vector of tuples (ComplexFieldElem, Int). Each tuple (z, k) corresponds to a cluster of k eigenvalues of $A$.

This function is experimental.

source
eigenvalues_simpleMethod
eigenvalues_simple(A::ComplexMatrix, algorithm::Symbol = :default)

Returns the eigenvalues of A as a vector of AcbFieldElem. 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.

source
julia> A = CC[1 2 3; 0 4 5; 0 0 6]
-[1.0000000000000000000   2.0000000000000000000   3.0000000000000000000]
-[                    0   4.0000000000000000000   5.0000000000000000000]
-[                    0                       0   6.0000000000000000000]
-
-julia> eigenvalues_simple(A)
-3-element Vector{ComplexFieldElem}:
- 1.0000000000000000000
- 4.0000000000000000000
- 6.0000000000000000000
-
-julia> A = CC[2 2 3; 0 2 5; 0 0 2]
-[2.0000000000000000000   2.0000000000000000000   3.0000000000000000000]
-[                    0   2.0000000000000000000   5.0000000000000000000]
-[                    0                       0   2.0000000000000000000]
-
-julia> eigenvalues(A)
-1-element Vector{ComplexFieldElem}:
- 2.0000000000000000000
-
-julia> eigenvalues_with_multiplicities(A)
-1-element Vector{Tuple{ComplexFieldElem, Int64}}:
- (2.0000000000000000000, 3)
diff --git a/previews/PR4245/Nemo/misc/index.html b/previews/PR4245/Nemo/misc/index.html deleted file mode 100644 index 558f779b0030..000000000000 --- a/previews/PR4245/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/PR4245/Nemo/mpolynomial/index.html b/previews/PR4245/Nemo/mpolynomial/index.html deleted file mode 100644 index 5e1fc23d84e8..000000000000 --- a/previews/PR4245/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/PR4245/Nemo/numberfield/index.html b/previews/PR4245/Nemo/numberfield/index.html deleted file mode 100644 index 6e762b7e5602..000000000000 --- a/previews/PR4245/Nemo/numberfield/index.html +++ /dev/null @@ -1,87 +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 number_field function.

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)$AbsSimpleNumFieldElemAbsSimpleNumField

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.

Examples

julia> R, x = polynomial_ring(QQ, "x");
-
-julia> K, a = number_field(x^3 + 3x + 1, "a")
-(Number field of degree 3 over QQ, a)
-
-julia> K
-Number field with defining polynomial x^3 + 3*x + 1
-  over rational field
source
cyclotomic_fieldMethod
cyclotomic_field(n::Int, s::VarName = "z_$n", t = "_\$"; cached::Bool = 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.

source
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.

source

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

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> L, b = cyclotomic_field(5, "b")
-(Cyclotomic field of order 5, b)
-
-julia> M, c = cyclotomic_real_subfield(5, "c")
-(Maximal real subfield of cyclotomic field of order 5, c)
-
-julia> d = K(3)
-3
-
-julia> f = L(b)
-b
-
-julia> g = L(ZZ(11))
-11
-
-julia> h = L(ZZ(11)//3)
-11//3
-
-julia> k = M(x)
-c

Number field element constructors

genMethod
gen(a::AbsSimpleNumField)

Return the generator of the given number field, i.e., a symbolic root of the defining polynomial.

source

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

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> d = gen(K)
-a
-
-julia> f = a^2 + 2a - 7
-a^2 + 2*a - 7

Basic functionality

mul_red!Method
mul_red!(z::AbsSimpleNumFieldElem, x::AbsSimpleNumFieldElem, y::AbsSimpleNumFieldElem, 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.

source
reduce!Method
reduce!(x::AbsSimpleNumFieldElem)

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.

source

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::AbsSimpleNumFieldElem)

Coerce the given number field element into the polynomial ring $R$ of which the number field is a quotient.

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> f = R(a^2 + 2a + 3)
-x^2 + 2*x + 3
-
-julia> g = K(x^2 + 2x + 1)
-a^2 + 2*a + 1

Basic manipulation

varMethod
var(a::AbsSimpleNumField)

Returns the identifier (as a symbol, not a string), that is used for printing the generator of the given number field.

source
is_genMethod
is_gen(a::AbsSimpleNumFieldElem)

Return true if the given number field element is the generator of the number field, otherwise return false.

source
coeffMethod
coeff(x::AbsSimpleNumFieldElem, 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.

source
denominatorMethod
denominator(a::AbsSimpleNumFieldElem)

Return the denominator of the polynomial representation of the given number field element.

source
degreeMethod
degree(a::AbsSimpleNumField)

Return the degree of the given number field, i.e. the degree of its defining polynomial.

source

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> d = a^2 + 2a - 7
-a^2 + 2*a - 7
-
-julia> m = gen(K)
-a
-
-julia> c = coeff(d, 1)
-2
-
-julia> is_gen(m)
-true
-
-julia> q = degree(K)
-3

Norm and trace

normMethod
norm(a::AbsSimpleNumFieldElem)

Return the absolute norm of $a$. The result will be a rational number.

source
trMethod
tr(a::AbsSimpleNumFieldElem)

Return the absolute trace of $a$. The result will be a rational number.

source

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/PR4245/Nemo/padic/index.html b/previews/PR4245/Nemo/padic/index.html deleted file mode 100644 index 8aaafc04e331..000000000000 --- a/previews/PR4245/Nemo/padic/index.html +++ /dev/null @@ -1,107 +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 padic_field function.

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$PadicFieldElemPadicField

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.

padic_fieldFunction
padic_field(p::Integer; precision::Int=64, cached::Bool=true, check::Bool=true)
-padic_field(p::ZZRingElem; precision::Int=64, cached::Bool=true, check::Bool=true)

Return the $p$-adic field for the given prime $p$. The default absolute precision of elements of the field may be set with precision.

source

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

julia> R = padic_field(7, precision = 30)
-Field of 7-adic numbers
-
-julia> S = padic_field(ZZ(65537), precision = 30)
-Field of 65537-adic numbers
-
-julia> a = R()
-O(7^30)
-
-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::PadicField, 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).

source
OMethod
O(R::PadicField, 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).

source
OMethod
O(R::PadicField, 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).

source

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

julia> R = padic_field(7, precision = 30)
-Field of 7-adic numbers
-
-julia> S = padic_field(ZZ(65537), precision = 30)
-Field of 65537-adic numbers
-
-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 ZZRingElems or Julia BigInts, overflow may result in evaluating the value.

Basic manipulation

primeMethod
prime(R::PadicField)

Return the prime $p$ for the given $p$-adic field.

source
precisionMethod
precision(a::PadicFieldElem)

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$.

source
valuationMethod
valuation(a::PadicFieldElem)

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$.

source
liftMethod
lift(R::ZZRing, a::PadicFieldElem)

Return a lift of the given $p$-adic field element to $\mathbb{Z}$.

source
liftMethod
lift(R::QQField, a::PadicFieldElem)

Return a lift of the given $p$-adic field element to $\mathbb{Q}$.

source

Examples

julia> R = padic_field(7, precision = 30)
-Field of 7-adic numbers
-
-julia> a = 1 + 2*7 + 4*7^2 + O(R, 7^3)
-7^0 + 2*7^1 + 4*7^2 + O(7^3)
-
-julia> b = 7^2 + 3*7^3 + O(R, 7^5)
-7^2 + 3*7^3 + O(7^5)
-
-julia> c = R(2)
-2*7^0 + O(7^30)
-
-julia> k = precision(a)
-3
-
-julia> m = prime(R)
-7
-
-julia> n = valuation(b)
-2
-
-julia> p = lift(ZZ, a)
-211
-
-julia> q = lift(QQ, divexact(a, b))
-337//49

Square root

sqrtMethod
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.

source
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.

source
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.

source
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.

source

Examples

julia> R = padic_field(7, precision = 30)
-Field of 7-adic numbers
-
-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)
-3*7^0 + 5*7^1 + 7^2 + 7^3 + O(7^5)
-
-julia> f = sqrt(c)
-7^1 + 7^2 + O(7^3)
-
-julia> g = sqrt(R(121))
-3*7^0 + 5*7^1 + 6*7^2 + 6*7^3 + 6*7^4 + 6*7^5 + 6*7^6 + 6*7^7 + 6*7^8 + 6*7^9 + 6*7^10 + 6*7^11 + 6*7^12 + 6*7^13 + 6*7^14 + 6*7^15 + 6*7^16 + 6*7^17 + 6*7^18 + 6*7^19 + 6*7^20 + 6*7^21 + 6*7^22 + 6*7^23 + 6*7^24 + 6*7^25 + 6*7^26 + 6*7^27 + 6*7^28 + 6*7^29 + O(7^30)
-
-julia> g^2 == R(121)
-true

Special functions

expMethod
exp(a::PadicFieldElem)

Return the $p$-adic exponential of $a$, assuming the $p$-adic exponential function converges at $a$.

source
logMethod
log(a::PadicFieldElem)

Return the $p$-adic logarithm of $a$, assuming the $p$-adic logarithm converges at $a$.

source
teichmullerMethod
teichmuller(a::PadicFieldElem)

Return the Teichmuller lift of the $p$-adic value $a$. We require the valuation of $a$ to be non-negative. 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.

source

Examples

julia> R = padic_field(7, precision = 30)
-Field of 7-adic numbers
-
-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))
-O(7^30)
-
-julia> f = teichmuller(b)
-2*7^0 + 4*7^1 + 6*7^2 + O(7^3)
diff --git a/previews/PR4245/Nemo/polynomial/index.html b/previews/PR4245/Nemo/polynomial/index.html deleted file mode 100644 index 8b2a8d03a634..000000000000 --- a/previews/PR4245/Nemo/polynomial/index.html +++ /dev/null @@ -1,158 +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)ArbRealPolyRingElemRealPolyRing
$\mathbb{C}$ (arbitrary precision)ArbComplexPolyRingElemComplexPolyRing
$\mathbb{R}$ (fixed precision)ArbArbPolyRingElemArbPolyRing
$\mathbb{C}$ (fixed precision)ArbAcbPolyRingElemAcbPolyRing

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::RealPolyRingElem, y::RingElement)

Return a tuple $p, q$ consisting of the polynomial $x$ evaluated at $y$ and its derivative evaluated at $y$.

source
evaluate2Method
evaluate2(x::ComplexPolyRingElem, 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$.

source

Examples

julia> RR = RealField()
-Real field
-
-julia> T, z = polynomial_ring(RR, "z")
-(Univariate polynomial ring in z over RR, z)
-
-julia> h = z^2 + 2z + 1
-z^2 + 2.0000000000000000000*z + 1
-
-julia> s, t = evaluate2(h, RR("2.0 +/- 0.1"))
-([9e+0 +/- 0.611], [6e+0 +/- 0.201])

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)
source
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)
source

Root finding

rootsMethod
roots(x::ComplexPolyRingElem; 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.

source

Examples

julia> CC = ComplexField()
-Complex field
-
-julia> C, y = polynomial_ring(CC, "y")
-(Univariate polynomial ring in y over CC, y)
-
-julia> m = y^2 + 2y + 3
-y^2 + 2.0000000000000000000*y + 3.0000000000000000000
-
-julia> n = m + CC("0 +/- 0.0001", "0 +/- 0.0001")
-y^2 + 2.0000000000000000000*y + [3.000 +/- 1.01e-4] + [+/- 1.01e-4]*im
-
-julia> r = roots(n);
-
-julia> sort(r; by=x->(real(x), imag(x))) # sort roots to make printing consistent
-2-element Vector{ComplexFieldElem}:
- [-1.00 +/- 1.01e-4] + [-1.414 +/- 3.14e-4]*im
- [-1.00 +/- 1.01e-4] + [1.414 +/- 3.14e-4]*im
-
-julia> p = y^7 - 1
-y^7 - 1.0000000000000000000
-
-julia> r = roots(n, isolate_real = true);
-
-julia> sort(r; by=x->(real(x), imag(x))) # sort roots to make printing consistent
-2-element Vector{ComplexFieldElem}:
- [-1.00 +/- 1.01e-4] + [-1.414 +/- 3.14e-4]*im
- [-1.00 +/- 1.01e-4] + [1.414 +/- 3.14e-4]*im

Construction from roots

from_rootsMethod
from_roots(R::ArbPolyRing, b::Vector{ArbFieldElem})

Construct a polynomial in the given polynomial ring from a list of its roots.

source
from_rootsMethod
from_roots(R::AcbPolyRing, b::Vector{AcbFieldElem})

Construct a polynomial in the given polynomial ring from a list of its roots.

source

Examples

julia> RR = RealField()
-Real field
-
-julia> R, x = polynomial_ring(RR, "x")
-(Univariate polynomial ring in x over RR, x)
-
-julia> xs = [inv(RR(i)) for i=1:5]
-5-element Vector{RealFieldElem}:
- 1.0000000000000000000
- 0.50000000000000000000
- [0.3333333333333333333 +/- 4.24e-20]
- 0.25000000000000000000
- [0.2000000000000000000 +/- 2.44e-20]
-
-julia> f = from_roots(R, xs)
-x^5 + [-2.283333333333333333 +/- 4.54e-19]*x^4 + [1.875000000000000000 +/- 5.10e-19]*x^3 + [-0.708333333333333333 +/- 3.99e-19]*x^2 + [0.1250000000000000000 +/- 3.69e-20]*x + [-0.00833333333333333333 +/- 4.13e-21]
-
-julia> all(x -> contains_zero(evaluate(f, x)), xs)
-true

Bounding absolute values of roots

roots_upper_boundMethod
roots_upper_bound(x::RealPolyRingElem) -> ArbFieldElem

Returns an upper bound for the absolute value of all complex roots of $x$.

source
roots_upper_boundMethod
roots_upper_bound(x::ComplexPolyRingElem) -> ArbFieldElem

Returns an upper bound for the absolute value of all complex roots of $x$.

source

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 non-negative coefficients. The ring R specifies the ring to lift into.

source
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 non-negative coefficients. The ring R specifies the ring to lift into.

source
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 non-negative coefficients. The ring R specifies the ring to lift into.

source
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 non-negative coefficients. The ring R specifies the ring to lift into.

source

Examples

julia> R, = residue_ring(ZZ, 123456789012345678949)
-(Integers modulo 123456789012345678949, Map: ZZ -> ZZ/(123456789012345678949))
-
-julia> S, x = polynomial_ring(R, "x")
-(Univariate polynomial ring in x over ZZ/(123456789012345678949), x)
-
-julia> T, y = polynomial_ring(ZZ, "y")
-(Univariate polynomial ring in y over ZZ, y)
-
-julia> f = x^2 + 2x + 1
-x^2 + 2*x + 1
-
-julia> a = lift(T, f)
-y^2 + 2*y + 1

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::RealPolyRingElem, y::RealPolyRingElem)

Return true if the coefficient balls of $x$ overlap the coefficient balls of $y$, otherwise return false.

source
overlapsMethod
overlaps(x::ComplexPolyRingElem, y::ComplexPolyRingElem)

Return true if the coefficient boxes of $x$ overlap the coefficient boxes of $y$, otherwise return false.

source
containsMethod
contains(x::RealPolyRingElem, y::RealPolyRingElem)

Return true if the coefficient balls of $x$ contain the corresponding coefficient balls of $y$, otherwise return false.

source
containsMethod
contains(x::ComplexPolyRingElem, y::ComplexPolyRingElem)

Return true if the coefficient boxes of $x$ contain the corresponding coefficient boxes of $y$, otherwise return false.

source
containsMethod
contains(x::RealPolyRingElem, y::ZZPolyRingElem)

Return true if the coefficient balls of $x$ contain the corresponding exact coefficients of $y$, otherwise return false.

source
containsMethod
contains(x::RealPolyRingElem, y::QQPolyRingElem)

Return true if the coefficient balls of $x$ contain the corresponding exact coefficients of $y$, otherwise return false.

source
containsMethod
contains(x::ComplexPolyRingElem, y::ZZPolyRingElem)

Return true if the coefficient boxes of $x$ contain the corresponding exact coefficients of $y$, otherwise return false.

source
containsMethod
contains(x::ComplexPolyRingElem, y::QQPolyRingElem)

Return true if the coefficient boxes of $x$ contain the corresponding exact coefficients of $y$, otherwise return false.

source

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::RealPolyRingElem)

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.

source
unique_integerMethod
unique_integer(x::ComplexPolyRingElem)

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.

source

Examples

julia> RR = RealField()
-Real field
-
-julia> R, x = polynomial_ring(RR, "x")
-(Univariate polynomial ring in x over RR, x)
-
-julia> f = x^2 + 2x + 1
-x^2 + 2.0000000000000000000*x + 1
-
-julia> h = f + RR("0 +/- 0.0001")
-x^2 + 2.0000000000000000000*x + [1.000 +/- 1.01e-4]
-
-julia> k = f + RR("0 +/- 0.0001") * x^4
-[+/- 1.01e-4]*x^4 + x^2 + 2.0000000000000000000*x + 1
-
-julia> contains(h, f)
-true
-
-julia> overlaps(f, k)
-true
-
-julia> t, z = unique_integer(k)
-(true, x^2 + 2*x + 1)
julia> CC = ComplexField()
-Complex field
-
-julia> C, y = polynomial_ring(CC, "y")
-(Univariate polynomial ring in y over CC, y)
-
-julia> m = y^2 + 2y + 1
-y^2 + 2.0000000000000000000*y + 1
-
-julia> n = m + CC("0 +/- 0.0001", "0 +/- 0.0001")
-y^2 + 2.0000000000000000000*y + [1.000 +/- 1.01e-4] + [+/- 1.01e-4]*im
-
-julia> contains(n, m)
-true
-
-julia> isreal(n)
-false
-
-julia> isreal(m)
-true

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$.

source
factor_distinct_degMethod
factor_distinct_deg(x::fpPolyRingElem)

Return the distinct degree factorisation of a squarefree polynomial $x$.

source
factor_distinct_degMethod
factor_distinct_deg(x::ZZModPolyRingElem)

Return the distinct degree factorisation of a squarefree polynomial $x$.

source
factor_distinct_degMethod
factor_distinct_deg(x::ZZModPolyRingElem)

Return the distinct degree factorisation of a squarefree polynomial $x$.

source
factor_distinct_degMethod
factor_distinct_deg(x::FqPolyRepPolyRingElem)

Return the distinct degree factorisation of a squarefree polynomial $x$.

source
factor_distinct_degMethod
factor_distinct_deg(x::fqPolyRepPolyRingElem)

Return the distinct degree factorisation of a squarefree polynomial $x$.

source

Examples

julia> R, = residue_ring(ZZ, 23)
-(Integers modulo 23, Map: ZZ -> ZZ/(23))
-
-julia> S, x = polynomial_ring(R, "x")
-(Univariate polynomial ring in x over ZZ/(23), x)
-
-julia> f = x^2 + 2x + 1
-x^2 + 2*x + 1
-
-julia> g = x^3 + 3x + 1
-x^3 + 3*x + 1
-
-julia> R = factor(f*g)
-1 * (x + 1)^2 * (x^3 + 3*x + 1)
-
-julia> S = factor_squarefree(f*g)
-1 * (x + 1)^2 * (x^3 + 3*x + 1)
-
-julia> T = factor_distinct_deg((x + 1)*g*(x^5+x^3+x+1))
-Dict{Int64, zzModPolyRingElem} with 3 entries:
-  4 => x^4 + 7*x^3 + 4*x^2 + 5*x + 13
-  3 => x^3 + 3*x + 1
-  1 => x^2 + 17*x + 16

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.

source
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}$).

source
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$.

source
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}$.

source
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)$.

source

Examples

julia> R, x = polynomial_ring(ZZ, "x")
-(Univariate polynomial ring in x over ZZ, x)
-
-julia> h = cyclotomic(120, x)
-x^32 + x^28 - x^20 - x^16 - x^12 + x^4 + 1
-
-julia> j = swinnerton_dyer(5, x)
-x^32 - 448*x^30 + 84864*x^28 - 9028096*x^26 + 602397952*x^24 - 26625650688*x^22 + 801918722048*x^20 - 16665641517056*x^18 + 239210760462336*x^16 - 2349014746136576*x^14 + 15459151516270592*x^12 - 65892492886671360*x^10 + 172580952324702208*x^8 - 255690851718529024*x^6 + 183876928237731840*x^4 - 44660812492570624*x^2 + 2000989041197056
-
-julia> k = cos_minpoly(30, x)
-x^4 + x^3 - 4*x^2 - 4*x + 1
-
-julia> l = theta_qexp(3, 30, x)
-72*x^29 + 32*x^27 + 72*x^26 + 30*x^25 + 24*x^24 + 24*x^22 + 48*x^21 + 24*x^20 + 24*x^19 + 36*x^18 + 48*x^17 + 6*x^16 + 48*x^14 + 24*x^13 + 8*x^12 + 24*x^11 + 24*x^10 + 30*x^9 + 12*x^8 + 24*x^6 + 24*x^5 + 6*x^4 + 8*x^3 + 12*x^2 + 6*x + 1
-
-julia> m = eta_qexp(24, 30, x)
--29211840*x^29 + 128406630*x^28 + 24647168*x^27 - 73279080*x^26 + 13865712*x^25 - 25499225*x^24 + 21288960*x^23 + 18643272*x^22 - 12830688*x^21 - 4219488*x^20 - 7109760*x^19 + 10661420*x^18 + 2727432*x^17 - 6905934*x^16 + 987136*x^15 + 1217160*x^14 + 401856*x^13 - 577738*x^12 - 370944*x^11 + 534612*x^10 - 115920*x^9 - 113643*x^8 + 84480*x^7 - 16744*x^6 - 6048*x^5 + 4830*x^4 - 1472*x^3 + 252*x^2 - 24*x + 1
-
-julia> o = cyclotomic(10, 1 + x + x^2)
-x^8 + 4*x^7 + 9*x^6 + 13*x^5 + 14*x^4 + 11*x^3 + 6*x^2 + 2*x + 1
diff --git a/previews/PR4245/Nemo/puiseux/index.html b/previews/PR4245/Nemo/puiseux/index.html deleted file mode 100644 index 95f1f19bfd7e..000000000000 --- a/previews/PR4245/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
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.

source
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.

source
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.

source
expMethod
exp(a::AbsPowerSeriesRingElem)

Return the exponential of the power series $a$.

source
exp(a::RelPowerSeriesRingElem)

Return the exponential of the power series $a$.

source
exp(a::Generic.LaurentSeriesElem)

Return the exponential of the power series $a$.

source
exp(a::Generic.PuiseuxSeriesElem{T}) where T <: RingElement

Return the exponential of the given Puiseux series $a$.

source
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.

source

Examples

julia> S, z = puiseux_series_ring(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/PR4245/Nemo/qadic/index.html b/previews/PR4245/Nemo/qadic/index.html deleted file mode 100644 index c51330ecaab8..000000000000 --- a/previews/PR4245/Nemo/qadic/index.html +++ /dev/null @@ -1,88 +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 qadic_field function.

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$QadicFieldElemQadicField

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.

qadic_fieldFunction
qadic_field(p::Integer, d::Int, var::String = "a"; precision::Int=64, cached::Bool=true, check::Bool=true)
-qadic_field(p::ZZRingElem, d::Int, var::String = "a"; precision::Int=64, cached::Bool=true, check::Bool=true)

Return an unramified extension $K$ of degree $d$ of a $p$-adic field for the given prime $p$. The generator of $K$ is printed as var.

The default absolute precision of elements of $K$ may be set with precision.

See also unramified_extension.

source
unramified_extensionFunction
unramified_extension(Qp::PadicField, d::Int, var::String = "a"; precision::Int=64, cached::Bool=true)

Return an unramified extension $K$ of degree $d$ of the given $p$-adic field Qp. The generator of $K$ is printed as var.

The default absolute precision of elements of $K$ may be set with precision.

source

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 = qadic_field(7, 1, precision = 30);
-
-julia> S, _ = qadic_field(ZZ(65537), 1, precision = 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::QadicField, 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).

source
OMethod
O(R::QadicField, 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).

source
OMethod
O(R::QadicField, 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).

source

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, _ = qadic_field(7, 1, precision = 30);
-
-julia> S, _ = qadic_field(ZZ(65537), 1, precision = 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::QadicField)

Return the prime $p$ for the given $q$-adic field.

source
precisionMethod
precision(a::QadicFieldElem)

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$.

source
valuationMethod
valuation(a::QadicFieldElem)

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$.

source
liftMethod
lift(R::QQPolyRing, a::QadicFieldElem)

Return a lift of the given $q$-adic field element to $\mathbb{Q}[x]$.

source
liftMethod
lift(R::ZZPolyRing, a::QadicFieldElem)

Return a lift of the given $q$-adic field element to $\mathbb{Z}[x]$ if possible.

source

Examples

R, _ = qadic_field(7, 1, precision = 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 = QQ["x"]
-p = lift(Qx, a)
-Zy, y = ZZ["y"]
-q = lift(Zy, divexact(a, b))

Square root

sqrtMethod
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.

source
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.

source
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.

source
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.

source

Examples

julia> R, _ = qadic_field(7, 1, precision = 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::QadicFieldElem)

Return the $p$-adic exponential of $a$, assuming the $p$-adic exponential function converges at $a$.

source
logMethod
log(a::QadicFieldElem)

Return the $p$-adic logarithm of $a$, assuming the $p$-adic logarithm converges at $a$.

source
teichmullerMethod
teichmuller(a::QadicFieldElem)

Return the Teichmuller lift of the $q$-adic value $a$. We require the valuation of $a$ to be non-negative. 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.

source
frobeniusMethod
frobenius(a::QadicFieldElem, 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.

source

Examples

julia> R, _ = qadic_field(7, 1, precision = 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/PR4245/Nemo/rational/index.html b/previews/PR4245/Nemo/rational/index.html deleted file mode 100644 index f8480ed35c43..000000000000 --- a/previews/PR4245/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/PR4245/Nemo/real/index.html b/previews/PR4245/Nemo/real/index.html deleted file mode 100644 index 9466bf07e301..000000000000 --- a/previews/PR4245/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
source
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]
source
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]
source
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> c = RR(1)
-1.0000000000000000000
-
-julia> d = RR(1//2)
-0.50000000000000000000

Note that for the construction, also the precision can be supplied:

julia> c = RR(1//3, precision=100)
-[0.33333333333333333333 +/- 3.34e-21]
-
-julia> d = RR(1//3, precision=4)
-[0.3 +/- 0.0438]

Conversions

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.

source
isfiniteMethod
isfinite(x::RealFieldElem)

Return true if $x$ is finite, i.e. having finite midpoint and radius, otherwise return false.

source
is_exactMethod
is_exact(x::RealFieldElem)

Return true if $x$ is exact, i.e. has zero radius, otherwise return false.

source
isintegerMethod
isinteger(x::RealFieldElem)

Return true if $x$ is an exact integer, otherwise return false.

source
is_positiveMethod
is_positive(x::RealFieldElem)

Return true if $x$ is certainly positive, otherwise return false.

source
is_nonnegativeMethod
is_nonnegative(x::RealFieldElem)

Return true if $x$ is certainly non-negative, otherwise return false.

source
is_negativeMethod
is_negative(x::RealFieldElem)

Return true if $x$ is certainly negative, otherwise return false.

source
is_nonpositiveMethod
is_nonpositive(x::RealFieldElem)

Return true if $x$ is certainly nonpositive, otherwise return false.

source
midpointMethod
midpoint(x::RealFieldElem)

Return the midpoint of the ball $x$ as an Arb ball.

source
radiusMethod
radius(x::RealFieldElem)

Return the radius of the ball $x$ as an Arb ball.

source
accuracy_bitsMethod
accuracy_bits(x::RealFieldElem)

Return the relative accuracy of $x$ measured in bits, capped between typemax(Int) and -typemax(Int).

source

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:

julia> a = RR(1)
-1.0000000000000000000
-
-julia> b = RR(2)
-2.0000000000000000000
-
-julia> c = RR(12)
-12.000000000000000000
-
-julia> x = ball(a, b)
-[+/- 3.01]
-
-julia> y = ball(c, b)
-[1e+1 +/- 4.01]
-
-julia> mid = midpoint(x)
-1.0000000000000000000
-
-julia> rad = radius(x)
-[2.0000000037252902985 +/- 3.81e-20]
-
-julia> print(x, "\n", y, "\n", mid, "\n", rad)
-[+/- 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.

source
containsMethod
contains(x::RealFieldElem, y::RealFieldElem)

Returns true if the ball $x$ contains the ball $y$, otherwise return false.

source
containsMethod
contains(x::RealFieldElem, y::Integer)

Returns true if the ball $x$ contains the given integer value, otherwise return false.

source
containsMethod
contains(x::RealFieldElem, y::ZZRingElem)

Returns true if the ball $x$ contains the given integer value, otherwise return false.

source
containsMethod
contains(x::RealFieldElem, y::QQFieldElem)

Returns true if the ball $x$ contains the given rational value, otherwise return false.

source
containsMethod
contains(x::RealFieldElem, y::Rational{T}) where {T <: Integer}

Returns true if the ball $x$ contains the given rational value, otherwise return false.

source
containsMethod
contains(x::RealFieldElem, y::BigFloat)

Returns true if the ball $x$ contains the given floating point value, otherwise return false.

source

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.

source
contains_negativeMethod
contains_negative(x::RealFieldElem)

Returns true if the ball $x$ contains any negative value, otherwise return false.

source
contains_positiveMethod
contains_positive(x::RealFieldElem)

Returns true if the ball $x$ contains any positive value, otherwise return false.

source
contains_nonnegativeMethod
contains_nonnegative(x::RealFieldElem)

Returns true if the ball $x$ contains any non-negative value, otherwise return false.

source
contains_nonpositiveMethod
contains_nonpositive(x::RealFieldElem)

Returns true if the ball $x$ contains any nonpositive value, otherwise return false.

source

Examples

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.

source

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> 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> x = RR("-1 +/- 0.001")
-[-1.00 +/- 1.01e-3]
-
-julia> a = abs(x)
-[1.00 +/- 1.01e-3]

Shifting

Examples

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$.

source
trimMethod
trim(x::RealFieldElem)

Return an RealFieldElem interval containing $x$ but which may be more economical, by rounding off insignificant bits from the midpoint.

source
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.

source
setunionMethod
setunion(x::RealFieldElem, y::RealFieldElem)

Return an ArbFieldElem containing the union of the intervals represented by $x$ and $y$.

source

Examples

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$.

source
const_eMethod
const_e(r::RealField)

Return $e = 2.71828\ldots$ as an element of $r$.

source
const_log2Method
const_log2(r::RealField)

Return $\log(2) = 0.69314\ldots$ as an element of $r$.

source
const_log10Method
const_log10(r::RealField)

Return $\log(10) = 2.302585\ldots$ as an element of $r$.

source
const_eulerMethod
const_euler(r::RealField)

Return Euler's constant $\gamma = 0.577215\ldots$ as an element of $r$.

source
const_catalanMethod
const_catalan(r::RealField)

Return Catalan's constant $C = 0.915965\ldots$ as an element of $r$.

source
const_khinchinMethod
const_khinchin(r::RealField)

Return Khinchin's constant $K = 2.685452\ldots$ as an element of $r$.

source
const_glaisherMethod
const_glaisher(r::RealField)

Return Glaisher's constant $A = 1.282427\ldots$ as an element of $r$.

source

Examples

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}$.

source
sqrt1pm1Method
sqrt1pm1(x::RealFieldElem)

Return $\sqrt{1+x}-1$, evaluated accurately for small $x$.

source
sqrtposMethod
sqrtpos(x::RealFieldElem)

Return the sqrt root of $x$, assuming that $x$ represents a non-negative number. Thus any negative number in the input interval is discarded.

source
gammaMethod
gamma(x::RealFieldElem)

Return the Gamma function evaluated at $x$.

source
lgammaMethod
lgamma(x::RealFieldElem)

Return the logarithm of the Gamma function evaluated at $x$.

source
rgammaMethod
rgamma(x::RealFieldElem)

Return the reciprocal of the Gamma function evaluated at $x$.

source
digammaMethod
digamma(x::RealFieldElem)

Return the logarithmic derivative of the gamma function evaluated at $x$, i.e. $\psi(x)$.

source
gammaMethod
gamma(s::RealFieldElem, x::RealFieldElem)

Return the upper incomplete gamma function $\Gamma(s,x)$.

source
gamma_regularizedMethod
gamma_regularized(s::RealFieldElem, x::RealFieldElem)

Return the regularized upper incomplete gamma function $\Gamma(s,x) / \Gamma(s)$.

source
gamma_lowerMethod
gamma_lower(s::RealFieldElem, x::RealFieldElem)

Return the lower incomplete gamma function $\gamma(s,x) / \Gamma(s)$.

source
gamma_lower_regularizedMethod
gamma_lower_regularized(s::RealFieldElem, x::RealFieldElem)

Return the regularized lower incomplete gamma function $\gamma(s,x) / \Gamma(s)$.

source
zetaMethod
zeta(x::RealFieldElem)

Return the Riemann zeta function evaluated at $x$.

source
atan2Method
atan2(y::RealFieldElem, x::RealFieldElem)

Return $\operatorname{atan2}(y,x) = \arg(x+yi)$. Same as atan(y, x).

source
agmMethod
agm(x::RealFieldElem, y::RealFieldElem)

Return the arithmetic-geometric mean of $x$ and $y$

source
zetaMethod
zeta(s::RealFieldElem, a::RealFieldElem)

Return the Hurwitz zeta function $\zeta(s,a)$.

source
rootMethod
root(x::RealFieldElem, n::Int)

Return the $n$-th root of $x$. We require $x \geq 0$.

source
factorialMethod
factorial(x::RealFieldElem)

Return the factorial of $x$.

source
factorialMethod
factorial(n::Int, r::RealField)

Return the factorial of $n$ in the given Arb field.

source
binomialMethod
binomial(x::RealFieldElem, n::UInt)

Return the binomial coefficient ${x \choose n}$.

source
binomialMethod
binomial(n::UInt, k::UInt, r::RealField)

Return the binomial coefficient ${n \choose k}$ in the given Arb field.

source
fibonacciMethod
fibonacci(n::ZZRingElem, r::RealField)

Return the $n$-th Fibonacci number in the given Arb field.

source
fibonacciMethod
fibonacci(n::Int, r::RealField)

Return the $n$-th Fibonacci number in the given Arb field.

source
gammaMethod
gamma(x::ZZRingElem, r::RealField)

Return the Gamma function evaluated at $x$ in the given Arb field.

source
gammaMethod
gamma(x::QQFieldElem, r::RealField)

Return the Gamma function evaluated at $x$ in the given Arb field.

source
zetaMethod
zeta(n::Int, r::RealField)

Return the Riemann zeta function $\zeta(n)$ as an element of the given Arb field.

source
bernoulliMethod
bernoulli(n::Int, r::RealField)

Return the $n$-th Bernoulli number as an element of the given Arb field.

source
rising_factorialMethod
rising_factorial(x::RealFieldElem, n::Int)

Return the rising factorial $x(x + 1)\ldots (x + n - 1)$ as an Arb.

source
rising_factorial(x::RingElement, n::Integer)

Return the rising factorial of $x$, i.e. $x(x + 1)(x + 2)\cdots (x + n - 1)$. If $n < 0$ we throw a DomainError().

Examples

julia> R, x = ZZ[:x];
-
-julia> rising_factorial(x, 1)
-x
-
-julia> rising_factorial(x, 2)
-x^2 + x
-
-julia> rising_factorial(4, 2)
-20
source
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.

source
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.

source
rising_factorial2(x::RingElement, n::Integer)

Return a tuple containing the rising factorial $x(x + 1)\cdots (x + n - 1)$ and its derivative. If $n < 0$ we throw a DomainError().

Examples

julia> R, x = ZZ[:x];
-
-julia> rising_factorial2(x, 1)
-(x, 1)
-
-julia> rising_factorial2(x, 2)
-(x^2 + x, 2*x + 1)
-
-julia> rising_factorial2(4, 2)
-(20, 9)
source
polylogMethod
polylog(s::Union{RealFieldElem,Int}, a::RealFieldElem)

Return the polylogarithm Li$_s(a)$.

source
chebyshev_tMethod
chebyshev_t(n::Int, x::RealFieldElem)

Return the value of the Chebyshev polynomial $T_n(x)$.

source
chebyshev_uMethod
chebyshev_u(n::Int, x::RealFieldElem)

Return the value of the Chebyshev polynomial $U_n(x)$.

source
chebyshev_t2Method
chebyshev_t2(n::Int, x::RealFieldElem)

Return the tuple $(T_{n}(x), T_{n-1}(x))$.

source
chebyshev_u2Method
chebyshev_u2(n::Int, x::RealFieldElem)

Return the tuple $(U_{n}(x), U_{n-1}(x))$

source
bellMethod
bell(n::ZZRingElem, r::RealField)

Return the Bell number $B_n$ as an element of $r$.

source
bellMethod
bell(n::Int, r::RealField)

Return the Bell number $B_n$ as an element of $r$.

source
numpartMethod
numpart(n::ZZRingElem, r::RealField)

Return the number of partitions $p(n)$ as an element of $r$.

source
numpartMethod
numpart(n::Int, r::RealField)

Return the number of partitions $p(n)$ as an element of $r$.

source
airy_aiMethod
airy_ai(x::RealFieldElem)

Return the Airy function $\operatorname{Ai}(x)$.

source
airy_ai_primeMethod
airy_ai_prime(x::RealFieldElem)

Return the derivative of the Airy function $\operatorname{Ai}^\prime(x)$.

source
airy_biMethod
airy_bi(x::RealFieldElem)

Return the Airy function $\operatorname{Bi}(x)$.

source
airy_bi_primeMethod
airy_bi_prime(x::RealFieldElem)

Return the derivative of the Airy function $\operatorname{Bi}^\prime(x)$.

source

Examples

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
source
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
source

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 ArbFieldElem 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 ArbFieldElem 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.

source
rand([rng=GLOBAL_RNG,] G::SymmetricGroup)

Return a random permutation from G.

source

Examples

a = rand(RR)
-b = rand(RR; randtype = :null_exact)
-c = rand(RR; randtype = :exact)
-d = rand(RR; randtype = :special)
diff --git a/previews/PR4245/Nemo/residue/index.html b/previews/PR4245/Nemo/residue/index.html deleted file mode 100644 index 3d30de34908a..000000000000 --- a/previews/PR4245/Nemo/residue/index.html +++ /dev/null @@ -1,5 +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.jlEuclideanRingResidueRingElem{T}EuclideanRingResidueRing{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}$.

source
gcdxMethod
gcdx(a::ZZModRingElem, b::ZZModRingElem)

Compute the extended gcd with the Euclidean structure inherited from $\mathbb{Z}$.

source

Examples

julia> R, = residue_ring(ZZ, 123456789012345678949);
-
-julia> g, s, t = gcdx(R(123), R(456))
-(1, 123456789012345678928, 41152263004115226322)
diff --git a/previews/PR4245/Nemo/series/index.html b/previews/PR4245/Nemo/series/index.html deleted file mode 100644 index 532acd17e3f6..000000000000 --- a/previews/PR4245/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/PR4245/Nemo/types/index.html b/previews/PR4245/Nemo/types/index.html deleted file mode 100644 index 5e704bcc85ee..000000000000 --- a/previews/PR4245/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)
    • PadicFieldElem (PadicField)
    • QadicFieldElem (QadicField)
    • 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

    • AbsSimpleNumFieldElem (AbsSimpleNumField)
  • Arb

    • ArbFieldElem (ArbField)
    • AcbFieldElem (AcbField)
    • ArbPolyRingElem (ArbPolyRing)
    • AcbPolyRingElem (AcbPolyRing)
    • ArbMatrix (ArbMatrixSpace)
    • AcbMatrix (AcbMatrixSpace)
  • Calcium

    • QQBarFieldElem (QQBarField)
    • CalciumFieldElem (CalciumField)
diff --git a/previews/PR4245/NoncommutativeAlgebra/PBWAlgebras/creation/index.html b/previews/PR4245/NoncommutativeAlgebra/PBWAlgebras/creation/index.html deleted file mode 100644 index f37aa93c885a..000000000000 --- a/previews/PR4245/NoncommutativeAlgebra/PBWAlgebras/creation/index.html +++ /dev/null @@ -1,90 +0,0 @@ - -Creating PBW-Algebras · Oscar.jl

Creating PBW-Algebras

Types

PBW-algebras are modeled 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 $\mathbb{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,
  • number_of_generators(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> number_of_generators(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/PR4245/NoncommutativeAlgebra/PBWAlgebras/ideals/index.html b/previews/PR4245/NoncommutativeAlgebra/PBWAlgebras/ideals/index.html deleted file mode 100644 index 4e6c2092aedf..000000000000 --- a/previews/PR4245/NoncommutativeAlgebra/PBWAlgebras/ideals/index.html +++ /dev/null @@ -1,318 +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,
  • number_of_generators(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> number_of_generators(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(a::AlgAssAbsOrdIdl, b::AlgAssAbsOrdIdl) -> AlgAssAbsOrdIdl

Returns $a \cap b$.

source
intersect(a::AlgAssRelOrdIdl, b::AlgAssRelOrdIdl) -> AlgAssRelOrdIdl

Returns $a \cap b$.

source
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 generated by
-  x^3*y - x*y - y^3
-  x^4 - x^2 - x*y^2
-
-julia> intersect([I, J])
-Ideal generated by
-  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 generated by
-  y^2
-
-julia> b = ideal(A, [x])
-Ideal generated by
-  x
-
-julia> intersect(a,b)
-Ideal generated by
-  x*y
-
-julia> intersect([a,b])
-Ideal generated by
-  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 R
-
-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> Rg, (x, y, z) = graded_polynomial_ring(QQ, [:x, :y, :z]);
-
-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

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/PR4245/NoncommutativeAlgebra/PBWAlgebras/intro/index.html b/previews/PR4245/NoncommutativeAlgebra/PBWAlgebras/intro/index.html deleted file mode 100644 index c62785e779f9..000000000000 --- a/previews/PR4245/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 [LS03] 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 \mathbb{N}^n$, then set $\alpha^{\text{op}} =(\alpha_n, \ldots, \alpha_1)\in \mathbb{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, [DL06]).

diff --git a/previews/PR4245/NoncommutativeAlgebra/PBWAlgebras/quotients/index.html b/previews/PR4245/NoncommutativeAlgebra/PBWAlgebras/quotients/index.html deleted file mode 100644 index 2c9faca58c84..000000000000 --- a/previews/PR4245/NoncommutativeAlgebra/PBWAlgebras/quotients/index.html +++ /dev/null @@ -1,89 +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 [Lev05]).

Types

GR-algebras are modeled 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 defined by a julia-function with inverse
-  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)
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_algebraMethod
exterior_algebra(K::Ring, nvars::Int)
-exterior_algebra(K::Ring, varnames::AbstractVector{<:VarName})

Given a coefficient ring K and variable names, say varnames = [:x1, :x2, ...], return a tuple E, [x1, x2, ...] consisting of the exterior algebra E over the polynomial ring R[x1, x2, ...] and its generators x1, x2, ....

If K is a field, this function will use a special implementation in Singular.

Note

Creating an exterior_algebra with many variables will create an object occupying a lot of memory (probably cubic in nvars).

Examples

julia> E, (x1,x2)  =  exterior_algebra(QQ, 2);
-
-julia> x2*x1
--x1*x2
-
-julia> (x1+x2)^2  # over fields, result is automatically reduced!
-0
-
-julia> E, (x,y)  =  exterior_algebra(QQ, ["x","y"]);
-
-julia> y*x
--x*y
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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,
  • number_of_generators(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> number_of_generators(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/PR4245/NoncommutativeAlgebra/free_associative_algebra/index.html b/previews/PR4245/NoncommutativeAlgebra/free_associative_algebra/index.html deleted file mode 100644 index ad9e7ab5f1fe..000000000000 --- a/previews/PR4245/NoncommutativeAlgebra/free_associative_algebra/index.html +++ /dev/null @@ -1,23 +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 FreeAssociativeAlgebraIdeal{T}, where T is the element type of the algebra.

Constructors

ideal(R::FreeAssociativeAlgebra, g::Vector{T}) where T <: FreeAssociativeAlgebraElem
-ideal(g::Vector{T}) where T <: FreeAssociativeAlgebraElem

Ideal Membership

Non-commutative polynomial rings are not Noetherian. Hence, in general, Groebner bases do not exist. Hence calling the functions below may not terminate. Picking suitable term orders is difficult in the noncommutative case. Therefore, we fix the term order to be degree reverse lexicographic.

Setting the parameter deg_bound to a positive value yields the truncation of the Groebner bases to a fixed degree. Such a truncation is always finite.

groebner_basisFunction
groebner_basis(I::FreeAssociativeAlgebraIdeal, deg_bound::Int=-1; protocol::Bool=false)

Return the Groebner basis of I with respect to the degree bound deg_bound. If protocol is true, the protocol of the computation is also returned. The default value of deg_bound is -1, which means that no degree bound is imposed, resulting in a computation that is usually slower, but will return a full Groebner basis if there exists a finite one.

julia> free, (x,y,z) = free_associative_algebra(QQ, [:x, :y, :z]);
-
-julia> f1 = x*y + y*z;
-
-julia> f2 = x^2 + y^2;
-
-julia> I = ideal([f1, f2]);
-
-julia> gb = groebner_basis(I, 3; protocol=false)
-Ideal generating system with elements
-  1 -> x*y + y*z
-  2 -> x^2 + y^2
-  3 -> y^3 + y*z^2
-  4 -> y^2*x + y*z*y
source

If a finite Gröbner basis exists, it solves the ideal membership problem.

ideal_membershipMethod
ideal_membership(a::FreeAssociativeAlgebraElem, I::FreeAssociativeAlgebraIdeal, deg_bound::Int)

Returns true if intermediate degree calculations bounded by deg_bound prove that $a$ is in $I$. Otherwise, returning false indicates an inconclusive answer, but larger deg_bounds give more confidence in a negative answer. If deg_bound is not specified, the default value is -1, which means that no degree bound is imposed, resulting in a calculation using a much slower algorithm that may not terminate, but will return a full Groebner basis if it does.

julia> free, (x,y,z) = free_associative_algebra(QQ, [:x, :y, :z]);
-
-julia> f1 = x*y + y*z;
-
-julia> I = ideal([f1]);
-
-julia> ideal_membership(f1, I, 4)
-true
source
diff --git a/previews/PR4245/NoncommutativeAlgebra/intro/index.html b/previews/PR4245/NoncommutativeAlgebra/intro/index.html deleted file mode 100644 index 048dd2da6791..000000000000 --- a/previews/PR4245/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

  • an evolving toolkit for dealing with PBW-algebras and their quotients modulo two-sided ideals,
  • some 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/PR4245/NumberTheory/abelian_closure/index.html b/previews/PR4245/NumberTheory/abelian_closure/index.html deleted file mode 100644 index 5fbcf205ffc2..000000000000 --- a/previews/PR4245/NumberTheory/abelian_closure/index.html +++ /dev/null @@ -1,54 +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::QQField; sparse::Bool = false)

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(K::QQAbField)

Return the generator of the abelian closure K that can be used to construct primitive roots of unity.

source
atlas_irrationalityFunction
atlas_irrationality([F::AbsSimpleNumField, ]description::String)

Return the value encoded by description. If F is given and is a cyclotomic field that contains the value then the result is in F, if F is not given then the result has type QQAbFieldElem.

description is assumed to have the format defined in [CCNPW85], Chapter 6, Section 10.

Examples

julia> Oscar.with_unicode() do
-         show(atlas_irrationality("r5"))
-       end;
--2*ζ(5)^3 - 2*ζ(5)^2 - 1
-
-julia> atlas_irrationality(cyclotomic_field(5)[1], "r5")
--2*z_5^3 - 2*z_5^2 - 1
-
-julia> Oscar.with_unicode() do
-         show(atlas_irrationality("i"))
-       end;
-ζ(4)
-
-julia> Oscar.with_unicode() do
-         show(atlas_irrationality("b7*3"))
-       end;
--ζ(7)^4 - ζ(7)^2 - ζ(7) - 1
-
-julia> Oscar.with_unicode() do
-         show(atlas_irrationality("3y'''24*13-2&5"))
-       end;
--5*ζ(24)^7 - 2*ζ(24)^5 + 2*ζ(24)^3 - 3*ζ(24)
source
atlas_descriptionFunction
atlas_description(val::QQAbFieldElem)

Return a string in the format defined in [CCNPW85], Chapter 6, Section 10, describing val. Applying atlas_irrationality to the result yields val.

Examples

julia> K, z = abelian_closure(QQ);
-
-julia> val = z(5) + z(5)^4;
-
-julia> str = Oscar.atlas_description(val)
-"b5"
-
-julia> val == atlas_irrationality(str)
-true
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::QQAbFieldElem, 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/PR4245/NumberTheory/galois/index.html b/previews/PR4245/NumberTheory/galois/index.html deleted file mode 100644 index 33ba7d28ac46..000000000000 --- a/previews/PR4245/NumberTheory/galois/index.html +++ /dev/null @@ -1,173 +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 (AbsSimpleNumField)
  • K a simple extension of an AbsSimpleNumField
  • 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 AbsSimpleNumField

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 specialized 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_verbosity_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_verbosity_level(:GaloisGroup, n::Int)
  • set_verbosity_level(:GaloisInvariants, n::Int)
galois_groupFunction
galois_group(K::AbsSimpleNumField, 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)
-(Permutation group of degree 4 and order 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{QadicFieldElem}:
- (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 = rational_function_field(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 QQ with defining polynomial a^3 + 54*t + 27, (1//12*_a^4 + (3//2*t + 3//4)*_a)//(t + 1//2))
- (Function Field over QQ with defining polynomial a^2 + 108*t^2 + 108*t + 27, _a^3)
- (Function Field over QQ with defining polynomial a^3 - 108*t^2 - 108*t - 27, -_a^2)
- (Function Field over QQ 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)
-(Permutation group of degree 6 and order 6, Galois context for s^6 + 108*t^2 + 540*t + 675)
-
-julia> G, C, k = galois_group(F, overC = true)
-(Permutation group of degree 6 and order 3, 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)
-(Permutation group of degree 4 and order 4, Galois context for x^4 - 5*x^2 + 6 and prime 11)
-
-julia> r = roots(C, 5)
-4-element Vector{QadicFieldElem}:
- 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)
- (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)
- (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)
-
-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 = rational_function_field(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])
-(Permutation group of degree 6 and order 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 generated by
-  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 generated by
-  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_verbosity_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.RelSimpleNumFieldElem{Hecke.RelSimpleNumFieldElem{AbsSimpleNumFieldElem}}}:
- 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])
-
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

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(3), Galois context for x^3 - 3*x + 17 and prime 7)
-
-julia> d = derived_series(G)
-3-element Vector{PermGroup}:
- Sym(3)
- Alt(3)
- Permutation group of degree 3 and order 1
-
-julia> fixed_field(C, d)
-(Relative number field of degree 3 over number field, a2)
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
diff --git a/previews/PR4245/NumberTheory/intro/index.html b/previews/PR4245/NumberTheory/intro/index.html deleted file mode 100644 index d8b7105a6214..000000000000 --- a/previews/PR4245/NumberTheory/intro/index.html +++ /dev/null @@ -1,2 +0,0 @@ - -Introduction · Oscar.jl
diff --git a/previews/PR4245/NumberTheory/vinberg/index.html b/previews/PR4245/NumberTheory/vinberg/index.html deleted file mode 100644 index f51c093a73a2..000000000000 --- a/previews/PR4245/NumberTheory/vinberg/index.html +++ /dev/null @@ -1,2 +0,0 @@ - -Vinberg's algorithm · Oscar.jl

Vinberg's algorithm

A Lorentzian lattice $L$ is an integral $\Z$-lattice of signature $(s_+, s_-)$ with $s_+=1$ and $s_->0$. A root of $r \in L$ is a primitive vector s.t. reflection in the hyperplane $r^\perp$ maps $L$ to itself. Let $W(L)\leq O(L)$ be the Weyl group, that is the group generated by reflections in the root hyperplanes of $L$. We say that $L$ is reflective if $W(L)$ is of finite index in $O(L)$. For $x,y \in L$ we write $x.y:=\Phi(x,y)$ and $x^2:=\Phi(x,x)$ for the symmetric bilinear form in $L$.

See for example [Tur18] for the theory of Arithmetic Reflection Groups and Reflective Lorentzian Lattices.

Description

Vinberg's algorithm constructs a fundamental polyhedron $P$ for a Lorentzian lattice $L$ by computing its fundamental roots $r$, i.e. the roots $r$ which are perpendicular to the faces of $P$ and which have inner product at least 0 with the elements of $P$. Choose $v_0$ in $L$ primitive with $v_0^2 > 0$ as a point that $P$ should contain.

Let $Q$ be the Gram matrix of $L$ with respect to some basis. A vector $r$ is a fundamental root, if

  • the vector $r$ is primitive,
  • reflection by $r$ preserves the lattice, i.e. $\frac{2}{r^2} r Q$ is an integer matrix,
  • the pair $(r, v_0)$ is positive oriented, i.e. $r. v_0 > 0$,
  • the product $r. \~{r} \geq \ 0$ for all roots $\~{r}$ already found.

This implies that $r^2$ divides $2 i$ for $i$ being the level of $Q$, i.e. the last invariant of the Smith normal form of $Q$.

$P$ can be constructed by solving $r.v_0 = n$ and $r^2 = k$ by increasing order of the value $\frac{n^2}{k}$ and $r$ satisfying the above conditions.

If $v_0$ lies on a root hyperplane, then $P$ is not uniquely determined. In that case we need a direction vector $v_1$ which satisfies $\~{v}. v_1 \neq 0$ for all possible roots $\~{v}$ with $v_0. \~{v} = 0$

With $v_0$ and $v_1$ fixed $P$ is uniquely determined for any choice of root lengths and maximal distance $v_0.r$. We choose the first roots $r$ by increasing order of the value $\frac{\~{r}. v_1}{r^2}$ for all possible roots $\~{v}$ with $v_0. \~{v} = 0$. For any other root length we continue as stated above.

For proofs of the statements above and further explanations see [Vin75].

Function

vinberg_algorithmFunction
vinberg_algorithm(Q::ZZMatrix, upper_bound; v0::ZZMatrix, root_lengths::Vector{ZZRingElem}, direction_vector::ZZMatrix) -> Vector{ZZMatrix}

Return the fundamental roots r of a given hyperbolic reflection lattice with standard basis represented by its corresponding Gram matrix Q with squared length contained in root_lengths and by increasing order of the value $\frac{r.v_0)^2}{r^2}$, stopping at upper_bound. If root_lengths is not defined it takes all possible values of $r^2$. If v0 lies on a root hyperplane and if there is no given direction_vector it is a random choice which reflection chamber next to v0 will be computed.

Arguments

  • Q: symmetric $\Z$ matrix of signature $(1, n)$ – the corresponding Gram matrix
  • upper_bound: the upper bound of the value $\frac{(r.v_0^2}{r^2}$
  • v0: primitive row vector with $v_0^2 > 0$
  • root_lengths: the possible integer values of $r^2$
  • direction_vector: row vector v1 with $v_0.v_1 = 0$ and $v.v_1 \neq 0$ for all possible roots v with $v.v_0 = 0$
source
vinberg_algorithm(S::ZZLat, upper_bound; v0::ZZMatrix, root_lengths::Vector{ZZRingElem}, direction_vector::ZZMatrix) -> Vector{ZZMatrix}

Return the fundamental roots r of a given hyperbolic reflection lattice S with standard basis with squared length contained in root_lengths and by increasing order of the value $\frac{r.v_0)^2}{r^2}$, stopping at upper_bound. If root_lengths is not defined it takes all possible values of $r^2$. If v0 lies on a root hyperplane and if there is no given direction_vector, then it is a random choice which reflection chamber next to v0 will be computed.

Arguments

  • S: a hyperbolic $\Z$-lattice of signature $(1,0,n)$.
  • upper_bound: the upper bound of the value $\frac{(r.v_0^2}{r^2}$
  • v0: primitive row vector with $v_0^2 > 0$ given w.r.t. the ambient space
  • root_lengths: the possible integer values of $r^2$
  • direction_vector: row vector v1 with $v_0.v_1 = 0$ and $v.v_1 \neq 0$ for all possible roots v with $v.v_0 = 0$, given w.r.t. the ambient space
  • divisibilities: a dictionary; The keys are the root lengths and the values are the divisibilities for the given root length. If given requires that a fundamental root $r$ has one of the specified divisibilities.
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/PR4245/PolyhedralGeometry/Polyhedra/auxiliary/index.html b/previews/PR4245/PolyhedralGeometry/Polyhedra/auxiliary/index.html deleted file mode 100644 index 89427d72f436..000000000000 --- a/previews/PR4245/PolyhedralGeometry/Polyhedra/auxiliary/index.html +++ /dev/null @@ -1,628 +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}}:
- Polytope in ambient dimension 3
- Polytope in ambient dimension 3
- Polytope in ambient dimension 3
- Polytope in ambient dimension 3
- Polytope in ambient dimension 3
- Polytope in ambient dimension 3
-
-julia> facets(Halfspace, C)
-6-element SubObjectIterator{AffineHalfspace{QQFieldElem}} over the halfspaces of R^3 described by:
--x_1 <= 1
-x_1 <= 1
--x_2 <= 1
-x_2 <= 1
--x_3 <= 1
-x_3 <= 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 <= 1
-x_1 <= 1
--x_2 <= 1
-x_2 <= 1
--x_3 <= 1
-x_3 <= 1
source
verticesMethod
vertices([as::Type{T} = PointVector,] P::Polyhedron)

Return an iterator over the vertices of P in the format defined by as. The vertices are defined to be the zero-dimensional faces, so if P has lineality, there are no vertices, only minimal faces.

See also minimal_faces and rays.

Optional arguments for as include

  • PointVector.

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(PointVector, P)
-5-element SubObjectIterator{PointVector{QQFieldElem}}:
- [-1, -1]
- [2, -1]
- [2, 1]
- [-1, 2]
- [1, 2]
-
-julia> point_matrix(vertices(P))
-[-1   -1]
-[ 2   -1]
-[ 2    1]
-[-1    2]
-[ 1    2]

A half-space (here in $3$-space) has no vertices:

julia> UH = polyhedron([-1 0 0], [0])
-Polyhedron in ambient dimension 3
-
-julia> vertices(UH)
-0-element SubObjectIterator{PointVector{QQFieldElem}}
source
raysMethod
rays([as::Type{T} = RayVector,] P::Polyhedron)

Return a minimal set of generators of the cone of unbounded directions of P (i.e. its rays) in the format defined by as. The rays are defined to be the one-dimensional faces of the recession cone, so if P has lineality, there are no rays.

See also rays_modulo_lineality, recession_cone and vertices.

Optional arguments for as include

  • RayVector.

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(RayVector, PO)
-2-element SubObjectIterator{RayVector{QQFieldElem}}:
- [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]

A half-space has no rays:

julia> UH = polyhedron([-1 0 0], [0])
-Polyhedron in ambient dimension 3
-
-julia> rays(UH)
-0-element SubObjectIterator{RayVector{QQFieldElem}}
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.

See also rays and lineality_space.

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.

See also vertices and lineality_space.

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_3 = 2
-x_4 = 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)
-Polytope in ambient dimension 3
-
-julia> is_lattice_polytope(c)
-true
-
-julia> c = cube(3, 0, 4//3)
-Polytope 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)
-Polytope 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

n_facetsMethod
n_facets(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> n_facets(cross_polytope(5))
-32
source
n_verticesMethod
n_vertices(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> n_vertices(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
facet_sizesMethod
facet_sizes(P::Polyhedron{T})

Number of vertices in each facet.

Example

julia> p = johnson_solid(4) 
-Polytope in ambient dimension 3 with EmbeddedAbsSimpleNumFieldElem type coefficients
-
-julia> facet_sizes(p)
-10-element Vector{Int64}:
- 8
- 4
- 3
- 4
- 4
- 3
- 4
- 3
- 3
- 4
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
vertex_sizesMethod
vertex_sizes(P::Polyhedron{T})

Number of incident facets for each vertex.

Example

julia> vertex_sizes(bipyramid(simplex(2)))
-5-element Vector{Int64}:
- 4
- 4
- 4
- 3
- 3
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)
-Polytope in ambient dimension 3
-
-julia> G = linear_symmetries(c)
-Permutation group of degree 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)
-Permutation group of degree 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)
-Permutation group of degree 4
-
-julia> order(G)
-8
-
-julia> G = linear_symmetries(quad)
-Permutation group of degree 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)
-Polytope 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)
-Polytope 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)
-Polytope 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)
-Polytope 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)

Return the integer points contained in the boundary of the bounded polyhedron P.

Examples

julia> c = polarize(cube(3))
-Polytope 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)
-Polytope in ambient dimension 3
-
-julia> Q = cube(3,-1,2)
-Polytope 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)
-Polytope 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)
-Polytope 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)
-Polytope 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)
-Polytope 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)

Return the integer points contained in the interior of the bounded polyhedron P.

Examples

julia> c = cube(3)
-Polytope 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)
-Polytope 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)
-Polytope 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)
-Polytope 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
is_archimedean_solidMethod
is_archimedean_solid(P::Polyhedron)

Check whether P is an Archimedean solid, i.e., a $3$-dimensional vertex transitive polytope with regular facets, but not a prism or antiprism.

See also archimedean_solid.

Note

This will only recognize algebraically precise solids, i.e. no solids with approximate coordinates.

Examples

julia> TO = archimedean_solid("truncated_octahedron")
-Polytope in ambient dimension 3
-
-julia> is_archimedean_solid(TO)
-true
-
-julia> T = tetrahedron()
-Polytope in ambient dimension 3
-
-julia> is_archimedean_solid(T)
-false
source
is_johnson_solidMethod
is_johnson_solid(P::Polyhedron)

Check whether P is a Johnson solid, i.e., a $3$-dimensional polytope with regular faces that is not vertex transitive.

See also johnson_solid.

Note

This will only recognize algebraically precise solids, i.e. no solids with approximate coordinates.

Examples

julia> J = johnson_solid(37)
-Polytope in ambient dimension 3 with EmbeddedAbsSimpleNumFieldElem type coefficients
-
-julia> is_johnson_solid(J)
-true
source
is_platonic_solidMethod
is_platonic_solid(P::Polyhedron)

Check whether P is a Platonic solid.

See also platonic_solid.

Note

This will only recognize algebraically precise solids, i.e. no solids with approximate coordinates.

Examples

julia> is_platonic_solid(cube(3))
-true
source
lattice_pointsMethod
lattice_points(P::Polyhedron)

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)
-Polytope in ambient dimension 2
-
-julia> P = polarize(square)
-Polytope 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([io = stdout,] A::AnyVecOrMat, b::AbstractVector; trivial = false, numbered = false, cmp = :lte)

Pretty print the constraints given by $P(A,b) = \{ x | Ax ≤ b \}$.

Optional & Keyword Arguments

  • io::IO: Target IO where the constraints are printed to.
  • trivial::Bool: If true, include trivial inequalities.
  • numbered::Bool: If true, the each constraint is printed with the index corresponding to the input AnyVecOrMat.
  • cmp::Symbol: Defines the string used for the comparison sign; supports :lte (less than or equal) and :eq (equal).

Trivial inequalities are always counted for numbering, even when omitted.

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_1 + 4*x_3 + 5*x_4 <= 0
-2: 4*x_1 + 4*x_2 + 4*x_3 + 3*x_4 <= 1
-3: x_1 <= 2
-5: 0 <= -4
-6: 9*x_1 + 9*x_2 + 9*x_3 + 9*x_4 <= 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_1 + 4*x_3 + 5*x_4 <= 0
-4*x_1 + 4*x_2 + 4*x_3 + 3*x_4 <= 1
-x_1 <= 2
-0 <= 3
-0 <= -4
-9*x_1 + 9*x_2 + 9*x_3 + 9*x_4 <= 5
source
print_constraintsMethod
print_constraints([io = stdout,] P::Polyhedron; trivial = false, numbered = false)

Pretty print the constraints given by $P(A,b) = \{ x | Ax ≤ b \}$.

Optional & Keyword Arguments

  • io::IO: Target IO where the constraints are printed to.
  • trivial::Bool: If true, include trivial inequalities.
  • numbered::Bool: If true, the each constraint is printed with the index corresponding to the input AnyVecOrMat.

Trivial inequalities are always counted for numbering, even when omitted.

Examples

The 3-cube is given by $-1 ≦ x_i ≦ 1 ∀ i ∈ \{1, 2, 3\}$.

julia> print_constraints(cube(3))
--x_1 <= 1
-x_1 <= 1
--x_2 <= 1
-x_2 <= 1
--x_3 <= 1
-x_3 <= 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)
-Polytope 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)
-Polytope 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)
-Polytope 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)
-Polytope 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)
-Polytope in ambient dimension 3
-
-julia> sc = secondary_polytope(c)
-Polytope 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. The solutions are the (transposed) rows of the output.
  • 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$. 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> it = solve_mixed(SubObjectIterator{PointVector{ZZRingElem}}, A, b, C);
-
-julia> typeof(it)
-SubObjectIterator{PointVector{ZZRingElem}}
-
-julia> for x in it
-       print(A*x," ")
-       end
-[7] [7] [7] [7] [7] [7] [7] [7] 
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. The solutions are the (transposed) rows of the output.
  • 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$. 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> it = solve_mixed(SubObjectIterator{PointVector{ZZRingElem}}, A, b, C);
-
-julia> typeof(it)
-SubObjectIterator{PointVector{ZZRingElem}}
-
-julia> for x in it
-       print(A*x," ")
-       end
-[3] [3] [3] [3] 
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/PR4245/PolyhedralGeometry/Polyhedra/constructions/index.html b/previews/PR4245/PolyhedralGeometry/Polyhedra/constructions/index.html deleted file mode 100644 index c2ac19869196..000000000000 --- a/previews/PR4245/PolyhedralGeometry/Polyhedra/constructions/index.html +++ /dev/null @@ -1,723 +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 [JT13]

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
polyhedronFunction
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_1 <= 0
-x_1 <= 1
-
-
-julia> affine_hull(P)
-1-element SubObjectIterator{AffineHyperplane{QQFieldElem}} over the hyperplanes of R^2 described by:
-x_2 = 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 [JT13].

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)
-Polytope in ambient dimension 7
-
-julia> facets(s)
-8-element SubObjectIterator{AffineHalfspace{QQFieldElem}} over the halfspaces of R^7 described by:
--x_1 <= 0
--x_2 <= 0
--x_3 <= 0
--x_4 <= 0
--x_5 <= 0
--x_6 <= 0
--x_7 <= 0
-x_1 + x_2 + x_3 + x_4 + x_5 + x_6 + x_7 <= 1
-
-julia> t = simplex(7, 5)
-Polytope in ambient dimension 7
-
-julia> facets(t)
-8-element SubObjectIterator{AffineHalfspace{QQFieldElem}} over the halfspaces of R^7 described by:
--x_1 <= 0
--x_2 <= 0
--x_3 <= 0
--x_4 <= 0
--x_5 <= 0
--x_6 <= 0
--x_7 <= 0
-x_1 + x_2 + x_3 + x_4 + x_5 + x_6 + x_7 <= 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)
-Polytope in ambient dimension 3
-
-julia> facets(C)
-8-element SubObjectIterator{AffineHalfspace{QQFieldElem}} over the halfspaces of R^3 described by:
-x_1 + x_2 + x_3 <= 1
--x_1 + x_2 + x_3 <= 1
-x_1 - x_2 + x_3 <= 1
--x_1 - x_2 + x_3 <= 1
-x_1 + x_2 - x_3 <= 1
--x_1 + x_2 - x_3 <= 1
-x_1 - x_2 - x_3 <= 1
--x_1 - x_2 - x_3 <= 1
-
-julia> D = cross_polytope(3, 2)
-Polytope in ambient dimension 3
-
-julia> facets(D)
-8-element SubObjectIterator{AffineHalfspace{QQFieldElem}} over the halfspaces of R^3 described by:
-x_1 + x_2 + x_3 <= 2
--x_1 + x_2 + x_3 <= 2
-x_1 - x_2 + x_3 <= 2
--x_1 - x_2 + x_3 <= 2
-x_1 + x_2 - x_3 <= 2
--x_1 + x_2 - x_3 <= 2
-x_1 - x_2 - x_3 <= 2
--x_1 - x_2 - x_3 <= 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.

See also is_platonic_solid.

Arguments

  • s::String: The name of the desired Platonic 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")
-Polytope in ambient dimension 3 with EmbeddedAbsSimpleNumFieldElem type coefficients
-
-julia> n_facets(T)
-20
source
archimedean_solidFunction
archimedean_solid(s)

Construct an Archimedean solid with the name given by String s from the list below.

See also is_archimedean_solid.

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. 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. This is a chiral polytope.

Examples

julia> T = archimedean_solid("cuboctahedron")
-Polytope in ambient dimension 3
-
-julia> sum([n_vertices(F) for F in faces(T, 2)] .== 3)
-8
-
-julia> sum([n_vertices(F) for F in faces(T, 2)] .== 4)
-6
-
-julia> n_facets(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. See the Polytope Wiki

See also is_johnson_solid.

source
catalan_solidFunction
catalan_solid(s::String)

Construct a Catalan solid with the name s from the list below.

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.
    • "pentagonal_hexecontahedron" : Pentagonal hexecontahedron. Dual polytope to the snub dodecahedron, made of 60 irregular pentagonal facets.
    • "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 -> n_vertices(F) == 3, faces(T, 2))
-12
-
-julia> n_facets(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

Like some of the Johnson solids, the following four Archimedean and Catalan solids are constructed using serialized data. In order to properly document the respective sources, they also come as seperate functions.

Other polytope constructions

SIM_body_polytopeFunction
SIM_body_polytope(alpha::AbstractVector)

Produce an $n$-dimensional SIM-body as generalized permutahedron in $(n+1)$-space. SIM-bodies are defined in [GK14], but the input needs to be descending instead of ascending, as used in [JKS22], i.e. alpha has parameters $(a_1,\dots,a_n)$ such that $a_1 \geq \dots \geq a_n \geq 0$.

Example

To produce a $2$-dimensional SIM-body, use for example the following code. Note that the polytope lives in $3$-space, so we project it down to $2$-space by eliminating the last coordinate.

julia> s = SIM_body_polytope([3,1])
-Polyhedron in ambient dimension 3
-
-julia> p = convex_hull(map(x->x[1:dim(s)],vertices(s)))
-Polyhedron in ambient dimension 2
-
-julia> vertices(p) 
-5-element SubObjectIterator{PointVector{QQFieldElem}}:
- [0, 0]
- [3, 0]
- [3, 1]
- [0, 3]
- [1, 3]
source
associahedronFunction
associahedron(d::Int)

Produce a $d$-dimensional associahedron (or Stasheff polytope). We use the facet description given in section 9.2. of [Zie95].

Note that in polymake, this function has an optional Boolean parameter group, to also construct the symmetry group of the polytope. For details, see [CSZ15].

Example

Produce the $2$-dimensional associahedron is a polygon in $\mathbb{R}⁴$ having $5$ vertices and $5$ facets.

julia> A =  associahedron(2)
-Polyhedron in ambient dimension 4
-
-julia> vertices(A)
-5-element SubObjectIterator{PointVector{QQFieldElem}}:
- [9, 4, 1, 10]
- [10, 1, 4, 9]
- [1, 10, 1, 9]
- [1, 4, 9, 6]
- [4, 1, 10, 6]
-
-julia> facets(A)
-5-element SubObjectIterator{AffineHalfspace{QQFieldElem}} over the halfspaces of R^4 described by:
--x_1 <= -1
--2*x_1 - 2*x_2 <= -10
--x_2 <= -1
--2*x_2 - 2*x_3 <= -10
--x_3 <= -1
source
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
binary_markov_graph_polytopeFunction
binary_markov_graph_polytope(observation::AbstractVector)

Defines a very simple graph for a polytope propagation related to a Hidden Markov Model. The length of observation is the number of possible oberservations. Its elements are of types Bool or Int. The propagated polytope is always a polygon. For a detailed description see [Jos05].

Examples

julia> P = binary_markov_graph_polytope([1,1,1,1])
-Polyhedron in ambient dimension 2
-
-julia> vertices(P)
-4-element SubObjectIterator{PointVector{QQFieldElem}}:
- [3, 0]
- [1, 1]
- [0, 2]
- [0, 7]
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)
-Polytope 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_caratheodory_polytopeFunction
cyclic_caratheodory_polytope(d::Int, n::Int)

Produce a $d$-dimensional cyclic polytope with $n$ points. Clearly $n\geq d$ is required. It is a prototypical example of a neighborly polytope whose combinatorics completely known due to Gale's evenness criterion. The coordinates are chosen on the trigonometric moment curve.

Example

julia> C= cyclic_caratheodory_polytope(4,5)
-Polytope in ambient dimension 4
-
-julia> vertices(C)
-5-element SubObjectIterator{PointVector{QQFieldElem}}:
- [1, 0, 1, 0]
- [347922205179541//1125899906842624, 8566355544790271//9007199254740992, -7286977268806823//9007199254740992, 5294298886396511//9007199254740992]
- [-7286977268806823//9007199254740992, 5294298886396511//9007199254740992, 1391688820718163//4503599627370496, -33462326346837//35184372088832]
- [-7286977268806825//9007199254740992, -5294298886396509//9007199254740992, 5566755282872661//18014398509481984, 8566355544790271//9007199254740992]
- [1391688820718163//4503599627370496, -33462326346837//35184372088832, -3643488634403413//4503599627370496, -5294298886396507//9007199254740992]
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)
-Polytope in ambient dimension 3
-
-julia> n_vertices(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)
-Polytope in ambient dimension 4
-
-julia> f_vector(DP)
-4-element Vector{ZZRingElem}:
- 10
- 40
- 60
- 30
source
dwarfed_cubeFunction
dwarfed_cube(d::Int)

Produce the $d$-dimensional dwarfed cube as defined in [ABS97].

Example

The $3$-dimensional dwarfed cube is illustrated in [Jos03].

julia> c = dwarfed_cube(3)
-Polytope in ambient dimension 3
-
-julia> vertices(c)
-10-element SubObjectIterator{PointVector{QQFieldElem}}:
- [1//2, 0, 1]
- [1//2, 1, 0]
- [1, 0, 1//2]
- [1, 1//2, 0]
- [1, 0, 0]
- [0, 0, 0]
- [0, 1, 0]
- [0, 1//2, 1]
- [0, 0, 1]
- [0, 1, 1//2]
source
dwarfed_product_polygonsFunction
dwarfed_product_polygons(d::Int, s::Int)

Produce a $d$-dimensional dwarfed product of polygons of size $s$ as defined in [ABS97]. It must be $d\geq4$ and even as well as $s\geq 3$.

Example

julia> p = dwarfed_product_polygons(4,3)
-Polytope in ambient dimension 4
-
-julia> vertices(p)
-11-element SubObjectIterator{PointVector{QQFieldElem}}:
- [5, 3, 0, 0]
- [5, 0, 0, 0]
- [2, 0, 3, 9]
- [0, 0, 5, 3]
- [0, 0, 3, 9]
- [2, 6, 3, 9]
- [0, 0, 5, 0]
- [0, 0, 0, 0]
- [3, 9, 2, 6]
- [3, 9, 2, 0]
- [3, 9, 0, 0]
source
explicit_zonotopeFunction
explicit_zonotope(zones::Matrix; rows_are_points::Bool=true)

Produce the points of a zonotope as the iterated Minkowski sum of all intervals $[-x,x]$, where $x$ ranges over the rows of the input matrix zones. If rows_are_points is true (default), the rows of the input matrix represent affine points, otherwise they represent linear vectors.

Examples

julia> Z = explicit_zonotope([1 1; 1 -1], rows_are_points=false)
-Polyhedron in ambient dimension 2
-
-julia> vertices(Z)
-4-element SubObjectIterator{PointVector{QQFieldElem}}:
- [2, 0]
- [0, -2]
- [0, 2]
- [-2, 0]
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.

Keywords

  • d::Int: the dimension.

Examples

julia> S = fano_simplex(3)
-Polytope 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)
-Polytope in ambient dimension 6
source
fractional_knapsack_polytopeFunction
fractional_knapsack_polytope(b::AbstractVector{<:Base.Number})

Produce a knapsack polytope defined by one linear inequality (and non-negativity constraints).

Example

julia> f = fractional_knapsack_polytope([10,-2,-3,-5])
-Polytope in ambient dimension 3
-
-julia> print_constraints(f)
-2*x_1 + 3*x_2 + 5*x_3 <= 10
--x_1 <= 0
--x_2 <= 0
--x_3 <= 0
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)
-Polytope 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
goldfarb_cubeFunction
goldfarb_cube(d::Int, e::Number, g::Number)

Produce a d-dimensional Goldfarb cube. The first parameter of deformation e must be $<\frac{1}{2}$, the second parameter of deformation d must be $\geq \frac{\texttt{e}}{4}$.

The Goldfarb cube is a combinatorial cube and yields a bad example for the Simplex Algorithm using the Shadow Vertex Pivoting Strategy. Here we use the description as a deformed product due to [AZ99]. For $g=0$ we obtain a Klee-Minty cube, in particular for $e=g=0$ we obtain the standard cube.

Example

The following produces a $3$-dimensional Klee-Minty cube for $e=\frac{1}{3}$.

julia> c = goldfarb_cube(3,1//3,0)
-Polytope in ambient dimension 3
-
-julia> vertices(c)
-8-element SubObjectIterator{PointVector{QQFieldElem}}:
- [1, 1//3, 8//9]
- [1, 2//3, 7//9]
- [1, 2//3, 2//9]
- [1, 1//3, 1//9]
- [0, 0, 0]
- [0, 1, 1//3]
- [0, 1, 2//3]
- [0, 0, 1]
source
goldfarb_sit_cubeFunction
goldfarb_sit_cube(d::Int, eps::Number, delta::Number)

Produces a d-dimensional variation of the Klee-Minty cube, which is scaled in direction $x_{d-i}$ by eps*delta^i. The first parameter of deformation eps must be $<\frac{1}{2}$, the second parameter of deformation delta must be $\geq \frac{1}{2}$. This cube is a combinatorial cube and yields a bad example for the Simplex Algorithm using the Steepest Edge Pivoting Strategy. Here we use a scaled description of the construction of Goldfarb and Sit, see [GS79].

Examples

julia> c = goldfarb_sit_cube(3,1//3,1//2)
-Polytope in ambient dimension 3
-
-julia> vertices(c) 
-8-element SubObjectIterator{PointVector{QQFieldElem}}:
- [1//36, 1//18, 8//9]
- [1//36, 1//9, 7//9]
- [1//36, 1//9, 2//9]
- [1//36, 1//18, 1//9]
- [0, 0, 0]
- [0, 1//6, 1//3]
- [0, 1//6, 2//3]
- [0, 0, 1]
source
hypersimplexFunction
hypersimplex(k::Int, d::Int; no_vertices::Bool=false, no_facets::Bool=false, no_vif::Bool=false)

Produce the hypersimplex $\Delta(k,d)$, that is the the convex hull of all $0/1$-vector in $\mathbb{R}^d$ with exactly $k$ ones. Note that the output is never full-dimensional.

Optional Arguments

  • no_vertices::Bool: If set equal to true, vertices of the underlying polymake object are not computed.
  • no_facets::Bool: If set equal to true, facets of the underlying polymake object are not computed.
  • no_vif::Bool: If set equal to true, vertices in facets of the underlying polymake object are not computed.

Example

julia> H = hypersimplex(3,4)
-Polytope in ambient dimension 4
-
-julia> G = hypersimplex(3,4,no_facets=true)
-Polytope in ambient dimension 4
-
-julia> facets(G)
-4-element SubObjectIterator{AffineHalfspace{QQFieldElem}} over the halfspaces of R^4 described by:
-x_4 <= 1
-x_3 <= 1
--x_1 - x_3 - x_4 <= -2
-x_1 <= 1
-
-julia> facets(H)
-4-element SubObjectIterator{AffineHalfspace{QQFieldElem}} over the halfspaces of R^4 described by:
-x_4 <= 1
-x_3 <= 1
--x_1 - x_3 - x_4 <= -2
-x_1 <= 1
source
hypertruncated_cubeFunction
hypertruncated_cube(d::Int, k::Number, lambda::Number)

Produce a $d$-dimensional hypertruncated cube with symmetric linear objective function $(1,1,…,1)$.

Arguments

  • k: cutoff parameter
  • lambda: scaling of extra vertex

Example

julia> H = hypertruncated_cube(3,2,3)
-Polytope in ambient dimension 3
-
-julia> print_constraints(H)
--x_1 <= 0
--x_2 <= 0
--x_3 <= 0
-x_1 <= 1
-x_2 <= 1
-x_3 <= 1
-5*x_1 - 2*x_2 - 2*x_3 <= 3
--2*x_1 + 5*x_2 - 2*x_3 <= 3
--2*x_1 - 2*x_2 + 5*x_3 <= 3
source
k_cyclic_polytopeFunction
k_cyclic_polytope(n::Int, s::Vector)

Produce a (rounded) $2*k$-dimensional $k$-cyclic polytope with n points, where $k$ is the length of the input vector s. Special cases are the bicyclic ($k=2$) and tricyclic ($k=3$) polytopes. Only possible in even dimensions.

The parameters $\texttt{s}_i$ can be integers, floating-points or rational numbers. The $i$-th vertex then is: $(\cos(\texttt{s}_1 * 2\pi i/\texttt{n}), \sin(\texttt{s}_1 * 2\pi i/\texttt{n}), ... , \cos(\texttt{s}_k * 2\pi i/\texttt{n}), \sin(\texttt{s}_k * 2\pi i/\texttt{n}))$.

Warning: Some of the $k-$cyclic polytopes are not simplicial. Since the components are rounded, this function might output a polytope which is not a $k-$cyclic polytope! More information see [Sch95].

Example

To produce a (not exactly) regular pentagon, type this:

julia> p = k_cyclic_polytope(5,[1])
-Polytope in ambient dimension 2
-
-julia> dim(p) 
-2
-
-julia> n_vertices(p)
-5
source
klee_minty_cubeFunction
klee_minty_cube(d::Int, e::Number)

Produces a $d-$dimensional Klee-Minty-cube if $\texttt{e} < 1/2$. Uses the goldfarb_cube method with the argument $\texttt{g} = 0$.

#Example

julia> k = klee_minty_cube(3,1//8)
-Polytope in ambient dimension 3
-
-julia> print_constraints(k)
--x_1 <= 0
-x_1 <= 1
-1//8*x_1 - x_2 <= 0
-1//8*x_1 + x_2 <= 1
-1//8*x_2 - x_3 <= 0
-1//8*x_2 + x_3 <= 1
source
lecture_hall_simplexFunction
lecture_hall_simplex(d::Int)

Produce the $d$-dimensional lecture hall simplex for the sequence $(s_i)=i$ for $1\geq i \geq d$ as defined in [SS12].

Note that in polymake, this function has an optional Boolean parameter group, to also construct the symmetry group of the simplex.

Example

The $3$-dimensional lecture hall simplex:

julia> S = lecture_hall_simplex(3) 
-Polytope in ambient dimension 3
-
-julia> vertices(S)
-4-element SubObjectIterator{PointVector{QQFieldElem}}:
- [0, 0, 0]
- [0, 0, 3]
- [0, 2, 3]
- [1, 2, 3]
source
max_GC_rank_polytopeFunction
max_GC_rank_polytope(d::Int)

Produce a d-dimensional polytope of maximal Gomory-Chvatal rank $\Omega(d/\log(d))$, integrally infeasible. With symmetric linear objective function $(1,1..,1)$. Construction due to Pokutta and Schulz, see [PS11].

Example

julia> c = max_GC_rank_polytope(3)
-Polytope in ambient dimension 3
-
-julia> vertices(c)
-6-element SubObjectIterator{PointVector{QQFieldElem}}:
- [0, 1//2, 1//2]
- [1//2, 0, 1//2]
- [1//2, 1//2, 0]
- [1//2, 1, 1//2]
- [1//2, 1//2, 1]
- [1, 1//2, 1//2]
source
n_gonFunction
n_gon(n::Int; r::RationalUnion=1, alpha_0::RationalUnion=0)

Produce a regular n-gon. All vertices lie on a circle of radius r (defaults to $1$) and initial angle divided by pi alpha_0 (defaults to $0$).

Examples

To store the regular pentagon in the variable p, do this:

julia> p = n_gon(3)
-Polytope in ambient dimension 2 with QQBarFieldElem type coefficients
-
-julia> volume(n_gon(4, r=2, alpha_0=1//4))
-Root 8.00000 of x - 8
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
permutahedronFunction
permutahedron(d::Int)

Produce a d-dimensional permutahedron. The vertices correspond to the elements of the symmetric group of degree d$+1$.

#Example

julia> p = permutahedron(2)
-Polytope 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
pile_polytopeFunction
pile_polytope(sizes::Vector{Int})

Produce a $($d$+1)$-dimensional polytope from a pile of cubes. Start with a d-dimensional pile of cubes. Take a generic convex function to lift this polytopal complex to the boundary of a $($d$+1)$–polytope. The argument sizes is a vector $(s_1,…,s_d)$ where $s_i$ specifies the number of boxes in the $i$-th dimension.

source
pitman_stanley_polytopeFunction
pitman_stanley_polytope(y::AbstractVector)

Produce a Pitman-Stanley polytope of dimension $n-1$, where y is a Vector of $n$ positive parameters. Does not check if the parameters are actually positive; negative values are legal but that do not yield a Pitman-Stanley polytope. Zeros just reduce the dimension; negative numbers may produce unbounded polyhedra.

Example:

Pitman-Stanley polytopes are combinatorial cubes:

julia> p = pitman_stanley_polytope([1,2,3])
-Polyhedron in ambient dimension 3
-
-julia> f_vector(p) 
-2-element Vector{ZZRingElem}:
- 4
- 4
source
perles_nonrational_8_polytopeFunction
perles_nonrational_8_polytope()

Create an $8$-dimensional polytope without rational realizations due to Perles. See [Gru03].

Example

julia> perles_nonrational_8_polytope()
-Polytope in ambient dimension 8 with EmbeddedAbsSimpleNumFieldElem type coefficients
source
pseudo_del_pezzo_polytopeFunction
pseudo_del_pezzo_polytope(d::Int)

Produce a d-dimensional del-Pezzo polytope, which is the convex hull of the cross polytope together with the all-ones vector. All coordinates are plus or minus one.

Example

julia> DP = pseudo_del_pezzo_polytope(4)
-Polytope in ambient dimension 4
-
-julia> f_vector(DP)
-4-element Vector{ZZRingElem}:
- 9
- 32
- 46
- 23
source
rand01_polytopeFunction
rand01_polytope(d::Int, n::Int; seed=nothing)

Produce a d-dimensional $0/1$-polytope with n random vertices. Uniform distribution.

Optional Argument

-seed::Int: Seed for random number generation

Example

julia> s = rand01_polytope(2, 4; seed=3)
-Polytope in ambient dimension 2
-
-julia> vertices(s)
-4-element SubObjectIterator{PointVector{QQFieldElem}}:
- [1, 1]
- [1, 0]
- [0, 0]
- [0, 1]
source
rand_box_polytopeFunction
rand_box_polytope(d::Int, n::Int, b::Int; seed::Int=nothing)

Computes the convex hull of n points sampled uniformly at random from the integer points in the cube $[0,\texttt{b}]^{\texttt{d}}$.

Optional Argument

-seed: Seed for random number generation.

Example

julia> r = rand_box_polytope(3, 10, 3, seed=1)
-Polyhedron in ambient dimension 3
-
-julia> vertices(r) 
-8-element SubObjectIterator{PointVector{QQFieldElem}}:
- [3, 2, 3]
- [0, 3, 0]
- [3, 3, 0]
- [3, 0, 1]
- [1, 1, 0]
- [2, 0, 3]
- [0, 3, 3]
- [0, 1, 2]
source
rand_cyclic_polytopeFunction
rand_cyclic_polytope(d::Int, n::Int; seed::Int=nothing)

Computes a random instance of a cyclic polytope of dimension d on n vertices by randomly generating a Gale diagram whose cocircuits have alternating signs.

Optional Argument

-seed: Seed for random number generation

Examples

julia> r = rand_cyclic_polytope(3, 5)
-Polytope in ambient dimension 3
-
-julia> f_vector(r)
-3-element Vector{ZZRingElem}:
- 5
- 9
- 6
source
rand_metricFunction
rand_metric(n::Int; seed=nothing)

Produce a rational n-point metric with random distances. The values are uniformily distributed in $[1, 2]$.

Examples

julia> rand_metric(3, seed=132)
-[                               0   260222460282405//140737488355328   371474612593257//281474976710656]
-[260222460282405//140737488355328                                  0   388326899436839//281474976710656]
-[371474612593257//281474976710656   388326899436839//281474976710656                                  0]
-
source
rand_metric_intFunction
rand_metric_int(n::Int, digits::Int; seed=nothing)

Produce a n-point metric with random integral distances. The values are uniformily distributed in $[1, 2]$. The distances are integers and lie in $[10^digits, 10^(digits+1)[$.

source
rand_normal_polytopeFunction
rand_normal_polytope(d::Int, n::Int; seed=nothing, precision=nothing)

Produce a rational d-dimensional polytope from n random points approximately normally distributed in the unit ball.

Optional Arguments

-seed: controls the outcome of the random number generator; fixing a seed number guarantees the same outcome -precision: number of bits for MPFR sphere approximation

Example

julia> rnp = rand_normal_polytope(2,4; seed=42, precision=4)
-Polytope in ambient dimension 2
-
-julia> is_simplicial(rnp)
-true
-
-julia> sort(map(x->dot(x,x), vertices(rnp)))
-4-element Vector{QQFieldElem}:
- 1417//4096
- 481//1024
- 225//256
- 101//32
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)
-Polytope in ambient dimension 3
-
-julia> is_simplicial(rsph)
-true
-
-julia> rsph = rand_spherical_polytope(3, 4; precision=5, seed=132)
-Polytope 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)
-Polytope 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> n_vertices(rand_subpolytope(cube(3), 5))
-5
-
source
rss_associahedronFunction
rss_associahedron(n::Int)

Produce a polytope of constrained expansions in ambient dimension n according to [RSS03].

Examples:

To produce a $3$-dimensional associahedron in $5$-space, do:

julia> a= rss_associahedron(5)
-Polyhedron in ambient dimension 5
-
-julia> vertices(a)
-14-element SubObjectIterator{PointVector{QQFieldElem}}:
- [0, 1, 12, 13, 16]
- [0, 7, 8, 11, 16]
- [0, 1, 4, 9, 16]
- [0, 3, 4, 9, 16]
- [0, 5, 6, 9, 16]
- [0, 5, 8, 9, 16]
- [0, 1, 8, 9, 16]
- [0, 7, 10, 11, 16]
- [0, 7, 12, 13, 16]
- [0, 7, 12, 15, 16]
- [0, 1, 12, 15, 16]
- [0, 7, 8, 15, 16]
- [0, 1, 4, 15, 16]
- [0, 3, 4, 15, 16]
-
-julia> facets(a) 
-9-element SubObjectIterator{AffineHalfspace{QQFieldElem}} over the halfspaces of R^5 described by:
-x_1 - x_2 <= -1
-x_1 - x_3 <= -4
-x_1 - x_4 <= -9
-x_2 - x_3 <= -1
-x_2 - x_4 <= -4
-x_2 - x_5 <= -9
-x_3 - x_4 <= -1
-x_3 - x_5 <= -4
-x_4 - x_5 <= -1
source
signed_permutahedronFunction
signed_permutahedron(d::Int)

Produce the d-dimensional signed permutahedron. I.e. for all possible permutations of the vector $(1,\dots,d)$, all possible sign patterns define vertices of this polytope. Contrary to the classical permutahedron, the signed permutahedron is full-dimensional.

Examples:

To produce the $2$-dimensional signed permutahedron, do:

julia> P = signed_permutahedron(2)
-Polytope in ambient dimension 2
-
-julia> vertices(P)
-8-element SubObjectIterator{PointVector{QQFieldElem}}:
- [1, 2]
- [-1, 2]
- [1, -2]
- [-1, -2]
- [2, 1]
- [-2, 1]
- [2, -1]
- [-2, -1]
source
stable_set_polytopeFunction
stable_set_polytope(G::Graph{Undirected})

Produces the stable set polytope from an undirected graph G$=(V,E)$. The stable set Polytope has the following inequalities: $x_i + x_j \leq 1 \forall \{i,j\} \in E$, $x_i \geq 0 \forall i \in V$ and $x_i \leq 1 \forall i \in V \text{ with } \mathrm{deg}(i)=0$

Example:

The following produces first the standard cube in $3$ dimensions, and then a bipyramid over the convex hull of the unit vectors.

julia> G = Graph{Undirected}(3)
-Undirected graph with 3 nodes and no edges
-
-julia> S = stable_set_polytope(G)
-Polytope in ambient dimension 3
-
-julia> vertices(S)
-8-element SubObjectIterator{PointVector{QQFieldElem}}:
- [1, 0, 0]
- [1, 1, 0]
- [1, 1, 1]
- [1, 0, 1]
- [0, 0, 1]
- [0, 0, 0]
- [0, 1, 0]
- [0, 1, 1]
-
-julia> add_edge!(G, 1, 2);
-
-julia> add_edge!(G, 1, 3);
-
-julia> add_edge!(G, 2, 3);
-
-julia> S = stable_set_polytope(G)
-Polytope in ambient dimension 3
-
-julia> vertices(S)
-5-element SubObjectIterator{PointVector{QQFieldElem}}:
- [0, 0, 1]
- [0, 1, 0]
- [1, 0, 0]
- [1//2, 1//2, 1//2]
- [0, 0, 0]
source
transportation_polytopeFunction
transportation_polytope(r::AbstractVector, c::AbstractVector)

Produce the transportation polytope from two vectors r of length $m$ and c of length $n$, i.e. all positive $m\times n$ Matrizes with row sums equal to r and column sums equal to c.

Example:

We can see that the set of $3\times 3$ magic squares with magic constant $15$ is a $4$-dimensional polytope.

julia> r = c = [15,15,15]
-3-element Vector{Int64}:
- 15
- 15
- 15
-
-julia> t = transportation_polytope(r,c) 
-Polytope in ambient dimension 9
-
-julia> dim(t) 
-4
-
-julia> is_bounded(t) 
-true
source
zonotopeFunction
zonotope(M::Matrix{<:Number}; centered::Bool=true)

Create a zonotope from a matrix whose rows are input points.

Optional Arguments

  • centered::Bool: This is true if the output should be centered; the default is true.

Examples

The following produces a parallelogram with the origin as its vertex barycenter:

julia> Z = zonotope([1 0; 1 1])
-Polyhedron in ambient dimension 2
-
-julia> vertices(Z)
-4-element SubObjectIterator{PointVector{QQFieldElem}}:
- [-1, -1//2]
- [0, -1//2]
- [0, 1//2]
- [1, 1//2]

The following produces a parallelogram with the origin being a vertex (not centered case):

julia> Z = zonotope([1 0; 1 1], centered = false)
-Polyhedron in ambient dimension 2
-
-julia> vertices(Z)
-4-element SubObjectIterator{PointVector{QQFieldElem}}:
- [0, 0]
- [1, 0]
- [1, 1]
- [2, 1]
source
zonotope_vertices_fukuda_matrixFunction
zonotope_vertices_fukuda(M::Matrix)

Create the vertices of a zonotope from a matrix whose rows are input points or vectors.

Examples

The following creates the vertices of a parallelogram with the origin as its vertex barycenter.

julia> zonotope_vertices_fukuda_matrix([1 1 0; 1 1 1])
-pm::Matrix<pm::Rational>
--1 -1 -1/2
-0 0 -1/2
-0 0 1/2
-1 1 1/2
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> n_vertices(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)
-Polytope in ambient dimension 2
-
-julia> S=cube(1)
-Polytope 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)
-Polytope 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)
-Polytope 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
vertex_figureFunction
vertex_figure(P::Polyhedron, n::Int; cutoff=1//2)

Construct the vertex figure of the vertex n of a bounded polytope. The vertex figure is dual to a facet of the dual polytope.

Optional Arguments

  • cutoff::Number: controls the exact location of the cutting hyperplane. It should lie in the open Interval $(0,1)$. Value $0$ would let the hyperplane go through the chosen vertex, thus degenerating the vertex figure to a single point. Value $1$ would let the hyperplane touch the nearest neighbor vertex of a polyhedron. Default value is $\frac{1}{2}$.

Example

To produce a triangular vertex figure of a $3$-dimensional cube in the positive orthant, do:

julia> T = vertex_figure(cube(3), 8) 
-Polyhedron in ambient dimension 3
-
-julia> vertices(T)
-3-element SubObjectIterator{PointVector{QQFieldElem}}:
- [1, 1, 0]
- [1, 0, 1]
- [0, 1, 1]
-
-julia> T = vertex_figure(cube(3), 8, cutoff = 1/4)
-Polyhedron in ambient dimension 3
-
-julia> vertices(T)
-3-element SubObjectIterator{PointVector{QQFieldElem}}:
- [1, 1, 1//2]
- [1, 1//2, 1]
- [1//2, 1, 1]
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/PR4245/PolyhedralGeometry/Polyhedra/intro/index.html b/previews/PR4245/PolyhedralGeometry/Polyhedra/intro/index.html deleted file mode 100644 index f0ec0d6e720b..000000000000 --- a/previews/PR4245/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/PR4245/PolyhedralGeometry/Polyhedra/polymake/index.html b/previews/PR4245/PolyhedralGeometry/Polyhedra/polymake/index.html deleted file mode 100644 index fcc801b7a7e2..000000000000 --- a/previews/PR4245/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 ([GJ00], polymake.org) is open source software for research in polyhedral geometry and is attached to Julia via Polymake.jl ([KLT20], 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)
-Polytope 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/PR4245/PolyhedralGeometry/cones/index.html b/previews/PR4245/PolyhedralGeometry/cones/index.html deleted file mode 100644 index b22cffc2233e..000000000000 --- a/previews/PR4245/PolyhedralGeometry/cones/index.html +++ /dev/null @@ -1,234 +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 non-negative 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 = incidence_matrix([[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
facet_degreesMethod
facet_degrees(C::Cone)

Facet degrees of the cone. The degree of a facet is the number of adjacent facets. In particular a general $2$-dimensional cone has two facets (rays) that meet at the origin.

Example

Produce the facet degrees of a cone over a square and a cone over a square pyramid.

julia> c = positive_hull([1 1 0; 1 -1 0; 1 0 1; 1 0 -1])
-Polyhedral cone in ambient dimension 3
-
-julia> facet_degrees(c)
-4-element Vector{Int64}:
- 2
- 2
- 2
- 2
-
-julia> c = positive_hull([1 0 1 0; 1 0 -1 0; 1 0 0 1; 1 0 0 -1; 1 1 0 0])
-Polyhedral cone in ambient dimension 4
-
-julia> facet_degrees(c)
-5-element Vector{Int64}:
- 4
- 3
- 3
- 3
- 3
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)
-Polytope 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
n_facetsMethod
n_facets(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> n_facets(C)
-4
source
n_raysMethod
n_rays(C::Cone)

Return the number of rays of C.

Examples

Here a cone is constructed from three rays. Calling number_of_rays reveals that one of these was redundant:

julia> R = [1 0; 0 1; 0 2];
-
-julia> PO = positive_hull(R);
-
-julia> n_rays(PO)
-2
source
raysMethod
rays([as::Type{T} = RayVector,] C::Cone)

Return the rays of C in the format defined by as. The rays are defined to be the one-dimensional faces, so if C has lineality, there are no rays.

See also rays_modulo_lineality.

Optional arguments for as include

  • RayVector.

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(RayVector, P))
-[1      0]
-[1   3//2]
-
-julia> matrix(ZZ, rays(P))
-[1   0]
-[2   3]

A half-space has no rays:

julia> UH = cone_from_inequalities([-1 0 0])
-Polyhedral cone in ambient dimension 3
-
-julia> rays(UH)
-0-element SubObjectIterator{RayVector{QQFieldElem}}
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.

See also rays and lineality_space.

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
ray_degreesMethod
ray_degrees(C::Cone)

Ray degrees of the cone. If the cone has lineality, the output is empty since there are no rays that are also faces.

Examples

julia> c = cone_from_inequalities([-1 0 0; 0 -1 0])
-Polyhedral cone in ambient dimension 3
-
-julia> ray_degrees(c)
-Int64[]
-
-julia> c = positive_hull([1 0 1 0; 1 0 -1 0; 1 0 0 1; 1 0 0 -1; 1 1 0 0])
-Polyhedral cone in ambient dimension 4
-
-julia> ray_degrees(c) 
-5-element Vector{Int64}:
- 3
- 3
- 3
- 3
- 4
source
diff --git a/previews/PR4245/PolyhedralGeometry/fans/index.html b/previews/PR4245/PolyhedralGeometry/fans/index.html deleted file mode 100644 index 7ea2b7148280..000000000000 --- a/previews/PR4245/PolyhedralGeometry/fans/index.html +++ /dev/null @@ -1,268 +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 = incidence_matrix([[1,2],[2,3],[3,4],[4,5],[1,5]]);
-
-julia> PF=polyhedral_fan(IM, R)
-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 = incidence_matrix([[1],[2]]);
-
-julia> PF=polyhedral_fan(IM, R, L)
-Polyhedral fan in ambient dimension 3
-
-julia> lineality_dim(PF)
-1
source
polyhedral_fan(cones::AbstractVector{Cone{T}}) where T<:scalar_types

Assemble a polyhedral fan from a non-empty list of cones.

source
polyhedral_fan(v::NormalToricVarietyType)

Return the fan of an abstract normal toric variety v.

Examples

julia> p2 = projective_space(NormalToricVariety, 2)
-Normal toric variety
-
-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) == n_facets(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(TropV::TropicalVariety)

See ambient_dim(::PolyhedralComplex).

source
arrangement_polynomialFunction
arrangement_polynomial([ring::MPolyRing{<: FieldElem},] A::MatElem{<: FieldElem})

Given some $A\in\mathbb{F}^{n\times d},$ return the product of the linear forms corresponding to the rows.

Let $A$ be a $n\times d$ matrix with entries from a field $\mathbb{F}$. The rows of $A$ are the normal vectors for a hyperplane arrangement $\mathcal{A} = \{H_{1},\dots,H_{n}:H_{i}\subset \mathbb{F}^{d}\}.$ We have $H_{i} = V(\alpha_{i})$, where $\alpha_{i}\in\mathbb{F}[x_{1},\dots,x_{d}]$ is a linear form whose coefficients are the entries of the $i$th row.

Then we have $\cup_{H_{i}\in\mathcal{A}}H_{i} = V(\Pi^{n}_{i=1}\alpha_{i}).$

Optionally one can select to use columns instead of rows in the following way:

arrangement_polynomial(...  ; hyperplanes=:in_cols)

Example using standard ring and then custom ring.

julia> A = matrix(QQ,[1 2 5//2; 0 0 1; 2 3 2; 1//2 3 5; 3 1 2; 7 8 1])
-[   1   2   5//2]
-[   0   0      1]
-[   2   3      2]
-[1//2   3      5]
-[   3   1      2]
-[   7   8      1]
-
-julia> factor(arrangement_polynomial(A))
-(1//4) * (2*x1 + 3*x2 + 2*x3) * (7*x1 + 8*x2 + x3) * (x1 + 6*x2 + 10*x3) * (2*x1 + 4*x2 + 5*x3) * x3 * (3*x1 + x2 + 2*x3)
-
-julia> R,_ = polynomial_ring(QQ, [:x, :y, :z])
-(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])
-
-julia> factor(arrangement_polynomial(R, A))
-(1//4) * (2*x + 3*y + 2*z) * (7*x + 8*y + z) * (x + 6*y + 10*z) * (2*x + 4*y + 5*z) * z * (3*x + y + 2*z)

To use the columns instead, proceed in the following way:

julia> A = matrix(QQ,[1 0 2 1//2 3 7;2 0 3 3 1 8;5//2 1 2 5 2 1]);
-
-julia> factor(arrangement_polynomial(A; hyperplanes=:in_cols))
-(1//4) * (2*x1 + 3*x2 + 2*x3) * (7*x1 + 8*x2 + x3) * (x1 + 6*x2 + 10*x3) * (2*x1 + 4*x2 + 5*x3) * x3 * (3*x1 + x2 + 2*x3)
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(incidence_matrix([[1, 2], [3]]), [1 0; 0 1; -1 -1]);
-
-julia> dim(PF)
-2
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)
-Polytope 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
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(incidence_matrix([[1, 2], [3]]), [1 0; 0 1; -1 -1]);
-
-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_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(incidence_matrix([[1, 2], [2, 3]]), [0 1; 2 1; 1 0]);
-
-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_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(incidence_matrix([[1, 2, 3], [3, 4, 1]]), [1 0; 0 1; -1 0; 0 -1])
-Polyhedral fan in ambient dimension 2
-
-julia> lineality_space(PF)
-1-element SubObjectIterator{RayVector{QQFieldElem}}:
- [1, 0]
source
maximal_conesMethod
maximal_cones(PF::PolyhedralFan)

Return the maximal cones of PF.

Optionally IncidenceMatrix can be passed as a first argument to return the incidence matrix specifying the maximal cones of PF. In that case, the indices refer to the output of rays_modulo_lineality(Cone).

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(n_rays(c))
-       end
-4
-4
-4
-4
-4
-4
-
-julia> maximal_cones(IncidenceMatrix, PF)
-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]
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(incidence_matrix([[1, 2], [3]]), [1 0; 0 1; -1 -1]);
-
-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(incidence_matrix([[1, 2], [3]]), [1 0; 0 1; -1 -1])
-Polyhedral fan in ambient dimension 2
-
-julia> n_cones(PF)
-4
source
n_raysMethod
n_rays(PF::PolyhedralFan)

Return the number of rays of PF.

Examples

The 3-cube has 8 vertices. Accordingly, its face fan has 8 rays.

julia> n_rays(face_fan(cube(3)))
-8
source
raysMethod
rays([as::Type{T} = RayVector,] PF::PolyhedralFan)

Return the rays of PF. The rays are defined to be the one-dimensional faces of its cones, so if PF has lineality, there are no rays.

See also rays_modulo_lineality.

Optional arguments for as include

  • RayVector.

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]

The following fan has no rays:

julia> IM = incidence_matrix([[1,2],[2,3]]);
-
-julia> R = [1 0 0; 0 1 0; -1 0 0];
-
-julia> L = [0 0 1];
-
-julia> PF = polyhedral_fan(IM, R, L)
-Polyhedral fan in ambient dimension 3
-
-julia> rays(PF)
-0-element SubObjectIterator{RayVector{QQFieldElem}}
source
rays(TropV::TropicalVariety)

See rays(::PolyhedralComplex).

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.

See also rays and lineality_space.

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
rays_modulo_lineality(TropV::TropicalVariety)

See rays_modulo_lineality(::PolyhedralComplex).

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 [CLS11].

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 [CLS11].

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/PR4245/PolyhedralGeometry/intro/index.html b/previews/PR4245/PolyhedralGeometry/intro/index.html deleted file mode 100644 index e9a3bf20471a..000000000000 --- a/previews/PR4245/PolyhedralGeometry/intro/index.html +++ /dev/null @@ -1,92 +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)
-Polytope 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

There are two specialized Vector-like types, PointVector and RayVector, which commonly are returned by functions from Polyhedral Geometry. These can also be manually constructed:

point_vectorFunction
point_vector(p = QQ, v::AbstractVector)

Return a PointVector resembling a point whose coordinates equal the entries of v. p specifies the Field or Type of its coefficients.

source
ray_vectorFunction
ray_vector(p = QQ, v::AbstractVector)

Return a RayVector resembling a ray from the origin through the point whose coordinates equal the entries of v. p specifies the Field or Type of its coefficients.

source

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{<:PointVector}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

Similar to points and rays, there are types AffineHalfspace, LinearHalfspace, AffineHyperplane and LinearHyperplane:

affine_halfspaceFunction
affine_halfspace(p = QQ, a, b)

Return the Oscar.AffineHalfspace H(a,b), which is given by a vector a and a value b such that $H(a,b) = \{ x | ax ≤ b \}.$ p specifies the Field or Type of its coefficients.

source
linear_halfspaceFunction
linear_halfspace(p = QQ, a, b)

Return the Oscar.LinearHalfspace H(a), which is given by a vector a such that $H(a,b) = \{ x | ax ≤ 0 \}.$ p specifies the Field or Type of its coefficients.

source
affine_hyperplaneFunction
affine_hyperplane(p = QQ, a, b)

Return the Oscar.AffineHyperplane H(a,b), which is given by a vector a and a value b such that $H(a,b) = \{ x | ax = b \}.$ p specifies the Field or Type of its coefficients.

source
linear_hyperplaneFunction
linear_hyperplane(p = QQ, a, b)

Return the Oscar.LinearHyperplane H(a), which is given by a vector a such that $H(a,b) = \{ x | ax = 0 \}.$ p specifies the Field or Type of its coefficients.

source

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 of this example and the print of an IncidenceMatrix list the non-zero indices for each row.

julia> IM = incidence_matrix([[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

The unique nature of the IncidenceMatrix allows for different ways of construction:

incidence_matrixFunction
incidence_matrix(r::Base.Integer, c::Base.Integer)

Return an IncidenceMatrix of size r x c whose entries are all false.

Examples

julia> IM = incidence_matrix(8, 5)
-8×5 IncidenceMatrix
-[]
-[]
-[]
-[]
-[]
-[]
-[]
-[]
-
source
incidence_matrix(mat::Union{AbstractMatrix{Bool}, IncidenceMatrix})

Convert mat to an IncidenceMatrix.

Examples

julia> IM = incidence_matrix([true false true false true false; false true false true false true])
-2×6 IncidenceMatrix
-[1, 3, 5]
-[2, 4, 6]
-
source
incidence_matrix(mat::AbstractMatrix)

Convert the 0/1 matrix mat to an IncidenceMatrix. Entries become true if the initial entry is 1 and false if the initial entry is 0.

Examples

julia> IM = incidence_matrix([1 0 1 0 1 0; 0 1 0 1 0 1])
-2×6 IncidenceMatrix
-[1, 3, 5]
-[2, 4, 6]
-
source
incidence_matrix(r::Base.Integer, c::Base.Integer, incidenceRows::AbstractVector{<:AbstractVector{<:Base.Integer}})

Return an IncidenceMatrix of size r x c. The i-th element of incidenceRows lists the indices of the true entries of the i-th row.

Examples

julia> IM = incidence_matrix(3, 4, [[2, 3], [1]])
-3×4 IncidenceMatrix
-[2, 3]
-[1]
-[]
-
source
incidence_matrix(incidenceRows::AbstractVector{<:AbstractVector{<:Base.Integer}})

Return an IncidenceMatrix where the i-th element of incidenceRows lists the indices of the true entries of the i-th row. The dimensions of the result are the smallest possible row and column count that can be deduced from the input.

Examples

julia> IM = incidence_matrix([[2, 3], [1]])
-2×3 IncidenceMatrix
-[2, 3]
-[1]
-
source
incidence_matrix(g::Graph{T}) where {T <: Union{Directed, Undirected}}

Return an unsigned (boolean) incidence matrix representing a graph g.

Examples

julia> g = Graph{Directed}(5);
-
-julia> add_edge!(g, 1, 3);
-
-julia> add_edge!(g, 3, 4);
-
-julia> incidence_matrix(g)
-5×2 IncidenceMatrix
-[1]
-[]
-[1, 2]
-[2]
-[]
source

From the examples 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 = incidence_matrix([[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 = incidence_matrix([[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}, SubdivisionOfPoints{T}}; kwargs...) where T<:Union{FieldElem, 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 [Zie95].

In higher dimensions there is no standard method; use projections to lower dimensions or try ideas from [GJRW10].

Extended help

Keyword Arguments

Colors

Colors can be given as

  • a literal String, e.g. "green".
  • a String of the format "r g b" where $r, g, b \in {0, \dots, 255}$ are integers corresponding to the R/G/B values of the color.
  • a String of the format "r g b" where $r, g, b \in [0, 1]$ are decimal values corresponding to the R/G/B values of the color.

Possible arguments are:

  • FacetColor: Filling color of the polygons.
  • EdgeColor: Color of the boundary lines.
  • PointColor/VertexColor: Color of the spheres or rectangles representing the points.

Scaling and other gradient properties

These arguments can be given as a floating point number:

  • FacetTransparency: Transparency factor of the polygons between 0 (opaque) and 1 (completely translucent).
  • EdgeThickness: Scaling factor for the thickness of the boundary lines.
  • PointThickness/VertexThickness`: Scaling factor for the size of the spheres or rectangles representing the points.

Camera

These arguments can be given as a 3-element vector over floating point numbers:

  • ViewPoint: Position of the camera.
  • ViewDirection: Direction of the camera.

Appearance and Texts

These arguments can be given as a string:

  • FacetStyle: If set to "hidden", the inner area of the polygons are not rendered at all.
  • FacetLabels: If set to "hidden", the facet labels are not displayed (in the most cases this is the default behavior). TODO
  • EdgeStyle: If set to "hidden", the boundary lines are not rendered.
  • Name: The name of this visual object in the drawing.
  • PointLabels/VertexLabels: If set to "hidden", no point labels are displayed.
  • PointStyle/VertexStyle: If set to "hidden", neither point nor its label is rendered.
  • LabelAlignment: Defines the alignment of the vertex labels: "left", "right" or "center".
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 [GHJ16]. 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/PR4245/PolyhedralGeometry/linear_programs/index.html b/previews/PR4245/PolyhedralGeometry/linear_programs/index.html deleted file mode 100644 index 8d52ea5ea9e6..000000000000 --- a/previews/PR4245/PolyhedralGeometry/linear_programs/index.html +++ /dev/null @@ -1,123 +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)
-Polytope in ambient dimension 3
-
-julia> LP = linear_program(P,[3,-2,4];k=2,convention = :min)
-Linear program
-   min{c*x + k | x in P}
-where P is a Polyhedron{QQFieldElem} and
-   c=QQFieldElem[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

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
ambient_dimMethod
ambient_dim(LP::LinearProgram)

Return the ambient dimension of the feasible reagion of LP.

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 or the feasible region is empty, m may be infinity, -infinity, or nothing 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 -infinity or infinity depending on convention, or nothing if the feasible region is empty.

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)
-Polytope in ambient dimension 3
-
-julia> LP=linear_program(C,[1,2,-3]; convention = :min)
-Linear program
-   min{c*x + k | x in P}
-where P is a Polyhedron{QQFieldElem} and
-   c=QQFieldElem[1, 2, -3]
-   k=0
-
-julia> optimal_value(LP)
--6

Optimizing in an unbounded direction yields infinity.

julia> lp = linear_program(convex_hull([0 0], [1 0; 0 1]), [1, 1])
-Linear program
-   max{c*x + k | x in P}
-where P is a Polyhedron{QQFieldElem} and
-   c=QQFieldElem[1, 1]
-   k=0
-
-julia> optimal_value(lp)
-infinity
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)
-Polytope in ambient dimension 3
-
-julia> LP=linear_program(C,[1,2,-3])
-Linear program
-   max{c*x + k | x in P}
-where P is a Polyhedron{QQFieldElem} and
-   c=QQFieldElem[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)
-Polytope 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)
-Polytope 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/PR4245/PolyhedralGeometry/mixed_integer_linear_programs/index.html b/previews/PR4245/PolyhedralGeometry/mixed_integer_linear_programs/index.html deleted file mode 100644 index 803151aff989..000000000000 --- a/previews/PR4245/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

feasible_regionMethod
feasible_region(milp::MixedIntegerLinearProgram)

Return the feasible region of the mixed integer linear program milp, which is a Polyhedron.

source
ambient_dimMethod
ambient_dim(MILP::MixedIntegerLinearProgram)

Return the ambient dimension of the feasible reagion of MILP.

source
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)
-Polytope 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)
-Polytope 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)
-Polytope 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/PR4245/PolyhedralGeometry/polyhedral_complexes/index.html b/previews/PR4245/PolyhedralGeometry/polyhedral_complexes/index.html deleted file mode 100644 index ac2e94b835ed..000000000000 --- a/previews/PR4245/PolyhedralGeometry/polyhedral_complexes/index.html +++ /dev/null @@ -1,326 +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 = incidence_matrix([[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 = incidence_matrix([[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
polyhedral_complex(polytopes::AbstractVector{Polyhedron{T}}) where T<:scalar_types

Assemble a polyhedral complex from a non-empty list of polyhedra.

source
polyhedral_complex(F::PolyhedralFan)

Turn a polyhedral fan into a polyhedral complex.

source
polyhedral_complex(TropV::TropicalVariety)

Return the polyhedral complex of a tropical variety.

source

Auxiliary functions

ambient_dimMethod
ambient_dim(PC::PolyhedralComplex)

Return the ambient dimension of PC.

Examples

julia> IM = incidence_matrix([[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 = incidence_matrix([[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 = incidence_matrix([[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 = incidence_matrix([[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 = incidence_matrix([[1,2],[1,3],[1,4]]);
-
-julia> PC = polyhedral_complex(IM, VR)
-Polyhedral complex in ambient dimension 2
-
-julia> is_embedded(PC)
-true
source
is_pureMethod
is_pure(PC::PolyhedralComplex)

Determine whether the polyhedral complex is pure.

Examples

julia> IM = incidence_matrix([[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> is_pure(PC)
-true
source
is_simplicialMethod
is_simplicial(PC::PolyhedralComplex)

Determine whether the polyhedral complex is simplicial.

Examples

julia> IM = incidence_matrix([[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> is_simplicial(PC)
-true
source
lineality_dimMethod
lineality_dim(PC::PolyhedralComplex)

Return the lineality dimension of PC.

Examples

julia> VR = [0 0 0; 1 0 0; 0 1 0; -1 0 0];
-
-julia> IM = incidence_matrix([[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
lineality_spaceMethod
lineality_space(PC::PolyhedralComplex)

Return the lineality space of PC.

Examples

julia> VR = [0 0 0; 1 0 0; 0 1 0; -1 0 0];
-
-julia> IM = incidence_matrix([[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_space(PC)
-1-element SubObjectIterator{RayVector{QQFieldElem}}:
- [0, 0, 1]
source
maximal_polyhedraMethod
maximal_polyhedra(PC::PolyhedralComplex)

Return the maximal polyhedra of PC

Optionally IncidenceMatrix can be passed as a first argument to return the incidence matrix specifying the maximal polyhedra of PC. The indices returned refer to the output of vertices_and_rays.

Examples

julia> IM = incidence_matrix([[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
- Polytope in ambient dimension 2
-
-julia> maximal_polyhedra(IncidenceMatrix, PC)
-2×4 IncidenceMatrix
-[1, 2, 3]
-[1, 3, 4]
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.

See also vertices and lineality_space.

Examples

julia> VR = [0 0 0; 1 0 0; 0 1 0; -1 0 0];
-
-julia> IM = incidence_matrix([[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 = incidence_matrix([[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
n_polyhedraMethod
n_polyhedra(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 = incidence_matrix([[1,2,4],[1,3,4]]);
-
-julia> far_vertices = [2,3,4];
-
-julia> PC = polyhedral_complex(IM, VR, far_vertices);
-
-julia> n_polyhedra(PC)
-6
source
n_raysMethod
n_rays(PC::PolyhedralComplex)

Return the number of rays of PC.

Examples

julia> VR = [0 0; 1 0; -1 0; 0 1];
-
-julia> IM = incidence_matrix([[1,2,4],[1,3,4]]);
-
-julia> far_vertices = [2,3,4];
-
-julia> PC = polyhedral_complex(IM, VR, far_vertices);
-
-julia> n_rays(PC)
-3
source
n_verticesMethod
n_vertices(PC::PolyhedralComplex)

Return the number of vertices of PC.

Examples

julia> VR = [0 0; 1 0; -1 0; 0 1];
-
-julia> IM = incidence_matrix([[1,2,4],[1,3,4]]);
-
-julia> far_vertices = [2,3,4];
-
-julia> PC = polyhedral_complex(IM, VR, far_vertices);
-
-julia> n_vertices(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 = incidence_matrix([[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}}:
- Polytope in ambient dimension 2
- Polytope in ambient dimension 2
- Polytope in ambient dimension 2
- Polytope in ambient dimension 2
- Polytope in ambient dimension 2
-
-julia> for p in P1s
-       println(dim(p))
-       end
-1
-1
-1
-1
-1
source
raysMethod
rays([as::Type{T} = RayVector,] PC::PolyhedralComplex)

Return the rays of PC. The rays are defined to be the far vertices, i.e. the one-dimensional faces of the recession cones of its polyhedra, so if PC has lineality, there are no rays.

See also rays_modulo_lineality and vertices.

Optional arguments for as include

  • RayVector.

Examples

julia> IM = incidence_matrix([[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(RayVector, PC))
-[1   0]

The following complex has no vertices:

julia> IM = incidence_matrix([[1,2,3],[1,3,4]]);
-
-julia> VR = [0 0 0; 1 0 0; 0 1 0; -1 0 0];
-
-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> rays(PC)
-0-element SubObjectIterator{RayVector{QQFieldElem}}
source
rays_modulo_linealityMethod
rays_modulo_lineality(as, PC::PolyhedralComplex)

Return the rays of the recession fan 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.

See also rays and lineality_space.

Examples

julia> VR = [0 0 0; 1 0 0; 0 1 0; -1 0 0];
-
-julia> IM = incidence_matrix([[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([as::Type{T} = PointVector,] PC::PolyhedralComplex)

Return an iterator over the vertices of PC in the format defined by as. The vertices are defined to be the zero-dimensional faces, so if P has lineality, there are no vertices, only minimal faces.

See also minimal_faces and rays.

Optional arguments for as include

  • PointVector.

Examples

julia> IM = incidence_matrix([[1,2,3],[1,3,4]]);
-
-julia> V = [0 0; 1 0; 1 1; 0 1];
-
-julia> PC = polyhedral_complex(IM, V)
-Polyhedral complex in ambient dimension 2
-
-julia> vertices(PC)
-4-element SubObjectIterator{PointVector{QQFieldElem}}:
- [0, 0]
- [1, 0]
- [1, 1]
- [0, 1]
-
-julia> matrix(QQ, vertices(PointVector, PC))
-[0   0]
-[1   0]
-[1   1]
-[0   1]

The following complex has no vertices:

julia> IM = incidence_matrix([[1,2,3],[1,3,4]]);
-
-julia> VR = [0 0 0; 1 0 0; 0 1 0; -1 0 0];
-
-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> vertices(PC)
-0-element SubObjectIterator{PointVector{QQFieldElem}}
source
vertices_and_raysMethod
vertices_and_rays(PC::PolyhedralComplex)

Return the vertices and rays of PC as a combined set, up to lineality. This function is mainly a helper function for maximal_polyhedra.

Examples

julia> IM = incidence_matrix([[1,2,3],[1,3,4]]);
-
-julia> VR = [0 0 0; 1 0 0; 0 1 0; -1 0 0];
-
-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> for vr in vertices_and_rays(PC)
-       println("$vr : $(typeof(vr))")
-       end
-QQFieldElem[0, 0, 0] : PointVector{QQFieldElem}
-QQFieldElem[1, 0, 0] : RayVector{QQFieldElem}
-QQFieldElem[0, 1, 0] : RayVector{QQFieldElem}
-QQFieldElem[-1, 0, 0] : RayVector{QQFieldElem}
source
diff --git a/previews/PR4245/PolyhedralGeometry/subdivisions_of_points/index.html b/previews/PR4245/PolyhedralGeometry/subdivisions_of_points/index.html deleted file mode 100644 index be6d7df744a4..000000000000 --- a/previews/PR4245/PolyhedralGeometry/subdivisions_of_points/index.html +++ /dev/null @@ -1,124 +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.

Warning

It is required, but not checked, that the cells cover the convex hull of the points. Likewise it is not checked that the cells form a proper polyhedral complex.

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 = incidence_matrix([[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 = incidence_matrix([[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.

Optionally IncidenceMatrix can be passed as a first argument to return the incidence matrix specifying 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 = incidence_matrix([[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]
-
-julia> maximal_cells(IncidenceMatrix, MOAE)
-7×6 IncidenceMatrix
-[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 = incidence_matrix([[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 = incidence_matrix([[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/PR4245/Rings/integer/index.html b/previews/PR4245/Rings/integer/index.html deleted file mode 100644 index 0ffa8e219984..000000000000 --- a/previews/PR4245/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 behavior 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 behavior.

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) -> ZZRingElem
  • 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 behavior.

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/PR4245/Rings/intro/index.html b/previews/PR4245/Rings/intro/index.html deleted file mode 100644 index a6759dc4c4f7..000000000000 --- a/previews/PR4245/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/PR4245/Rings/rational/index.html b/previews/PR4245/Rings/rational/index.html deleted file mode 100644 index 07926056d538..000000000000 --- a/previews/PR4245/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_perfect_power_with_data(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_perfect_power_with_data(QQ(9//16))
-(2, 3//4)
-
-julia> root(QQ(25//9), 2)
-5//3
-
diff --git a/previews/PR4245/StraightLinePrograms/abstractalgebra/index.html b/previews/PR4245/StraightLinePrograms/abstractalgebra/index.html deleted file mode 100644 index df241361e290..000000000000 --- a/previews/PR4245/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/PR4245/StraightLinePrograms/gapslps/index.html b/previews/PR4245/StraightLinePrograms/gapslps/index.html deleted file mode 100644 index 1adefc64c31e..000000000000 --- a/previews/PR4245/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/PR4245/StraightLinePrograms/intro/index.html b/previews/PR4245/StraightLinePrograms/intro/index.html deleted file mode 100644 index 254c9d2bd6ca..000000000000 --- a/previews/PR4245/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/PR4245/TropicalGeometry/curve/index.html b/previews/PR4245/TropicalGeometry/curve/index.html deleted file mode 100644 index d102d3aa0a82..000000000000 --- a/previews/PR4245/TropicalGeometry/curve/index.html +++ /dev/null @@ -1,34 +0,0 @@ - -Tropical curves · Oscar.jl

Tropical curves

Introduction

A tropical curve is a graph with multiplicities on its edges. If embedded, it is a polyhedral complex of dimension (at most) one.

Note:

  • The type TropicalCurve can be thought of as subtype of TropicalVariety in the sense that it should have all properties and features of the latter.

Construction

In addition to converting from TropicalVariety, objects of type TropicalCurve can be constructed from:

Properties

In addition to the properties inherited from TropicalVariety, objects of type TropicalCurve have the following exclusive properties:

graphMethod
graph(f::AbsAffineSchemeMor)

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 x1, x2, x3
-      over rational field
-    by ideal (x1)
-
-julia> f = inclusion_morphism(X, Y)
-Affine scheme morphism
-  from [x1, x2, x3]  scheme(x1)
-  to   [x1, x2, x3]  affine 3-space over QQ
-given by the pullback function
-  x1 -> x1
-  x2 -> x2
-  x3 -> x3
-
-julia> graph(f)
-(scheme(x1, -x1, x2 - x2, x3 - x3), Hom: scheme(x1, -x1, x2 - x2, x3 - x3) -> scheme(x1), Hom: scheme(x1, -x1, x2 - x2, x3 - x3) -> affine 3-space over QQ with coordinates [x1, x2, x3])
source
graph(TropC::TropicalCurve{minOrMax,false})

Return the graph of an abstract tropical curve TropC. Same as polyhedral_complex(tc).

source
diff --git a/previews/PR4245/TropicalGeometry/groebner_theory/index.html b/previews/PR4245/TropicalGeometry/groebner_theory/index.html deleted file mode 100644 index 18ff95377adb..000000000000 --- a/previews/PR4245/TropicalGeometry/groebner_theory/index.html +++ /dev/null @@ -1,59 +0,0 @@ - -Groebner theory · Oscar.jl

Groebner theory

Introduction

Tropical algebraic geometry incorporates the valuation of the underlying ground field, and therefore so does its Groebner theory. Tropical Groebner theory is a generalization of its classical counterpart to fields with valuation, and the classical Groebner theory is a specialization of tropical Groebner theory to fields with trivial valuation. Instead of monomial orderings there are term orderings which take the valuation into account, and initial forms and ideals live over the residue field. For details, see Chapter 2.4 in [MS15].

Groebner bases

Groebner bases in [MS15] are only defined for homogeneous ideals and they are finite sets whose initial forms generate the initial ideal. Groebner bases in OSCAR are defined for all ideals and they are finite generating sets whose initial forms generate the initial ideal. For homogeneous ideals generating the initial ideal implies generating the original ideal, so both notions coincide. For principal and binomial ideals the algorithm simply returns its input.

groebner_basisMethod
groebner_basis(I::MPolyIdeal, nu::TropicalSemiringMap, w::AbstractVector{<:Union{QQFieldElem,ZZRingElem,Rational,Integer}})

Return a (tropical) Groebner basis of I with respect to the tropical semiring map nu and weight vector w.

Examples

julia> R,(x,y) = QQ[:x, :y];
-
-julia> I = ideal([x^3-5*x^2*y,3*y^3-2*x^2*y]);
-
-julia> nu = tropical_semiring_map(QQ,2);
-
-julia> w = [0,0];
-
-julia> groebner_basis(I,nu,w)
-2-element Vector{QQMPolyRingElem}:
- x^3 - 5*x^2*y
- -2*x^2*y + 3*y^3
-
source

Initial forms and initial ideals

initialMethod
initial(f::MPolyRingElem, nu::TropicalSemiringMap, w::Vector)

Return the initial form of f with respect to the tropical semiring map nu and weight vector w.

Examples (trivial and $p$-adic valuation)

julia> R,(x,y) = QQ[:x, :y];
-
-julia> nu_0 = tropical_semiring_map(QQ,max);
-
-julia> nu_2 = tropical_semiring_map(QQ,2);
-
-julia> w = [0,0];
-
-julia> f = x+y+2;
-
-julia> initial(f,nu_2,w) # polynomial over GF(2)
-x + y
-
-julia> initial(f,nu_0,w) # polynomial over QQ
-x + y + 2
-

Examples ($t$-adic valuation)

julia> K,t = rational_function_field(GF(2),"t");
-
-julia> nu_t = tropical_semiring_map(K,t,max);
-
-julia> R,(x,y) = K[:x, :y];
-
-julia> w = [1,1];
-
-julia> f = t*x+t*y+1;
-
-julia> initial(f,nu_t,w) # polynomial over GF(2)
-x + y + 1
-
source
initialMethod
initial(I::MPolyIdeal, nu::TropicalSemiringMap, w::Vector; skip_groebner_basis_computation::Bool=false)

Return the initial ideal of I with respect to the tropical semiring map nu and weight vector w. If skip_groebner_basis_computation=true, skips the necessary Groebner basis computation and returns the ideal generated by the initial forms of gens(I).

Examples

julia> R,(x,y) = QQ[:x, :y];
-
-julia> I = ideal([x^3-5*x^2*y,3*y^3-2*x^2*y]);
-
-julia> nu_2 = tropical_semiring_map(QQ,2);
-
-julia> nu_0 = tropical_semiring_map(QQ);
-
-julia> w = [0,0];
-
-julia> initial(I,nu_2,w)
-Ideal generated by
-  x^3 + x^2*y
-  y^3
-
-julia> initial(I,nu_0,w)
-Ideal generated by
-  x^3 - 5*x^2*y
-  -2*x^2*y + 3*y^3
source
diff --git a/previews/PR4245/TropicalGeometry/hypersurface/index.html b/previews/PR4245/TropicalGeometry/hypersurface/index.html deleted file mode 100644 index 5f9ad781ce17..000000000000 --- a/previews/PR4245/TropicalGeometry/hypersurface/index.html +++ /dev/null @@ -1,89 +0,0 @@ - -Tropical hypersurfaces · Oscar.jl

Tropical hypersurfaces

Introduction

A tropical hypersurface is a balanced polyhedral complex of codimension one. It is dual to a regular subdivision of a Newton polytope. For more on tropical hypersurfaces, see

Note:

  • Objects of type TropicalHypersurface need to be embedded, abstract tropical hypersurfaces are currently not supported.
  • The type TropicalHypersurface can be thought of as subtype of TropicalVariety in the sense that it should have all properties and features of the latter.

Constructors

In addition to converting from TropicalVariety, objects of type TropicalHypersurface can be constructed from:

  • polynomials over a tropical semiring,
  • polynomials over a field and a tropical semiring map,
  • subdivision of points and a choice of min- or max-convention.
tropical_hypersurfaceFunction
tropical_hypersurface(f::MPolyRingElem{<:TropicalSemiringElem}, weighted_polyhedral_complex_only::Bool=false)

Return the tropical hypersurface of the tropical polynomial f. If weighted_polyhedral_complex==true, will not cache any extra information.

Examples

julia> T = tropical_semiring()
-Min tropical semiring
-
-julia> R,(x,y) = T[:x, :y];
-
-julia> f = x+y+1
-x + y + (1)
-
-julia> tropical_hypersurface(f)
-Min tropical hypersurface
-
source
tropical_hypersurface(f::MPolyRingElem, val::TropicalSemiringMap; weighted_polyhedral_complex_only::Bool=false)

Return the tropical hypersurface of the tropical polynomial that is the image of f under coefficient-wise val. If weighted_polyhedral_complex==true, will not cache any extra information.

Examples

julia> R,(x,y) = QQ[:x, :y];
-
-julia> val = tropical_semiring_map(QQ,2)
-Map into Min tropical semiring encoding the 2-adic valuation on Rational field
-
-julia> f = x+y+2
-x + y + 2
-
-julia> tropical_hypersurface(f,val)
-Min tropical hypersurface
-
source
tropical_hypersurface(Delta::SubdivisionOfPoints, minOrMax::Union{typeof(min),typeof(max)}=min; weighted_polyhedral_complex_only::Bool=false)

Construct the tropical hypersurface dual to a regular subdivision Delta in convention minOrMax. To be precise, the tropical hypersurface of the tropical polynomial with exponent vectors points(Delta) and coefficients min_weight(Delta) (min-convention) or -min_weight(Delta) (max-convention). If weighted_polyhedral_complex==true, will not cache any extra information.

Examples

julia> Delta = subdivision_of_points([0 0; 1 0; 0 1; 2 0],[0,0,0,1])
-Subdivision of points in ambient dimension 2
-
-julia> tropical_hypersurface(Delta)
-Min tropical hypersurface
source

Properties

In addition to the properties inherited from TropicalVariety, objects of type TropicalHypersurface have the following exclusive properties:

algebraic_polynomialMethod
algebraic_polynomial(TropH::TropicalHypersurface)

Return the polynomial over a valued field used to construct TropH. Raises an error if it is not cached.

source
tropical_polynomialMethod
tropical_polynomial(TropH::TropicalHypersurface)

Return the tropical polynomial used to construct TropH. Raises an error if it is not cached.

source
dual_subdivisionMethod
dual_subdivision(TropH::TropicalHypersurface)

Return the dual subdivision used to construct TropH. Raises an error if it is not cached.

Examples

julia> Delta = subdivision_of_points([0 0; 1 0; 0 1; 2 0],[0,0,0,1])
-Subdivision of points in ambient dimension 2
-
-julia> th = tropical_hypersurface(Delta)
-Min tropical hypersurface
-
-julia> sop = dual_subdivision(th)
-Subdivision of points in ambient dimension 2
-
-julia> points(sop)
-4-element SubObjectIterator{PointVector{QQFieldElem}}:
- [0, 0]
- [1, 0]
- [0, 1]
- [2, 0]
-
-julia> maximal_cells(sop)
-2-element SubObjectIterator{Vector{Int64}}:
- [1, 2, 3]
- [2, 3, 4]
source

Example

The following code sets up an example and prints the vertices and rays of the tropical hypersurface (in no particular order).

julia> T = tropical_semiring();
-
-julia> Tx,(x1,x2) = polynomial_ring(T, 2);
-
-julia> g = 1 + 2*x1^2 + 2*x2^2 + 1*x1*x2;
-
-julia> TropH = tropical_hypersurface(g);
-
-julia> vertRays = vertices_and_rays(TropH)
-5-element SubObjectIterator{Union{PointVector{QQFieldElem}, RayVector{QQFieldElem}}}:
- [-1, -1]
- [1, 0]
- [0, 1]
- [-1//2, 1//2]
- [1//2, -1//2]

By broadcasting the typeof() command, we can see, which are vertices, and which are rays.

julia> typeof.(vertRays)
-5-element Vector{DataType}:
- RayVector{QQFieldElem}
- RayVector{QQFieldElem}
- RayVector{QQFieldElem}
- PointVector{QQFieldElem}
- PointVector{QQFieldElem}

The maximal polyhedra of our tropical hypersurface is simply the edges (both bounded and unbounded). The command maximal_polyhedra() gives us a list of these edges (in no particular order).

julia> maxPol = maximal_polyhedra(TropH)
-5-element SubObjectIterator{Polyhedron{QQFieldElem}}:
- Polyhedron in ambient dimension 2
- Polyhedron in ambient dimension 2
- Polyhedron in ambient dimension 2
- Polytope in ambient dimension 2
- Polyhedron in ambient dimension 2

The polyhedrons are the unbounded edges, and the polytopes are the bounded edges.

The incidence matrix of the maximal polyhedra is a list of the relations between the elements of vertices_and_rays(TropH). From these relations, we can draw the hypersurface. However, one should be careful, as there is no distinction between vertices and rays in the incidence matrix.

julia> IncidenceMatrix(maxPol)
-5×5 IncidenceMatrix
-[1, 4]
-[1, 5]
-[3, 4]
-[4, 5]
-[2, 5]

This is made clearer if we ask for the vertices of each of the maximal polyhedra (the bounded edges have a vertex at each end, while the unbounded only have one vertex).

julia> vertices.(maxPol)
-5-element Vector{SubObjectIterator{PointVector{QQFieldElem}}}:
- [[-1//2, 1//2]]
- [[1//2, -1//2]]
- [[-1//2, 1//2]]
- [[-1//2, 1//2], [1//2, -1//2]]
- [[1//2, -1//2]]

Instead of being between two vertices, the unbounded edges are defined by a vertex and a ray. These rays can be seen in the following way.

julia> rays.(maxPol)
-5-element Vector{SubObjectIterator{RayVector{QQFieldElem}}}:
- [[-1, -1]]
- [[-1, -1]]
- [[0, 1]]
- 0-element SubObjectIterator{RayVector{QQFieldElem}}
- [[1, 0]]
diff --git a/previews/PR4245/TropicalGeometry/intro/index.html b/previews/PR4245/TropicalGeometry/intro/index.html deleted file mode 100644 index 2410d607aeea..000000000000 --- a/previews/PR4245/TropicalGeometry/intro/index.html +++ /dev/null @@ -1,2 +0,0 @@ - -Introduction · Oscar.jl

Introduction

The tropical geometry part of OSCAR provides functionality for

  • tropical min-plus and max-plus semirings,
  • matrices and polynomials thereover,
  • tropical varieties, hypersurfaces, curves, and linear spaces.

General textbooks offering details on theory and algorithms include:

  • Maclagan, Sturmfels: Introduction to Tropical Geometry [MS15]
  • Joswig: Essentials of Tropical Combinatorics [Jos21]

Like [MS15], OSCAR follows the min-convention by default and unless specified otherwise.

Contact

Please direct questions about this part of OSCAR to:

You can also ask questions in the OSCAR Slack or raise an issue on github.

diff --git a/previews/PR4245/TropicalGeometry/linear_space/index.html b/previews/PR4245/TropicalGeometry/linear_space/index.html deleted file mode 100644 index 863f3f7f26af..000000000000 --- a/previews/PR4245/TropicalGeometry/linear_space/index.html +++ /dev/null @@ -1,58 +0,0 @@ - -Tropical linear spaces · Oscar.jl

Tropical linear spaces

Introduction

A tropical linear space is a balanced polyhedral complex supported on a finite intersection of linear tropical hypersurfaces with all multiplicities one. It is dual to a matroid subdivision of a hypersimplex, and may arise as tropicalizations of linear ideals. For more on tropical linear spaces, see

Note:

  • Objects of type TropicalLinearSpace need to be embedded, abstract tropical linear spaces are currently not supported.
  • The type TropicalLinearSpace can be thought of as subtype of TropicalVariety in the sense that it should have all properties and features of the latter.

Constructors

In addition to converting from TropicalVariety, objects of type TropicalLinearSpace can be constructed from:

  1. Pluecker vectors over a tropical semiring: uses a low-level implementation in polymake
  2. Pluecker vectors over a field and a tropical semiring map: computes coordinatewise valuation and uses constructor (1.)
  3. matrices over a tropical semiring: computes tropical minors and uses constructor (1.)
  4. matrices over a field and a tropical semiring map.
    • if matrix over QQ and tropical semiring map is trivial, uses an implementation of Rincon's algorithm [Rin13] in polymake
    • for general input, computes minors and uses constructor (2.)
tropical_linear_spaceFunction
tropical_linear_space(Lambda::Vector{Vector{Int}}, p::Vector{<:TropicalSemiringElem}; weighted_polyhedral_complex_only::Bool=false)

Return a tropical linear space from a tropical Pluecker vector with indices Lambda and values p. If weighted_polyhedral_complex==true, will not cache any extra information.

Examples

julia> T = tropical_semiring();
-
-julia> plueckerIndices = [[1,2],[1,3],[1,4],[2,3],[2,4],[3,4]];
-
-julia> plueckerVector = T.([0,0,0,0,0,0]);
-
-julia> tropical_linear_space(plueckerIndices,plueckerVector)
-Min tropical linear space
-
source
tropical_linear_space(k::Int, n::Int, p::Vector{<:TropicalSemiringElem}; weighted_polyhedral_complex_only::Bool=false)

Return a tropical linear space from a tropical Pluecker vector with indices AbstractAlgebra.combinations(1:n,k) and values p. If weighted_polyhedral_complex==true, will not cache any extra information.

Examples

julia> T = tropical_semiring();
-
-julia> plueckerVector = T.([0,0,0,0,0,0]);
-
-julia> tropical_linear_space(2,4,plueckerVector)
-Min tropical linear space
-
source
tropical_linear_space(Lambda::Vector{Vector{Int}}, p::Vector, nu::TropicalSemiringMap; weighted_polyhedral_complex_only::Bool=false)

Return a tropical linear space from a tropical Pluecker vector with indices Lambda and values nu(p). If weighted_polyhedral_complex==true, will not cache any extra information.

Examples

julia> nu = tropical_semiring_map(QQ,2)
-Map into Min tropical semiring encoding the 2-adic valuation on Rational field
-
-julia> plueckerIndices = [[1,2],[1,3],[1,4],[2,3],[2,4],[3,4]];
-
-julia> plueckerVector = QQ.([1,3,5,5,3,1]);
-
-julia> tropical_linear_space(plueckerIndices,plueckerVector,nu)
-Min tropical linear space
-
source
tropical_linear_space(k::Int, n::Int, p::Vector, nu::TropicalSemiringMap; weighted_polyhedral_complex_only::Bool=false)

Return a tropical linear space from a tropical Pluecker vector with indices AbstractAlgebra.combinations(1:n,k) and values nu(p). If weighted_polyhedral_complex==true, will not cache any extra information.

Examples

julia> nu = tropical_semiring_map(QQ);
-
-julia> plueckerVector = QQ.([1,3,5,5,3,1]);
-
-julia> tropical_linear_space(2,4,plueckerVector,nu)
-Min tropical linear space
-
source
tropical_linear_space(A::MatElem{<:TropicalSemiringElem}; weighted_polyhedral_complex_only::Bool=false)

Return a tropical linear space whose Pluecker vector are the tropical minors of A. Assumes that ncols(A)>=nrows(A). If weighted_polyhedral_complex==true, will not cache any extra information.

Examples

julia> A = matrix(tropical_semiring(),[[1,2,4,8],[8,4,2,1]])
-[(1)   (2)   (4)   (8)]
-[(8)   (4)   (2)   (1)]
-
-julia> tropical_linear_space(A)
-Min tropical linear space
-
source
tropical_linear_space(A::MatElem,nu::TropicalSemiringMap; weighted_polyhedral_complex_only::Bool=false)

Return a tropical linear space whose Pluecker vector is nu applied to the minors of A. If weighted_polyhedral_complex==true, will not cache any extra information.

Examples

julia> nu = tropical_semiring_map(QQ,2)
-Map into Min tropical semiring encoding the 2-adic valuation on Rational field
-
-julia> A = matrix(QQ,[[1,2,4,8],[8,4,2,1]])
-[1   2   4   8]
-[8   4   2   1]
-
-julia> tropical_linear_space(A, nu)
-Min tropical linear space
-
source
tropical_linear_space(I::MPolyIdeal, nu::TropicalSemiringMap; weighted_polyhedral_complex_only::Bool=false)

Return the tropicalization of the vanishing set of I with respect to the tropical semiring map nu. Requires the generators of I to be linear and homogeneous. If weighted_polyhedral_complex==true, will not cache any extra information.

Examples

julia> R,(x1,x2,x3,x4) = polynomial_ring(QQ,4);
-
-julia> I = ideal(R,[-x1+x3,-x2+x4])
-Ideal generated by
-  -x1 + x3
-  -x2 + x4
-
-julia> nu = tropical_semiring_map(QQ)
-Map into Min tropical semiring encoding the trivial valuation on Rational field
-
-julia> tropical_linear_space(I, nu)
-Min tropical linear space
-
source

Properties

In addition to the properties inherited from TropicalVariety, objects of type TropicalLinearSpace have the following exclusive properties:

pluecker_indicesMethod
pluecker_indices(TropL::TropicalLinearSpace)

Return the Pluecker indices used to construct TropL.

source
algebraic_pluecker_vectorMethod
algebraic_pluecker_vector(TropL::TropicalLinearSpace)

Return the Pluecker vector over a valued field used to construct TropL.

source
tropical_semiring_mapMethod
tropical_semiring_map(TropL::TropicalLinearSpace)

Return the tropical semiring map used to construct TropL. Raises an error, if it is not cached.

source
tropical_matrixMethod
tropical_matrix(TropL::TropicalLinearSpace)

Return the tropical matrix used to construct TropL. Raises an error, if it is not cached.

source
algebraic_matrixMethod
algebraic_matrix(TropL::TropicalLinearSpace)

Return the matrix over a valued field used to construct TropL.

source
algebraic_idealMethod
algebraic_ideal(TropL::TropicalLinearSpace)

Return the polynomial ideal over a valued field used to construct TropL. Raises an error, if it is not cached.

source
diff --git a/previews/PR4245/TropicalGeometry/semiring/index.html b/previews/PR4245/TropicalGeometry/semiring/index.html deleted file mode 100644 index 1f8a60779df8..000000000000 --- a/previews/PR4245/TropicalGeometry/semiring/index.html +++ /dev/null @@ -1,79 +0,0 @@ - -Tropical semirings, matrices, and polynomials · Oscar.jl

Tropical semirings, matrices, and polynomials

Introduction

In OSCAR, the tropical semiring is either

  • the min-plus semiring $(\mathbb{Q}\cup\{+\infty\},\oplus,\odot)$ with $a\oplus b=\min(a,b)$ and $a\odot b=a+b$,
  • the max-plus semiring $(\mathbb{Q}\cup\{-\infty\},\oplus,\odot)$ with $a\oplus b=\max(a,b)$ and $a\odot b=a+b$.

Whereas tropical semirings in [MS15] and [Jos21] are extensions of the real numbers, tropical semirings in OSCAR are an extension of the rational numbers to avoid precision issues.

Constructor

Objects of type TropicalSemiring, as well as matrices and polynomials thereover, can be constructed as follows:

tropical_semiringMethod
tropical_semiring(M::Union{typeof(min),typeof(max)}=min)

Return the min-plus (default) or max-plus semiring.

Warning
  • +, *, /, and ^ are used for tropical addition, tropical multipliciation, tropical division, and tropical exponentiation, respectively.
  • There is no additive inverse or subtraction in the tropical semiring. Negating a tropical number or subtracting two tropical numbers will raise an error.
  • Zeroes of tropical semirings are printed as infty or -infty instead of their proper unicode characters. To enabled unicode in the current and future sessions, run allow_unicode(true).

Examples (basic arithmetic)

julia> T = tropical_semiring() # = tropical_semiring(min)
-Min tropical semiring
-
-julia> T = tropical_semiring(max)
-Max tropical semiring
-
-julia> 0*T(3) + 1*T(1)^2 + zero(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 = tropical_semiring()
-Min tropical semiring
-
-julia> Tx,(x1,x2) = polynomial_ring(T,2)
-(Multivariate polynomial ring in 2 variables over min tropical semiring, AbstractAlgebra.Generic.MPoly{TropicalSemiringElem{typeof(min)}}[x1, x2])
-
-julia> f = x1 + -1*x2 + 0
-x1 + (-1)*x2 + (0)
-
-julia> evaluate(f,T.([-1//2,1//2])) # warning: omitting T() gives an error
-(-1//2)

Examples (matrices)

julia> T = tropical_semiring()
-Min tropical semiring
-
-julia> A = identity_matrix(T, 2) # = tropical identity matrix
-[  (0)   infty]
-[infty     (0)]
-
-julia> 2*A
-[  (2)   infty]
-[infty     (2)]
-
-julia> A*A
-[  (0)   infty]
-[infty     (0)]
-
-julia> det(A)
-(0)
-
-julia> minors(A,1)
-4-element Vector{TropicalSemiringElem{typeof(min)}}:
- (0)
- infty
- infty
- (0)
source

Properties

Objects of type TropicalSemiring have the following properties:

conventionMethod
convention(T::TropicalSemiring)

Return min if T is the min tropical semiring, return max if T is the max tropical semiring. Works similarly for tropical numbers, tropical vectors and matrices, and tropical polynomials.

Examples

julia> T = tropical_semiring(min)
-Min tropical semiring
-
-julia> convention(T)
-min (generic function with 27 methods)
-
-julia> T = tropical_semiring(max)
-Max tropical semiring
-
-julia> convention(T)
-max (generic function with 27 methods)
source

Other functions related to TropicalSemiring, matrices, and polynomials thereover include:

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> A = R[x 1; 1 x^2];
-
-julia> d = det(A)
-x^3 - 1
source
det(A::MatrixElem{<: TropicalSemiringElem})

Return the tropical determinant of A. That is, this function evaluates the tropicalization of the ordinary determinant considered as a multivariate polynomial at A.

That computation is equivalent to solving a linear assignment problem from combinatorial optimization. The implementation employs the Hungarian method, which is polynomial time. See Chapter 3 in [Jos21].

Note

This function effectively overwrites the det command for tropical matrices. This means that functions like minors will use the tropical determinant when used on a tropical matrix.

Examples

julia> A = matrix(tropical_semiring(),[1 2; 3 4])
-[(1)   (2)]
-[(3)   (4)]
-
-julia> det(A)
-(5)
source
tropical_polynomialMethod
tropical_polynomial(f::Union{<:MPolyRingElem,<:PolyRingElem},nu::TropicalSemiringMap)

Given a polynomial f and a tropical semiring map nu, return 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> nu = tropical_semiring_map(QQ,7)
-Map into Min tropical semiring encoding the 7-adic valuation on Rational field
-
-julia> f = 7*x+y+49
-7*x + y + 49
-
-julia> tropical_polynomial(f,nu)
-(1)*x + y + (2)
source
diff --git a/previews/PR4245/TropicalGeometry/semiring_map/index.html b/previews/PR4245/TropicalGeometry/semiring_map/index.html deleted file mode 100644 index 8586689b36fc..000000000000 --- a/previews/PR4245/TropicalGeometry/semiring_map/index.html +++ /dev/null @@ -1,54 +0,0 @@ - -Tropical semiring maps · Oscar.jl

Tropical semiring maps

Introduction

In OSCAR, a TropicalSemiringMap is a map $\nu: K\to\mathbb{T}$ from a field $K$ to a tropical semiring $\mathbb{T}$ satisfing

  1. finiteness: $\nu(a)=\pm\infty$ if and only if $a=0$,
  2. multiplicativity: $\nu(a\cdot b)=\nu(a)+\nu(b)$,
  3. superadditivity: $\nu(a\cdot b)\geq\min(\nu(a),\nu(b))$ (in the order defined in Section 2.7 of [Jos21]).

Most commonly, $\nu(a)=-\mathrm{val}(a)$ if $\mathbb{T}$ is the min-plus semiring, and $\nu(a)=+\mathrm{val}(a)$ if $\mathbb{T}$ is the max-plus semiring, for some valuation $\mathrm{val}:K^\ast\rightarrow\mathbb{R}$. Essentially, $\nu$ captures a valuation on $K$ as well as a choice of min- or max-convention. They are an optional input for most tropical functions over valued fields (the default being the trivial valuation and the min-convention).

Constructor

Tropical semiring maps can be constructed as follows:

tropical_semiring_mapFunction
tropical_semiring_map(K::Field, minOrMax::Union{typeof(min),typeof(max)}=min)

Return a map nu from K to the min (default) or max tropical semiring T such that nu(0)=zero(T) and nu(c)=one(T) for c non-zero. In other words, nu extends the trivial valuation on K.

Example

julia> nu = tropical_semiring_map(QQ) # arbitrary rings possible
-Map into Min tropical semiring encoding the trivial valuation on Rational field
-
-julia> nu(1)
-(0)
-
-julia> nu(0)
-infty
-
-julia> nu = tropical_semiring_map(QQ,max) # arbitrary rings possible
-Map into Max tropical semiring encoding the trivial valuation on Rational field
-
-julia> nu(1)
-(0)
-
-julia> nu(0)
--infty
-
source
tropical_semiring_mapFunction
tropical_semiring_map(QQ::QQField, p::QQFieldElem, minOrMax::Union{typeof(min),typeof(max)}=min)

Return a map nu from QQ to the min (default) or max tropical semiring T such that nu(0)=zero(T) and nu(c)=+/-val(c) for c non-zero, where val denotes the p-adic valuation. Requires p to be a prime.

Example

julia> nu_2 = tropical_semiring_map(QQ,2)
-Map into Min tropical semiring encoding the 2-adic valuation on Rational field
-
-julia> nu_2(4)
-(2)
-
-julia> nu_2(1//4)
-(-2)
-
-julia> nu_2 = tropical_semiring_map(QQ,2,max);
-
-julia> nu_2(4)
-(-2)
-
-julia> nu_2(1//4)
-(2)
-
source
tropical_semiring_mapFunction
tropical_semiring_map(Kt::Generic.RationalFunctionField, t::Generic.RationalFunctionFieldElem, minOrMax::Union{typeof(min),typeof(max)}=min)

Return a map nu from rational function field Kt to the min (default) or max tropical semiring T such that nu(0)=zero(T) and nu(c)=+/-val(c) for c non-zero, where val denotes the t-adic valuation with uniformizer t. Requires t to be non-constant and have denominator 1.

Example

julia> Kt,t = rational_function_field(QQ,"t");
-
-julia> nu_t = tropical_semiring_map(Kt,t)
-Map into Min tropical semiring encoding the t-adic valuation on Rational function field over QQ
-
-julia> nu_t(t^2)
-(2)
-
-julia> nu_t(1//t^2)
-(-2)
-
-julia> nu_t = tropical_semiring_map(Kt,t,max)
-Map into Max tropical semiring encoding the t-adic valuation on Rational function field over QQ
-
-julia> nu_t(t^2)
-(-2)
-
-julia> nu_t(1//t^2)
-(2)
-
source
diff --git a/previews/PR4245/TropicalGeometry/tropicalization/index.html b/previews/PR4245/TropicalGeometry/tropicalization/index.html deleted file mode 100644 index 706030871c67..000000000000 --- a/previews/PR4245/TropicalGeometry/tropicalization/index.html +++ /dev/null @@ -1,11 +0,0 @@ - -Tropicalization of polynomial ideals · Oscar.jl

Tropicalization of polynomial ideals

Introduction

Tropical varieties can arise as tropicalizations of polynomial ideals. For a general introduction, see

For algorithmic details, see

Main function

tropical_varietyFunction
tropical_variety(I::MPolyIdeal, nu::Union{TropicalSemiringMap,Nothing}=nothing; weighted_polyhedral_complex_only::Bool=false, skip_saturation::Bool=false, skip_primary_decomposition::Bool=false)

Return the tropicalization of I with respect to nu as a Vector{TropicalVariety}. If nu==nothing, will compute with respect to the trivial valuation and min convention. If weighted_polyhedral_complex_only==true, will not cache any additional information. If skip_saturation==true, will not saturate I with respect to the product of all variables. If skip_primary_decomposition==true, will not decompose I.

Warning

tropical_variety is currently under development and only works for ideals that primary decompose into principal, linear, and binomial ideals.

Examples

julia> R,(x,y) = QQ[:x, :y];
-
-julia> I = ideal([(x^2+y)*(x+y^2)*(x+y)]);
-
-julia> tropical_variety(I)
-3-element Vector{TropicalVariety}:
- Min tropical variety
- Min tropical variety
- Min tropical variety
-
source
diff --git a/previews/PR4245/TropicalGeometry/variety/index.html b/previews/PR4245/TropicalGeometry/variety/index.html deleted file mode 100644 index 7b33f2f3a484..000000000000 --- a/previews/PR4245/TropicalGeometry/variety/index.html +++ /dev/null @@ -1,57 +0,0 @@ - -Tropical varieties · Oscar.jl

Tropical varieties

Introduction

Tropial varieties (in OSCAR) are weighted polyhedral complexes. They may arise as tropicalizations of polynomial ideals or from operations on the more specialized types of tropical varieties, such as the stable intersection of tropical hypersurfaces. For more on the first, see

Note:

  • Objects of type TropicalVariety need to be embedded, abstract tropical varieties are currently not supported.
  • The type TropicalVariety can be thought of as supertype of TropicalHypersurface, TropicalCurve, and TropicalLinearSpace in the sense that the latter three should have all properties and features of the former.
  • Embedded tropical varieties are polyhedral complexes with multiplicities and should have all properties of polyhedral complexes

Constructor

Objects of type TropicalVariety can be constructed as follows:

tropical_varietyFunction
tropical_variety(Sigma::PolyhedralComplex, mult, minOrMax::Union{typeof(min),typeof(max)}=min)

Return the TropicalVariety whose polyhedral complex is Sigma with multiplicities mult and convention minOrMax. Here, mult is optional can be specified as a Vector{ZZRingElem} which represents a list of multiplicities on the maximal polyhedra in the order of maximal_polyhedra(Sigma). If mult is unspecified, then all multiplicities are set to one.

Examples

julia> Sigma = polyhedral_complex(incidence_matrix([[1],[2]]), [[0],[1]])
-Polyhedral complex in ambient dimension 1
-
-julia> tropical_variety(Sigma)
-Min tropical variety
-
-julia> mult = ones(ZZRingElem, n_maximal_polyhedra(Sigma))
-2-element Vector{ZZRingElem}:
- 1
- 1
-
-julia> tropical_variety(Sigma,mult,min)
-Min tropical variety
-
-julia> mult = ZZ.([1,2])
-2-element Vector{ZZRingElem}:
- 1
- 2
-
-julia> tropical_variety(Sigma,mult,max)
-Max tropical variety
-
source

Properties

Objects of type TropicalVariety (and TropicalHypersurface, TropicalCurve, TropicalLinearSpace) have the following properties:

polyhedral_complexMethod
polyhedral_complex(TropV::TropicalVariety)

Return the polyhedral complex of a tropical variety.

source
maximal_polyhedra_and_multiplicitiesMethod
maximal_polyhedra_and_multiplicities(TropV::TropicalVariety)

Return the maximal polyhedra and multiplicities of TropV.

Examples

julia> R,(x1,x2) = polynomial_ring(QQ,4);
-
-julia> nu = tropical_semiring_map(QQ,2);
-
-julia> f = 2*x1^2+x1*x2+x2^2+1
-2*x1^2 + x1*x2 + x2^2 + 1
-
-julia> TropH = tropical_hypersurface(f,nu)
-Min tropical hypersurface
-
-julia> maximal_polyhedra_and_multiplicities(TropH)
-5-element Vector{Tuple{Polyhedron{QQFieldElem}, ZZRingElem}}:
- (Polyhedron in ambient dimension 4, 1)
- (Polyhedron in ambient dimension 4, 1)
- (Polyhedron in ambient dimension 4, 2)
- (Polyhedron in ambient dimension 4, 1)
- (Polyhedron in ambient dimension 4, 2)
-
source
multiplicitiesMethod
multiplicities(TropV::TropicalVariety)

Return the multiplicities of TropV. Order is the same as maximal_polyhedra.

Examples

julia> R,(x1,x2) = polynomial_ring(QQ,4);
-
-julia> nu = tropical_semiring_map(QQ,2);
-
-julia> f = 2*x1^2+x1*x2+x2^2+1
-2*x1^2 + x1*x2 + x2^2 + 1
-
-julia> TropH = tropical_hypersurface(f,nu)
-Min tropical hypersurface
-
-julia> multiplicities(TropH)
-5-element Vector{ZZRingElem}:
- 1
- 1
- 2
- 1
- 2
-
source
diff --git a/previews/PR4245/assets/documenter.js b/previews/PR4245/assets/documenter.js deleted file mode 100644 index 82252a11dabd..000000000000 --- a/previews/PR4245/assets/documenter.js +++ /dev/null @@ -1,1064 +0,0 @@ -// Generated by Documenter.jl -requirejs.config({ - paths: { - 'highlight-julia': 'https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.8.0/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.13.2/jquery-ui.min', - 'katex-auto-render': 'https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.16.8/contrib/auto-render.min', - 'jquery': 'https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.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.16.8/katex.min', - 'highlight': 'https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.8.0/highlight.min', - 'highlight-julia-repl': 'https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.8.0/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(['jquery'], function($) { - -let timer = 0; -var isExpanded = true; - -$(document).on( - "click", - ".docstring .docstring-article-toggle-button", - function () { - let articleToggleTitle = "Expand docstring"; - const parent = $(this).parent(); - - debounce(() => { - if (parent.siblings("section").is(":visible")) { - parent - .find("a.docstring-article-toggle-button") - .removeClass("fa-chevron-down") - .addClass("fa-chevron-right"); - } else { - parent - .find("a.docstring-article-toggle-button") - .removeClass("fa-chevron-right") - .addClass("fa-chevron-down"); - - articleToggleTitle = "Collapse docstring"; - } - - parent - .children(".docstring-article-toggle-button") - .prop("title", articleToggleTitle); - parent.siblings("section").slideToggle(); - }); - } -); - -$(document).on("click", ".docs-article-toggle-button", function (event) { - let articleToggleTitle = "Expand docstring"; - let navArticleToggleTitle = "Expand all docstrings"; - let animationSpeed = event.noToggleAnimation ? 0 : 400; - - debounce(() => { - if (isExpanded) { - $(this).removeClass("fa-chevron-up").addClass("fa-chevron-down"); - $("a.docstring-article-toggle-button") - .removeClass("fa-chevron-down") - .addClass("fa-chevron-right"); - - isExpanded = false; - - $(".docstring section").slideUp(animationSpeed); - } else { - $(this).removeClass("fa-chevron-down").addClass("fa-chevron-up"); - $("a.docstring-article-toggle-button") - .removeClass("fa-chevron-right") - .addClass("fa-chevron-down"); - - isExpanded = true; - articleToggleTitle = "Collapse docstring"; - navArticleToggleTitle = "Collapse all docstrings"; - - $(".docstring section").slideDown(animationSpeed); - } - - $(this).prop("title", navArticleToggleTitle); - $(".docstring-article-toggle-button").prop("title", articleToggleTitle); - }); -}); - -function debounce(callback, timeout = 300) { - if (Date.now() - timer > timeout) { - callback(); - } - - clearTimeout(timer); - - timer = Date.now(); -} - -}) -//////////////////////////////////////////////////////////////////////////////// -require([], function() { -function addCopyButtonCallbacks() { - for (const el of document.getElementsByTagName("pre")) { - const button = document.createElement("button"); - button.classList.add("copy-button", "fa-solid", "fa-copy"); - button.setAttribute("aria-label", "Copy this code block"); - button.setAttribute("title", "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-xmark"); - 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-xmark"); - }, 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($) { - -$(document).ready(function () { - let meta = $("div[data-docstringscollapsed]").data(); - - if (meta?.docstringscollapsed) { - $("#documenter-article-toggle-button").trigger({ - type: "click", - noToggleAnimation: true, - }); - } -}); - -}) -//////////////////////////////////////////////////////////////////////////////// -require(['jquery'], function($) { - -/* -To get an in-depth about the thought process you can refer: https://hetarth02.hashnode.dev/series/gsoc - -PSEUDOCODE: - -Searching happens automatically as the user types or adjusts the selected filters. -To preserve responsiveness, as much as possible of the slow parts of the search are done -in a web worker. Searching and result generation are done in the worker, and filtering and -DOM updates are done in the main thread. The filters are in the main thread as they should -be very quick to apply. This lets filters be changed without re-searching with minisearch -(which is possible even if filtering is on the worker thread) and also lets filters be -changed _while_ the worker is searching and without message passing (neither of which are -possible if filtering is on the worker thread) - -SEARCH WORKER: - -Import minisearch - -Build index - -On message from main thread - run search - find the first 200 unique results from each category, and compute their divs for display - note that this is necessary and sufficient information for the main thread to find the - first 200 unique results from any given filter set - post results to main thread - -MAIN: - -Launch worker - -Declare nonconstant globals (worker_is_running, last_search_text, unfiltered_results) - -On text update - if worker is not running, launch_search() - -launch_search - set worker_is_running to true, set last_search_text to the search text - post the search query to worker - -on message from worker - if last_search_text is not the same as the text in the search field, - the latest search result is not reflective of the latest search query, so update again - launch_search() - otherwise - set worker_is_running to false - - regardless, display the new search results to the user - save the unfiltered_results as a global - update_search() - -on filter click - adjust the filter selection - update_search() - -update_search - apply search filters by looping through the unfiltered_results and finding the first 200 - unique results that match the filters - - Update the DOM -*/ - -/////// SEARCH WORKER /////// - -function worker_function(documenterSearchIndex, documenterBaseURL, filters) { - importScripts( - "https://cdn.jsdelivr.net/npm/minisearch@6.1.0/dist/umd/index.min.js" - ); - - let data = documenterSearchIndex.map((x, key) => { - x["id"] = key; // minisearch requires a unique for each object - return x; - }); - - // 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 - const stopWords = new Set([ - "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", - ]); - - let index = new MiniSearch({ - fields: ["title", "text"], // fields to index for full-text search - storeFields: ["location", "title", "text", "category", "page"], // fields to return with results - processTerm: (term) => { - let word = stopWords.has(term) ? null : term; - if (word) { - // custom trimmer that doesn't strip @ and !, which are used in julia macro and function names - word = word - .replace(/^[^a-zA-Z0-9@!]+/, "") - .replace(/[^a-zA-Z0-9@!]+$/, ""); - - word = word.toLowerCase(); - } - - return word ?? null; - }, - // add . as a separator, because otherwise "title": "Documenter.Anchors.add!", would not - // find anything if searching for "add!", only for the entire qualification - tokenize: (string) => string.split(/[\s\-\.]+/), - // options which will be applied during the search - searchOptions: { - prefix: true, - boost: { title: 100 }, - fuzzy: 2, - }, - }); - - index.addAll(data); - - /** - * Used to map characters to HTML entities. - * Refer: https://github.com/lodash/lodash/blob/main/src/escape.ts - */ - const htmlEscapes = { - "&": "&", - "<": "<", - ">": ">", - '"': """, - "'": "'", - }; - - /** - * Used to match HTML entities and HTML characters. - * Refer: https://github.com/lodash/lodash/blob/main/src/escape.ts - */ - const reUnescapedHtml = /[&<>"']/g; - const reHasUnescapedHtml = RegExp(reUnescapedHtml.source); - - /** - * Escape function from lodash - * Refer: https://github.com/lodash/lodash/blob/main/src/escape.ts - */ - function escape(string) { - return string && reHasUnescapedHtml.test(string) - ? string.replace(reUnescapedHtml, (chr) => htmlEscapes[chr]) - : string || ""; - } - - /** - * RegX escape function from MDN - * Refer: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#escaping - */ - function escapeRegExp(string) { - return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); // $& means the whole matched string - } - - /** - * Make the result component given a minisearch result data object and the value - * of the search input as queryString. To view the result object structure, refer: - * https://lucaong.github.io/minisearch/modules/_minisearch_.html#searchresult - * - * @param {object} result - * @param {string} querystring - * @returns string - */ - function make_search_result(result, querystring) { - let search_divider = `
`; - let display_link = - result.location.slice(Math.max(0), Math.min(50, result.location.length)) + - (result.location.length > 30 ? "..." : ""); // To cut-off the link because it messes with the overflow of the whole div - - if (result.page !== "") { - display_link += ` (${result.page})`; - } - searchstring = escapeRegExp(querystring); - let textindex = new RegExp(`${searchstring}`, "i").exec(result.text); - let text = - textindex !== null - ? result.text.slice( - Math.max(textindex.index - 100, 0), - Math.min( - textindex.index + querystring.length + 100, - result.text.length - ) - ) - : ""; // cut-off text before and after from the match - - text = text.length ? escape(text) : ""; - - let display_result = text.length - ? "..." + - text.replace( - new RegExp(`${escape(searchstring)}`, "i"), // For first occurrence - '$&' - ) + - "..." - : ""; // highlights the match - - let in_code = false; - if (!["page", "section"].includes(result.category.toLowerCase())) { - in_code = true; - } - - // We encode the full url to escape some special characters which can lead to broken links - let result_div = ` - -
-
${escape(result.title)}
-
${result.category}
-
-

- ${display_result} -

-
- ${display_link} -
-
- ${search_divider} - `; - - return result_div; - } - - self.onmessage = function (e) { - let query = e.data; - let results = index.search(query, { - filter: (result) => { - // Only return relevant results - return result.score >= 1; - }, - combineWith: "AND", - }); - - // Pre-filter to deduplicate and limit to 200 per category to the extent - // possible without knowing what the filters are. - let filtered_results = []; - let counts = {}; - for (let filter of filters) { - counts[filter] = 0; - } - let present = {}; - - for (let result of results) { - cat = result.category; - cnt = counts[cat]; - if (cnt < 200) { - id = cat + "---" + result.location; - if (present[id]) { - continue; - } - present[id] = true; - filtered_results.push({ - location: result.location, - category: cat, - div: make_search_result(result, query), - }); - } - } - - postMessage(filtered_results); - }; -} - -// `worker = Threads.@spawn worker_function(documenterSearchIndex)`, but in JavaScript! -const filters = [ - ...new Set(documenterSearchIndex["docs"].map((x) => x.category)), -]; -const worker_str = - "(" + - worker_function.toString() + - ")(" + - JSON.stringify(documenterSearchIndex["docs"]) + - "," + - JSON.stringify(documenterBaseURL) + - "," + - JSON.stringify(filters) + - ")"; -const worker_blob = new Blob([worker_str], { type: "text/javascript" }); -const worker = new Worker(URL.createObjectURL(worker_blob)); - -/////// SEARCH MAIN /////// - -// Whether the worker is currently handling a search. This is a boolean -// as the worker only ever handles 1 or 0 searches at a time. -var worker_is_running = false; - -// The last search text that was sent to the worker. This is used to determine -// if the worker should be launched again when it reports back results. -var last_search_text = ""; - -// The results of the last search. This, in combination with the state of the filters -// in the DOM, is used compute the results to display on calls to update_search. -var unfiltered_results = []; - -// Which filter is currently selected -var selected_filter = ""; - -$(document).on("input", ".documenter-search-input", function (event) { - if (!worker_is_running) { - launch_search(); - } -}); - -function launch_search() { - worker_is_running = true; - last_search_text = $(".documenter-search-input").val(); - worker.postMessage(last_search_text); -} - -worker.onmessage = function (e) { - if (last_search_text !== $(".documenter-search-input").val()) { - launch_search(); - } else { - worker_is_running = false; - } - - unfiltered_results = e.data; - update_search(); -}; - -$(document).on("click", ".search-filter", function () { - if ($(this).hasClass("search-filter-selected")) { - selected_filter = ""; - } else { - selected_filter = $(this).text().toLowerCase(); - } - - // This updates search results and toggles classes for UI: - update_search(); -}); - -/** - * Make/Update the search component - */ -function update_search() { - let querystring = $(".documenter-search-input").val(); - - if (querystring.trim()) { - if (selected_filter == "") { - results = unfiltered_results; - } else { - results = unfiltered_results.filter((result) => { - return selected_filter == result.category.toLowerCase(); - }); - } - - let search_result_container = ``; - let modal_filters = make_modal_body_filters(); - let search_divider = `
`; - - if (results.length) { - let links = []; - let count = 0; - let search_results = ""; - - for (var i = 0, n = results.length; i < n && count < 200; ++i) { - let result = results[i]; - if (result.location && !links.includes(result.location)) { - search_results += result.div; - count++; - links.push(result.location); - } - } - - if (count == 1) { - count_str = "1 result"; - } else if (count == 200) { - count_str = "200+ results"; - } else { - count_str = count + " results"; - } - let result_count = `
${count_str}
`; - - search_result_container = ` -
- ${modal_filters} - ${search_divider} - ${result_count} -
- ${search_results} -
-
- `; - } else { - search_result_container = ` -
- ${modal_filters} - ${search_divider} -
0 result(s)
-
-
No result found!
- `; - } - - if ($(".search-modal-card-body").hasClass("is-justify-content-center")) { - $(".search-modal-card-body").removeClass("is-justify-content-center"); - } - - $(".search-modal-card-body").html(search_result_container); - } else { - if (!$(".search-modal-card-body").hasClass("is-justify-content-center")) { - $(".search-modal-card-body").addClass("is-justify-content-center"); - } - - $(".search-modal-card-body").html(` -
Type something to get started!
- `); - } -} - -/** - * Make the modal filter html - * - * @returns string - */ -function make_modal_body_filters() { - let str = filters - .map((val) => { - if (selected_filter == val.toLowerCase()) { - return `${val}`; - } else { - return `${val}`; - } - }) - .join(""); - - return ` -
- Filters: - ${str} -
`; -} - -}) -//////////////////////////////////////////////////////////////////////////////// -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($) { - -$(document).ready(function () { - let search_modal_header = ` - - `; - - let initial_search_body = ` -
Type something to get started!
- `; - - let search_modal_footer = ` -
- - Ctrl + - / to search - - esc to close -
- `; - - $(document.body).append( - ` - - ` - ); - - document.querySelector(".docs-search-query").addEventListener("click", () => { - openModal(); - }); - - document - .querySelector(".close-search-modal") - .addEventListener("click", () => { - closeModal(); - }); - - $(document).on("click", ".search-result-link", function () { - closeModal(); - }); - - document.addEventListener("keydown", (event) => { - if ((event.ctrlKey || event.metaKey) && event.key === "/") { - openModal(); - } else if (event.key === "Escape") { - closeModal(); - } - - return false; - }); - - // Functions to open and close a modal - function openModal() { - let searchModal = document.querySelector("#search-modal"); - - searchModal.classList.add("is-active"); - document.querySelector(".documenter-search-input").focus(); - } - - function closeModal() { - let searchModal = document.querySelector("#search-modal"); - let initial_search_body = ` -
Type something to get started!
- `; - - searchModal.classList.remove("is-active"); - document.querySelector(".documenter-search-input").blur(); - - if (!$(".search-modal-card-body").hasClass("is-justify-content-center")) { - $(".search-modal-card-body").addClass("is-justify-content-center"); - } - - $(".documenter-search-input").val(""); - $(".search-modal-card-body").html(initial_search_body); - } - - document - .querySelector("#search-modal .modal-background") - .addEventListener("click", () => { - closeModal(); - }); -}); - -}) -//////////////////////////////////////////////////////////////////////////////// -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($) { - -// Theme picker setup -$(document).ready(function () { - // onchange callback - $("#documenter-themepicker").change(function themepick_callback(ev) { - var themename = $("#documenter-themepicker option:selected").attr("value"); - if (themename === "auto") { - // set_theme(window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'); - window.localStorage.removeItem("documenter-theme"); - } else { - // set_theme(themename); - window.localStorage.setItem("documenter-theme", themename); - } - // We re-use the global function from themeswap.js to actually do the swapping. - set_theme_from_local_storage(); - }); - - // 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; - }); - } - } -}); - -}) -//////////////////////////////////////////////////////////////////////////////// -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/PR4245/assets/logo.png b/previews/PR4245/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/PR4245/assets/themes/catppuccin-frappe.css b/previews/PR4245/assets/themes/catppuccin-frappe.css deleted file mode 100644 index 32e3f008233c..000000000000 --- a/previews/PR4245/assets/themes/catppuccin-frappe.css +++ /dev/null @@ -1 +0,0 @@ -html.theme--catppuccin-frappe .pagination-previous,html.theme--catppuccin-frappe .pagination-next,html.theme--catppuccin-frappe .pagination-link,html.theme--catppuccin-frappe .pagination-ellipsis,html.theme--catppuccin-frappe .file-cta,html.theme--catppuccin-frappe .file-name,html.theme--catppuccin-frappe .select select,html.theme--catppuccin-frappe .textarea,html.theme--catppuccin-frappe .input,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input,html.theme--catppuccin-frappe .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:1rem;height:2.5em;justify-content:flex-start;line-height:1.5;padding-bottom:calc(0.5em - 1px);padding-left:calc(0.75em - 1px);padding-right:calc(0.75em - 1px);padding-top:calc(0.5em - 1px);position:relative;vertical-align:top}html.theme--catppuccin-frappe .pagination-previous:focus,html.theme--catppuccin-frappe .pagination-next:focus,html.theme--catppuccin-frappe .pagination-link:focus,html.theme--catppuccin-frappe .pagination-ellipsis:focus,html.theme--catppuccin-frappe .file-cta:focus,html.theme--catppuccin-frappe .file-name:focus,html.theme--catppuccin-frappe .select select:focus,html.theme--catppuccin-frappe .textarea:focus,html.theme--catppuccin-frappe .input:focus,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input:focus,html.theme--catppuccin-frappe .button:focus,html.theme--catppuccin-frappe .is-focused.pagination-previous,html.theme--catppuccin-frappe .is-focused.pagination-next,html.theme--catppuccin-frappe .is-focused.pagination-link,html.theme--catppuccin-frappe .is-focused.pagination-ellipsis,html.theme--catppuccin-frappe .is-focused.file-cta,html.theme--catppuccin-frappe .is-focused.file-name,html.theme--catppuccin-frappe .select select.is-focused,html.theme--catppuccin-frappe .is-focused.textarea,html.theme--catppuccin-frappe .is-focused.input,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--catppuccin-frappe .is-focused.button,html.theme--catppuccin-frappe .pagination-previous:active,html.theme--catppuccin-frappe .pagination-next:active,html.theme--catppuccin-frappe .pagination-link:active,html.theme--catppuccin-frappe .pagination-ellipsis:active,html.theme--catppuccin-frappe .file-cta:active,html.theme--catppuccin-frappe .file-name:active,html.theme--catppuccin-frappe .select select:active,html.theme--catppuccin-frappe .textarea:active,html.theme--catppuccin-frappe .input:active,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input:active,html.theme--catppuccin-frappe .button:active,html.theme--catppuccin-frappe .is-active.pagination-previous,html.theme--catppuccin-frappe .is-active.pagination-next,html.theme--catppuccin-frappe .is-active.pagination-link,html.theme--catppuccin-frappe .is-active.pagination-ellipsis,html.theme--catppuccin-frappe .is-active.file-cta,html.theme--catppuccin-frappe .is-active.file-name,html.theme--catppuccin-frappe .select select.is-active,html.theme--catppuccin-frappe .is-active.textarea,html.theme--catppuccin-frappe .is-active.input,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-active,html.theme--catppuccin-frappe .is-active.button{outline:none}html.theme--catppuccin-frappe .pagination-previous[disabled],html.theme--catppuccin-frappe .pagination-next[disabled],html.theme--catppuccin-frappe .pagination-link[disabled],html.theme--catppuccin-frappe .pagination-ellipsis[disabled],html.theme--catppuccin-frappe .file-cta[disabled],html.theme--catppuccin-frappe .file-name[disabled],html.theme--catppuccin-frappe .select select[disabled],html.theme--catppuccin-frappe .textarea[disabled],html.theme--catppuccin-frappe .input[disabled],html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input[disabled],html.theme--catppuccin-frappe .button[disabled],fieldset[disabled] html.theme--catppuccin-frappe .pagination-previous,html.theme--catppuccin-frappe fieldset[disabled] .pagination-previous,fieldset[disabled] html.theme--catppuccin-frappe .pagination-next,html.theme--catppuccin-frappe fieldset[disabled] .pagination-next,fieldset[disabled] html.theme--catppuccin-frappe .pagination-link,html.theme--catppuccin-frappe fieldset[disabled] .pagination-link,fieldset[disabled] html.theme--catppuccin-frappe .pagination-ellipsis,html.theme--catppuccin-frappe fieldset[disabled] .pagination-ellipsis,fieldset[disabled] html.theme--catppuccin-frappe .file-cta,html.theme--catppuccin-frappe fieldset[disabled] .file-cta,fieldset[disabled] html.theme--catppuccin-frappe .file-name,html.theme--catppuccin-frappe fieldset[disabled] .file-name,fieldset[disabled] html.theme--catppuccin-frappe .select select,fieldset[disabled] html.theme--catppuccin-frappe .textarea,fieldset[disabled] html.theme--catppuccin-frappe .input,fieldset[disabled] html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input,html.theme--catppuccin-frappe fieldset[disabled] .select select,html.theme--catppuccin-frappe .select fieldset[disabled] select,html.theme--catppuccin-frappe fieldset[disabled] .textarea,html.theme--catppuccin-frappe fieldset[disabled] .input,html.theme--catppuccin-frappe fieldset[disabled] #documenter .docs-sidebar form.docs-search>input,html.theme--catppuccin-frappe #documenter .docs-sidebar fieldset[disabled] form.docs-search>input,fieldset[disabled] html.theme--catppuccin-frappe .button,html.theme--catppuccin-frappe fieldset[disabled] .button{cursor:not-allowed}html.theme--catppuccin-frappe .tabs,html.theme--catppuccin-frappe .pagination-previous,html.theme--catppuccin-frappe .pagination-next,html.theme--catppuccin-frappe .pagination-link,html.theme--catppuccin-frappe .pagination-ellipsis,html.theme--catppuccin-frappe .breadcrumb,html.theme--catppuccin-frappe .file,html.theme--catppuccin-frappe .button,.is-unselectable{-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}html.theme--catppuccin-frappe .navbar-link:not(.is-arrowless)::after,html.theme--catppuccin-frappe .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--catppuccin-frappe .admonition:not(:last-child),html.theme--catppuccin-frappe .tabs:not(:last-child),html.theme--catppuccin-frappe .pagination:not(:last-child),html.theme--catppuccin-frappe .message:not(:last-child),html.theme--catppuccin-frappe .level:not(:last-child),html.theme--catppuccin-frappe .breadcrumb:not(:last-child),html.theme--catppuccin-frappe .block:not(:last-child),html.theme--catppuccin-frappe .title:not(:last-child),html.theme--catppuccin-frappe .subtitle:not(:last-child),html.theme--catppuccin-frappe .table-container:not(:last-child),html.theme--catppuccin-frappe .table:not(:last-child),html.theme--catppuccin-frappe .progress:not(:last-child),html.theme--catppuccin-frappe .notification:not(:last-child),html.theme--catppuccin-frappe .content:not(:last-child),html.theme--catppuccin-frappe .box:not(:last-child){margin-bottom:1.5rem}html.theme--catppuccin-frappe .modal-close,html.theme--catppuccin-frappe .delete{-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-moz-appearance:none;-webkit-appearance:none;background-color:rgba(10,10,10,0.2);border:none;border-radius:9999px;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--catppuccin-frappe .modal-close::before,html.theme--catppuccin-frappe .delete::before,html.theme--catppuccin-frappe .modal-close::after,html.theme--catppuccin-frappe .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--catppuccin-frappe .modal-close::before,html.theme--catppuccin-frappe .delete::before{height:2px;width:50%}html.theme--catppuccin-frappe .modal-close::after,html.theme--catppuccin-frappe .delete::after{height:50%;width:2px}html.theme--catppuccin-frappe .modal-close:hover,html.theme--catppuccin-frappe .delete:hover,html.theme--catppuccin-frappe .modal-close:focus,html.theme--catppuccin-frappe .delete:focus{background-color:rgba(10,10,10,0.3)}html.theme--catppuccin-frappe .modal-close:active,html.theme--catppuccin-frappe .delete:active{background-color:rgba(10,10,10,0.4)}html.theme--catppuccin-frappe .is-small.modal-close,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.modal-close,html.theme--catppuccin-frappe .is-small.delete,html.theme--catppuccin-frappe #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--catppuccin-frappe .is-medium.modal-close,html.theme--catppuccin-frappe .is-medium.delete{height:24px;max-height:24px;max-width:24px;min-height:24px;min-width:24px;width:24px}html.theme--catppuccin-frappe .is-large.modal-close,html.theme--catppuccin-frappe .is-large.delete{height:32px;max-height:32px;max-width:32px;min-height:32px;min-width:32px;width:32px}html.theme--catppuccin-frappe .control.is-loading::after,html.theme--catppuccin-frappe .select.is-loading::after,html.theme--catppuccin-frappe .loader,html.theme--catppuccin-frappe .button.is-loading::after{animation:spinAround 500ms infinite linear;border:2px solid #838ba7;border-radius:9999px;border-right-color:transparent;border-top-color:transparent;content:"";display:block;height:1em;position:relative;width:1em}html.theme--catppuccin-frappe .hero-video,html.theme--catppuccin-frappe .modal-background,html.theme--catppuccin-frappe .modal,html.theme--catppuccin-frappe .image.is-square img,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-square img,html.theme--catppuccin-frappe .image.is-square .has-ratio,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-square .has-ratio,html.theme--catppuccin-frappe .image.is-1by1 img,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-1by1 img,html.theme--catppuccin-frappe .image.is-1by1 .has-ratio,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-1by1 .has-ratio,html.theme--catppuccin-frappe .image.is-5by4 img,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-5by4 img,html.theme--catppuccin-frappe .image.is-5by4 .has-ratio,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-5by4 .has-ratio,html.theme--catppuccin-frappe .image.is-4by3 img,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-4by3 img,html.theme--catppuccin-frappe .image.is-4by3 .has-ratio,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-4by3 .has-ratio,html.theme--catppuccin-frappe .image.is-3by2 img,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-3by2 img,html.theme--catppuccin-frappe .image.is-3by2 .has-ratio,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-3by2 .has-ratio,html.theme--catppuccin-frappe .image.is-5by3 img,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-5by3 img,html.theme--catppuccin-frappe .image.is-5by3 .has-ratio,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-5by3 .has-ratio,html.theme--catppuccin-frappe .image.is-16by9 img,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-16by9 img,html.theme--catppuccin-frappe .image.is-16by9 .has-ratio,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-16by9 .has-ratio,html.theme--catppuccin-frappe .image.is-2by1 img,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-2by1 img,html.theme--catppuccin-frappe .image.is-2by1 .has-ratio,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-2by1 .has-ratio,html.theme--catppuccin-frappe .image.is-3by1 img,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-3by1 img,html.theme--catppuccin-frappe .image.is-3by1 .has-ratio,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-3by1 .has-ratio,html.theme--catppuccin-frappe .image.is-4by5 img,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-4by5 img,html.theme--catppuccin-frappe .image.is-4by5 .has-ratio,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-4by5 .has-ratio,html.theme--catppuccin-frappe .image.is-3by4 img,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-3by4 img,html.theme--catppuccin-frappe .image.is-3by4 .has-ratio,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-3by4 .has-ratio,html.theme--catppuccin-frappe .image.is-2by3 img,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-2by3 img,html.theme--catppuccin-frappe .image.is-2by3 .has-ratio,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-2by3 .has-ratio,html.theme--catppuccin-frappe .image.is-3by5 img,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-3by5 img,html.theme--catppuccin-frappe .image.is-3by5 .has-ratio,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-3by5 .has-ratio,html.theme--catppuccin-frappe .image.is-9by16 img,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-9by16 img,html.theme--catppuccin-frappe .image.is-9by16 .has-ratio,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-9by16 .has-ratio,html.theme--catppuccin-frappe .image.is-1by2 img,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-1by2 img,html.theme--catppuccin-frappe .image.is-1by2 .has-ratio,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-1by2 .has-ratio,html.theme--catppuccin-frappe .image.is-1by3 img,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-1by3 img,html.theme--catppuccin-frappe .image.is-1by3 .has-ratio,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-1by3 .has-ratio,.is-overlay{bottom:0;left:0;position:absolute;right:0;top:0}html.theme--catppuccin-frappe .navbar-burger{-moz-appearance:none;-webkit-appearance:none;appearance:none;background:none;border:none;color:currentColor;font-family:inherit;font-size:1em;margin:0;padding:0}/*! minireset.css v0.0.6 | 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,video{height:auto;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:inherit}.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:#414559 !important}a.has-text-dark:hover,a.has-text-dark:focus{color:#2b2e3c !important}.has-background-dark{background-color:#414559 !important}.has-text-primary{color:#8caaee !important}a.has-text-primary:hover,a.has-text-primary:focus{color:#6089e7 !important}.has-background-primary{background-color:#8caaee !important}.has-text-primary-light{color:#edf2fc !important}a.has-text-primary-light:hover,a.has-text-primary-light:focus{color:#c1d1f6 !important}.has-background-primary-light{background-color:#edf2fc !important}.has-text-primary-dark{color:#153a8e !important}a.has-text-primary-dark:hover,a.has-text-primary-dark:focus{color:#1c4cbb !important}.has-background-primary-dark{background-color:#153a8e !important}.has-text-link{color:#8caaee !important}a.has-text-link:hover,a.has-text-link:focus{color:#6089e7 !important}.has-background-link{background-color:#8caaee !important}.has-text-link-light{color:#edf2fc !important}a.has-text-link-light:hover,a.has-text-link-light:focus{color:#c1d1f6 !important}.has-background-link-light{background-color:#edf2fc !important}.has-text-link-dark{color:#153a8e !important}a.has-text-link-dark:hover,a.has-text-link-dark:focus{color:#1c4cbb !important}.has-background-link-dark{background-color:#153a8e !important}.has-text-info{color:#81c8be !important}a.has-text-info:hover,a.has-text-info:focus{color:#5db9ac !important}.has-background-info{background-color:#81c8be !important}.has-text-info-light{color:#f1f9f8 !important}a.has-text-info-light:hover,a.has-text-info-light:focus{color:#cde9e5 !important}.has-background-info-light{background-color:#f1f9f8 !important}.has-text-info-dark{color:#2d675f !important}a.has-text-info-dark:hover,a.has-text-info-dark:focus{color:#3c8a7f !important}.has-background-info-dark{background-color:#2d675f !important}.has-text-success{color:#a6d189 !important}a.has-text-success:hover,a.has-text-success:focus{color:#8ac364 !important}.has-background-success{background-color:#a6d189 !important}.has-text-success-light{color:#f4f9f0 !important}a.has-text-success-light:hover,a.has-text-success-light:focus{color:#d8ebcc !important}.has-background-success-light{background-color:#f4f9f0 !important}.has-text-success-dark{color:#446a29 !important}a.has-text-success-dark:hover,a.has-text-success-dark:focus{color:#5b8f38 !important}.has-background-success-dark{background-color:#446a29 !important}.has-text-warning{color:#e5c890 !important}a.has-text-warning:hover,a.has-text-warning:focus{color:#dbb467 !important}.has-background-warning{background-color:#e5c890 !important}.has-text-warning-light{color:#fbf7ee !important}a.has-text-warning-light:hover,a.has-text-warning-light:focus{color:#f1e2c5 !important}.has-background-warning-light{background-color:#fbf7ee !important}.has-text-warning-dark{color:#78591c !important}a.has-text-warning-dark:hover,a.has-text-warning-dark:focus{color:#a17726 !important}.has-background-warning-dark{background-color:#78591c !important}.has-text-danger{color:#e78284 !important}a.has-text-danger:hover,a.has-text-danger:focus{color:#df575a !important}.has-background-danger{background-color:#e78284 !important}.has-text-danger-light{color:#fceeee !important}a.has-text-danger-light:hover,a.has-text-danger-light:focus{color:#f3c3c4 !important}.has-background-danger-light{background-color:#fceeee !important}.has-text-danger-dark{color:#9a1e20 !important}a.has-text-danger-dark:hover,a.has-text-danger-dark:focus{color:#c52629 !important}.has-background-danger-dark{background-color:#9a1e20 !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:#414559 !important}.has-background-grey-darker{background-color:#414559 !important}.has-text-grey-dark{color:#51576d !important}.has-background-grey-dark{background-color:#51576d !important}.has-text-grey{color:#626880 !important}.has-background-grey{background-color:#626880 !important}.has-text-grey-light{color:#737994 !important}.has-background-grey-light{background-color:#737994 !important}.has-text-grey-lighter{color:#838ba7 !important}.has-background-grey-lighter{background-color:#838ba7 !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}.is-flex-direction-row{flex-direction:row !important}.is-flex-direction-row-reverse{flex-direction:row-reverse !important}.is-flex-direction-column{flex-direction:column !important}.is-flex-direction-column-reverse{flex-direction:column-reverse !important}.is-flex-wrap-nowrap{flex-wrap:nowrap !important}.is-flex-wrap-wrap{flex-wrap:wrap !important}.is-flex-wrap-wrap-reverse{flex-wrap:wrap-reverse !important}.is-justify-content-flex-start{justify-content:flex-start !important}.is-justify-content-flex-end{justify-content:flex-end !important}.is-justify-content-center{justify-content:center !important}.is-justify-content-space-between{justify-content:space-between !important}.is-justify-content-space-around{justify-content:space-around !important}.is-justify-content-space-evenly{justify-content:space-evenly !important}.is-justify-content-start{justify-content:start !important}.is-justify-content-end{justify-content:end !important}.is-justify-content-left{justify-content:left !important}.is-justify-content-right{justify-content:right !important}.is-align-content-flex-start{align-content:flex-start !important}.is-align-content-flex-end{align-content:flex-end !important}.is-align-content-center{align-content:center !important}.is-align-content-space-between{align-content:space-between !important}.is-align-content-space-around{align-content:space-around !important}.is-align-content-space-evenly{align-content:space-evenly !important}.is-align-content-stretch{align-content:stretch !important}.is-align-content-start{align-content:start !important}.is-align-content-end{align-content:end !important}.is-align-content-baseline{align-content:baseline !important}.is-align-items-stretch{align-items:stretch !important}.is-align-items-flex-start{align-items:flex-start !important}.is-align-items-flex-end{align-items:flex-end !important}.is-align-items-center{align-items:center !important}.is-align-items-baseline{align-items:baseline !important}.is-align-items-start{align-items:start !important}.is-align-items-end{align-items:end !important}.is-align-items-self-start{align-items:self-start !important}.is-align-items-self-end{align-items:self-end !important}.is-align-self-auto{align-self:auto !important}.is-align-self-flex-start{align-self:flex-start !important}.is-align-self-flex-end{align-self:flex-end !important}.is-align-self-center{align-self:center !important}.is-align-self-baseline{align-self:baseline !important}.is-align-self-stretch{align-self:stretch !important}.is-flex-grow-0{flex-grow:0 !important}.is-flex-grow-1{flex-grow:1 !important}.is-flex-grow-2{flex-grow:2 !important}.is-flex-grow-3{flex-grow:3 !important}.is-flex-grow-4{flex-grow:4 !important}.is-flex-grow-5{flex-grow:5 !important}.is-flex-shrink-0{flex-shrink:0 !important}.is-flex-shrink-1{flex-shrink:1 !important}.is-flex-shrink-2{flex-shrink:2 !important}.is-flex-shrink-3{flex-shrink:3 !important}.is-flex-shrink-4{flex-shrink:4 !important}.is-flex-shrink-5{flex-shrink:5 !important}.is-clearfix::after{clear:both;content:" ";display:table}.is-pulled-left{float:left !important}.is-pulled-right{float:right !important}.is-radiusless{border-radius:0 !important}.is-shadowless{box-shadow:none !important}.is-clickable{cursor:pointer !important;pointer-events:all !important}.is-clipped{overflow:hidden !important}.is-relative{position:relative !important}.is-marginless{margin:0 !important}.is-paddingless{padding:0 !important}.m-0{margin:0 !important}.mt-0{margin-top:0 !important}.mr-0{margin-right:0 !important}.mb-0{margin-bottom:0 !important}.ml-0{margin-left:0 !important}.mx-0{margin-left:0 !important;margin-right:0 !important}.my-0{margin-top:0 !important;margin-bottom:0 !important}.m-1{margin:.25rem !important}.mt-1{margin-top:.25rem !important}.mr-1{margin-right:.25rem !important}.mb-1{margin-bottom:.25rem !important}.ml-1{margin-left:.25rem !important}.mx-1{margin-left:.25rem !important;margin-right:.25rem !important}.my-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.m-2{margin:.5rem !important}.mt-2{margin-top:.5rem !important}.mr-2{margin-right:.5rem !important}.mb-2{margin-bottom:.5rem !important}.ml-2{margin-left:.5rem !important}.mx-2{margin-left:.5rem !important;margin-right:.5rem !important}.my-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.m-3{margin:.75rem !important}.mt-3{margin-top:.75rem !important}.mr-3{margin-right:.75rem !important}.mb-3{margin-bottom:.75rem !important}.ml-3{margin-left:.75rem !important}.mx-3{margin-left:.75rem !important;margin-right:.75rem !important}.my-3{margin-top:.75rem !important;margin-bottom:.75rem !important}.m-4{margin:1rem !important}.mt-4{margin-top:1rem !important}.mr-4{margin-right:1rem !important}.mb-4{margin-bottom:1rem !important}.ml-4{margin-left:1rem !important}.mx-4{margin-left:1rem !important;margin-right:1rem !important}.my-4{margin-top:1rem !important;margin-bottom:1rem !important}.m-5{margin:1.5rem !important}.mt-5{margin-top:1.5rem !important}.mr-5{margin-right:1.5rem !important}.mb-5{margin-bottom:1.5rem !important}.ml-5{margin-left:1.5rem !important}.mx-5{margin-left:1.5rem !important;margin-right:1.5rem !important}.my-5{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.m-6{margin:3rem !important}.mt-6{margin-top:3rem !important}.mr-6{margin-right:3rem !important}.mb-6{margin-bottom:3rem !important}.ml-6{margin-left:3rem !important}.mx-6{margin-left:3rem !important;margin-right:3rem !important}.my-6{margin-top:3rem !important;margin-bottom:3rem !important}.m-auto{margin:auto !important}.mt-auto{margin-top:auto !important}.mr-auto{margin-right:auto !important}.mb-auto{margin-bottom:auto !important}.ml-auto{margin-left:auto !important}.mx-auto{margin-left:auto !important;margin-right:auto !important}.my-auto{margin-top:auto !important;margin-bottom:auto !important}.p-0{padding:0 !important}.pt-0{padding-top:0 !important}.pr-0{padding-right:0 !important}.pb-0{padding-bottom:0 !important}.pl-0{padding-left:0 !important}.px-0{padding-left:0 !important;padding-right:0 !important}.py-0{padding-top:0 !important;padding-bottom:0 !important}.p-1{padding:.25rem !important}.pt-1{padding-top:.25rem !important}.pr-1{padding-right:.25rem !important}.pb-1{padding-bottom:.25rem !important}.pl-1{padding-left:.25rem !important}.px-1{padding-left:.25rem !important;padding-right:.25rem !important}.py-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.p-2{padding:.5rem !important}.pt-2{padding-top:.5rem !important}.pr-2{padding-right:.5rem !important}.pb-2{padding-bottom:.5rem !important}.pl-2{padding-left:.5rem !important}.px-2{padding-left:.5rem !important;padding-right:.5rem !important}.py-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.p-3{padding:.75rem !important}.pt-3{padding-top:.75rem !important}.pr-3{padding-right:.75rem !important}.pb-3{padding-bottom:.75rem !important}.pl-3{padding-left:.75rem !important}.px-3{padding-left:.75rem !important;padding-right:.75rem !important}.py-3{padding-top:.75rem !important;padding-bottom:.75rem !important}.p-4{padding:1rem !important}.pt-4{padding-top:1rem !important}.pr-4{padding-right:1rem !important}.pb-4{padding-bottom:1rem !important}.pl-4{padding-left:1rem !important}.px-4{padding-left:1rem !important;padding-right:1rem !important}.py-4{padding-top:1rem !important;padding-bottom:1rem !important}.p-5{padding:1.5rem !important}.pt-5{padding-top:1.5rem !important}.pr-5{padding-right:1.5rem !important}.pb-5{padding-bottom:1.5rem !important}.pl-5{padding-left:1.5rem !important}.px-5{padding-left:1.5rem !important;padding-right:1.5rem !important}.py-5{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.p-6{padding:3rem !important}.pt-6{padding-top:3rem !important}.pr-6{padding-right:3rem !important}.pb-6{padding-bottom:3rem !important}.pl-6{padding-left:3rem !important}.px-6{padding-left:3rem !important;padding-right:3rem !important}.py-6{padding-top:3rem !important;padding-bottom:3rem !important}.p-auto{padding:auto !important}.pt-auto{padding-top:auto !important}.pr-auto{padding-right:auto !important}.pb-auto{padding-bottom:auto !important}.pl-auto{padding-left:auto !important}.px-auto{padding-left:auto !important;padding-right:auto !important}.py-auto{padding-top:auto !important;padding-bottom:auto !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,html.theme--catppuccin-frappe .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}.is-underlined{text-decoration:underline !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}}html.theme--catppuccin-frappe html{background-color:#303446;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--catppuccin-frappe article,html.theme--catppuccin-frappe aside,html.theme--catppuccin-frappe figure,html.theme--catppuccin-frappe footer,html.theme--catppuccin-frappe header,html.theme--catppuccin-frappe hgroup,html.theme--catppuccin-frappe section{display:block}html.theme--catppuccin-frappe body,html.theme--catppuccin-frappe button,html.theme--catppuccin-frappe input,html.theme--catppuccin-frappe optgroup,html.theme--catppuccin-frappe select,html.theme--catppuccin-frappe textarea{font-family:"Lato Medium",-apple-system,BlinkMacSystemFont,"Segoe UI","Helvetica Neue","Helvetica","Arial",sans-serif}html.theme--catppuccin-frappe code,html.theme--catppuccin-frappe 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--catppuccin-frappe body{color:#c6d0f5;font-size:1em;font-weight:400;line-height:1.5}html.theme--catppuccin-frappe a{color:#8caaee;cursor:pointer;text-decoration:none}html.theme--catppuccin-frappe a strong{color:currentColor}html.theme--catppuccin-frappe a:hover{color:#99d1db}html.theme--catppuccin-frappe code{background-color:#292c3c;color:#c6d0f5;font-size:.875em;font-weight:normal;padding:.1em}html.theme--catppuccin-frappe hr{background-color:#292c3c;border:none;display:block;height:2px;margin:1.5rem 0}html.theme--catppuccin-frappe img{height:auto;max-width:100%}html.theme--catppuccin-frappe input[type="checkbox"],html.theme--catppuccin-frappe input[type="radio"]{vertical-align:baseline}html.theme--catppuccin-frappe small{font-size:.875em}html.theme--catppuccin-frappe span{font-style:inherit;font-weight:inherit}html.theme--catppuccin-frappe strong{color:#b0bef1;font-weight:700}html.theme--catppuccin-frappe fieldset{border:none}html.theme--catppuccin-frappe pre{-webkit-overflow-scrolling:touch;background-color:#292c3c;color:#c6d0f5;font-size:.875em;overflow-x:auto;padding:1.25rem 1.5rem;white-space:pre;word-wrap:normal}html.theme--catppuccin-frappe pre code{background-color:transparent;color:currentColor;font-size:1em;padding:0}html.theme--catppuccin-frappe table td,html.theme--catppuccin-frappe table th{vertical-align:top}html.theme--catppuccin-frappe table td:not([align]),html.theme--catppuccin-frappe table th:not([align]){text-align:inherit}html.theme--catppuccin-frappe table th{color:#b0bef1}html.theme--catppuccin-frappe .box{background-color:#51576d;border-radius:8px;box-shadow:none;color:#c6d0f5;display:block;padding:1.25rem}html.theme--catppuccin-frappe a.box:hover,html.theme--catppuccin-frappe a.box:focus{box-shadow:0 0.5em 1em -0.125em rgba(10,10,10,0.1),0 0 0 1px #8caaee}html.theme--catppuccin-frappe a.box:active{box-shadow:inset 0 1px 2px rgba(10,10,10,0.2),0 0 0 1px #8caaee}html.theme--catppuccin-frappe .button{background-color:#292c3c;border-color:#484d69;border-width:1px;color:#8caaee;cursor:pointer;justify-content:center;padding-bottom:calc(0.5em - 1px);padding-left:1em;padding-right:1em;padding-top:calc(0.5em - 1px);text-align:center;white-space:nowrap}html.theme--catppuccin-frappe .button strong{color:inherit}html.theme--catppuccin-frappe .button .icon,html.theme--catppuccin-frappe .button .icon.is-small,html.theme--catppuccin-frappe .button #documenter .docs-sidebar form.docs-search>input.icon,html.theme--catppuccin-frappe #documenter .docs-sidebar .button form.docs-search>input.icon,html.theme--catppuccin-frappe .button .icon.is-medium,html.theme--catppuccin-frappe .button .icon.is-large{height:1.5em;width:1.5em}html.theme--catppuccin-frappe .button .icon:first-child:not(:last-child){margin-left:calc(-0.5em - 1px);margin-right:.25em}html.theme--catppuccin-frappe .button .icon:last-child:not(:first-child){margin-left:.25em;margin-right:calc(-0.5em - 1px)}html.theme--catppuccin-frappe .button .icon:first-child:last-child{margin-left:calc(-0.5em - 1px);margin-right:calc(-0.5em - 1px)}html.theme--catppuccin-frappe .button:hover,html.theme--catppuccin-frappe .button.is-hovered{border-color:#737994;color:#b0bef1}html.theme--catppuccin-frappe .button:focus,html.theme--catppuccin-frappe .button.is-focused{border-color:#737994;color:#769aeb}html.theme--catppuccin-frappe .button:focus:not(:active),html.theme--catppuccin-frappe .button.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(140,170,238,0.25)}html.theme--catppuccin-frappe .button:active,html.theme--catppuccin-frappe .button.is-active{border-color:#51576d;color:#b0bef1}html.theme--catppuccin-frappe .button.is-text{background-color:transparent;border-color:transparent;color:#c6d0f5;text-decoration:underline}html.theme--catppuccin-frappe .button.is-text:hover,html.theme--catppuccin-frappe .button.is-text.is-hovered,html.theme--catppuccin-frappe .button.is-text:focus,html.theme--catppuccin-frappe .button.is-text.is-focused{background-color:#292c3c;color:#b0bef1}html.theme--catppuccin-frappe .button.is-text:active,html.theme--catppuccin-frappe .button.is-text.is-active{background-color:#1f212d;color:#b0bef1}html.theme--catppuccin-frappe .button.is-text[disabled],fieldset[disabled] html.theme--catppuccin-frappe .button.is-text{background-color:transparent;border-color:transparent;box-shadow:none}html.theme--catppuccin-frappe .button.is-ghost{background:none;border-color:rgba(0,0,0,0);color:#8caaee;text-decoration:none}html.theme--catppuccin-frappe .button.is-ghost:hover,html.theme--catppuccin-frappe .button.is-ghost.is-hovered{color:#8caaee;text-decoration:underline}html.theme--catppuccin-frappe .button.is-white{background-color:#fff;border-color:transparent;color:#0a0a0a}html.theme--catppuccin-frappe .button.is-white:hover,html.theme--catppuccin-frappe .button.is-white.is-hovered{background-color:#f9f9f9;border-color:transparent;color:#0a0a0a}html.theme--catppuccin-frappe .button.is-white:focus,html.theme--catppuccin-frappe .button.is-white.is-focused{border-color:transparent;color:#0a0a0a}html.theme--catppuccin-frappe .button.is-white:focus:not(:active),html.theme--catppuccin-frappe .button.is-white.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(255,255,255,0.25)}html.theme--catppuccin-frappe .button.is-white:active,html.theme--catppuccin-frappe .button.is-white.is-active{background-color:#f2f2f2;border-color:transparent;color:#0a0a0a}html.theme--catppuccin-frappe .button.is-white[disabled],fieldset[disabled] html.theme--catppuccin-frappe .button.is-white{background-color:#fff;border-color:#fff;box-shadow:none}html.theme--catppuccin-frappe .button.is-white.is-inverted{background-color:#0a0a0a;color:#fff}html.theme--catppuccin-frappe .button.is-white.is-inverted:hover,html.theme--catppuccin-frappe .button.is-white.is-inverted.is-hovered{background-color:#000}html.theme--catppuccin-frappe .button.is-white.is-inverted[disabled],fieldset[disabled] html.theme--catppuccin-frappe .button.is-white.is-inverted{background-color:#0a0a0a;border-color:transparent;box-shadow:none;color:#fff}html.theme--catppuccin-frappe .button.is-white.is-loading::after{border-color:transparent transparent #0a0a0a #0a0a0a !important}html.theme--catppuccin-frappe .button.is-white.is-outlined{background-color:transparent;border-color:#fff;color:#fff}html.theme--catppuccin-frappe .button.is-white.is-outlined:hover,html.theme--catppuccin-frappe .button.is-white.is-outlined.is-hovered,html.theme--catppuccin-frappe .button.is-white.is-outlined:focus,html.theme--catppuccin-frappe .button.is-white.is-outlined.is-focused{background-color:#fff;border-color:#fff;color:#0a0a0a}html.theme--catppuccin-frappe .button.is-white.is-outlined.is-loading::after{border-color:transparent transparent #fff #fff !important}html.theme--catppuccin-frappe .button.is-white.is-outlined.is-loading:hover::after,html.theme--catppuccin-frappe .button.is-white.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-frappe .button.is-white.is-outlined.is-loading:focus::after,html.theme--catppuccin-frappe .button.is-white.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #0a0a0a #0a0a0a !important}html.theme--catppuccin-frappe .button.is-white.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-frappe .button.is-white.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}html.theme--catppuccin-frappe .button.is-white.is-inverted.is-outlined{background-color:transparent;border-color:#0a0a0a;color:#0a0a0a}html.theme--catppuccin-frappe .button.is-white.is-inverted.is-outlined:hover,html.theme--catppuccin-frappe .button.is-white.is-inverted.is-outlined.is-hovered,html.theme--catppuccin-frappe .button.is-white.is-inverted.is-outlined:focus,html.theme--catppuccin-frappe .button.is-white.is-inverted.is-outlined.is-focused{background-color:#0a0a0a;color:#fff}html.theme--catppuccin-frappe .button.is-white.is-inverted.is-outlined.is-loading:hover::after,html.theme--catppuccin-frappe .button.is-white.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-frappe .button.is-white.is-inverted.is-outlined.is-loading:focus::after,html.theme--catppuccin-frappe .button.is-white.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #fff #fff !important}html.theme--catppuccin-frappe .button.is-white.is-inverted.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-frappe .button.is-white.is-inverted.is-outlined{background-color:transparent;border-color:#0a0a0a;box-shadow:none;color:#0a0a0a}html.theme--catppuccin-frappe .button.is-black{background-color:#0a0a0a;border-color:transparent;color:#fff}html.theme--catppuccin-frappe .button.is-black:hover,html.theme--catppuccin-frappe .button.is-black.is-hovered{background-color:#040404;border-color:transparent;color:#fff}html.theme--catppuccin-frappe .button.is-black:focus,html.theme--catppuccin-frappe .button.is-black.is-focused{border-color:transparent;color:#fff}html.theme--catppuccin-frappe .button.is-black:focus:not(:active),html.theme--catppuccin-frappe .button.is-black.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(10,10,10,0.25)}html.theme--catppuccin-frappe .button.is-black:active,html.theme--catppuccin-frappe .button.is-black.is-active{background-color:#000;border-color:transparent;color:#fff}html.theme--catppuccin-frappe .button.is-black[disabled],fieldset[disabled] html.theme--catppuccin-frappe .button.is-black{background-color:#0a0a0a;border-color:#0a0a0a;box-shadow:none}html.theme--catppuccin-frappe .button.is-black.is-inverted{background-color:#fff;color:#0a0a0a}html.theme--catppuccin-frappe .button.is-black.is-inverted:hover,html.theme--catppuccin-frappe .button.is-black.is-inverted.is-hovered{background-color:#f2f2f2}html.theme--catppuccin-frappe .button.is-black.is-inverted[disabled],fieldset[disabled] html.theme--catppuccin-frappe .button.is-black.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#0a0a0a}html.theme--catppuccin-frappe .button.is-black.is-loading::after{border-color:transparent transparent #fff #fff !important}html.theme--catppuccin-frappe .button.is-black.is-outlined{background-color:transparent;border-color:#0a0a0a;color:#0a0a0a}html.theme--catppuccin-frappe .button.is-black.is-outlined:hover,html.theme--catppuccin-frappe .button.is-black.is-outlined.is-hovered,html.theme--catppuccin-frappe .button.is-black.is-outlined:focus,html.theme--catppuccin-frappe .button.is-black.is-outlined.is-focused{background-color:#0a0a0a;border-color:#0a0a0a;color:#fff}html.theme--catppuccin-frappe .button.is-black.is-outlined.is-loading::after{border-color:transparent transparent #0a0a0a #0a0a0a !important}html.theme--catppuccin-frappe .button.is-black.is-outlined.is-loading:hover::after,html.theme--catppuccin-frappe .button.is-black.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-frappe .button.is-black.is-outlined.is-loading:focus::after,html.theme--catppuccin-frappe .button.is-black.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #fff #fff !important}html.theme--catppuccin-frappe .button.is-black.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-frappe .button.is-black.is-outlined{background-color:transparent;border-color:#0a0a0a;box-shadow:none;color:#0a0a0a}html.theme--catppuccin-frappe .button.is-black.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}html.theme--catppuccin-frappe .button.is-black.is-inverted.is-outlined:hover,html.theme--catppuccin-frappe .button.is-black.is-inverted.is-outlined.is-hovered,html.theme--catppuccin-frappe .button.is-black.is-inverted.is-outlined:focus,html.theme--catppuccin-frappe .button.is-black.is-inverted.is-outlined.is-focused{background-color:#fff;color:#0a0a0a}html.theme--catppuccin-frappe .button.is-black.is-inverted.is-outlined.is-loading:hover::after,html.theme--catppuccin-frappe .button.is-black.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-frappe .button.is-black.is-inverted.is-outlined.is-loading:focus::after,html.theme--catppuccin-frappe .button.is-black.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #0a0a0a #0a0a0a !important}html.theme--catppuccin-frappe .button.is-black.is-inverted.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-frappe .button.is-black.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}html.theme--catppuccin-frappe .button.is-light{background-color:#f5f5f5;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .button.is-light:hover,html.theme--catppuccin-frappe .button.is-light.is-hovered{background-color:#eee;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .button.is-light:focus,html.theme--catppuccin-frappe .button.is-light.is-focused{border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .button.is-light:focus:not(:active),html.theme--catppuccin-frappe .button.is-light.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(245,245,245,0.25)}html.theme--catppuccin-frappe .button.is-light:active,html.theme--catppuccin-frappe .button.is-light.is-active{background-color:#e8e8e8;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .button.is-light[disabled],fieldset[disabled] html.theme--catppuccin-frappe .button.is-light{background-color:#f5f5f5;border-color:#f5f5f5;box-shadow:none}html.theme--catppuccin-frappe .button.is-light.is-inverted{background-color:rgba(0,0,0,0.7);color:#f5f5f5}html.theme--catppuccin-frappe .button.is-light.is-inverted:hover,html.theme--catppuccin-frappe .button.is-light.is-inverted.is-hovered{background-color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .button.is-light.is-inverted[disabled],fieldset[disabled] html.theme--catppuccin-frappe .button.is-light.is-inverted{background-color:rgba(0,0,0,0.7);border-color:transparent;box-shadow:none;color:#f5f5f5}html.theme--catppuccin-frappe .button.is-light.is-loading::after{border-color:transparent transparent rgba(0,0,0,0.7) rgba(0,0,0,0.7) !important}html.theme--catppuccin-frappe .button.is-light.is-outlined{background-color:transparent;border-color:#f5f5f5;color:#f5f5f5}html.theme--catppuccin-frappe .button.is-light.is-outlined:hover,html.theme--catppuccin-frappe .button.is-light.is-outlined.is-hovered,html.theme--catppuccin-frappe .button.is-light.is-outlined:focus,html.theme--catppuccin-frappe .button.is-light.is-outlined.is-focused{background-color:#f5f5f5;border-color:#f5f5f5;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .button.is-light.is-outlined.is-loading::after{border-color:transparent transparent #f5f5f5 #f5f5f5 !important}html.theme--catppuccin-frappe .button.is-light.is-outlined.is-loading:hover::after,html.theme--catppuccin-frappe .button.is-light.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-frappe .button.is-light.is-outlined.is-loading:focus::after,html.theme--catppuccin-frappe .button.is-light.is-outlined.is-loading.is-focused::after{border-color:transparent transparent rgba(0,0,0,0.7) rgba(0,0,0,0.7) !important}html.theme--catppuccin-frappe .button.is-light.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-frappe .button.is-light.is-outlined{background-color:transparent;border-color:#f5f5f5;box-shadow:none;color:#f5f5f5}html.theme--catppuccin-frappe .button.is-light.is-inverted.is-outlined{background-color:transparent;border-color:rgba(0,0,0,0.7);color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .button.is-light.is-inverted.is-outlined:hover,html.theme--catppuccin-frappe .button.is-light.is-inverted.is-outlined.is-hovered,html.theme--catppuccin-frappe .button.is-light.is-inverted.is-outlined:focus,html.theme--catppuccin-frappe .button.is-light.is-inverted.is-outlined.is-focused{background-color:rgba(0,0,0,0.7);color:#f5f5f5}html.theme--catppuccin-frappe .button.is-light.is-inverted.is-outlined.is-loading:hover::after,html.theme--catppuccin-frappe .button.is-light.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-frappe .button.is-light.is-inverted.is-outlined.is-loading:focus::after,html.theme--catppuccin-frappe .button.is-light.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #f5f5f5 #f5f5f5 !important}html.theme--catppuccin-frappe .button.is-light.is-inverted.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-frappe .button.is-light.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)}html.theme--catppuccin-frappe .button.is-dark,html.theme--catppuccin-frappe .content kbd.button{background-color:#414559;border-color:transparent;color:#fff}html.theme--catppuccin-frappe .button.is-dark:hover,html.theme--catppuccin-frappe .content kbd.button:hover,html.theme--catppuccin-frappe .button.is-dark.is-hovered,html.theme--catppuccin-frappe .content kbd.button.is-hovered{background-color:#3c3f52;border-color:transparent;color:#fff}html.theme--catppuccin-frappe .button.is-dark:focus,html.theme--catppuccin-frappe .content kbd.button:focus,html.theme--catppuccin-frappe .button.is-dark.is-focused,html.theme--catppuccin-frappe .content kbd.button.is-focused{border-color:transparent;color:#fff}html.theme--catppuccin-frappe .button.is-dark:focus:not(:active),html.theme--catppuccin-frappe .content kbd.button:focus:not(:active),html.theme--catppuccin-frappe .button.is-dark.is-focused:not(:active),html.theme--catppuccin-frappe .content kbd.button.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(65,69,89,0.25)}html.theme--catppuccin-frappe .button.is-dark:active,html.theme--catppuccin-frappe .content kbd.button:active,html.theme--catppuccin-frappe .button.is-dark.is-active,html.theme--catppuccin-frappe .content kbd.button.is-active{background-color:#363a4a;border-color:transparent;color:#fff}html.theme--catppuccin-frappe .button.is-dark[disabled],html.theme--catppuccin-frappe .content kbd.button[disabled],fieldset[disabled] html.theme--catppuccin-frappe .button.is-dark,fieldset[disabled] html.theme--catppuccin-frappe .content kbd.button{background-color:#414559;border-color:#414559;box-shadow:none}html.theme--catppuccin-frappe .button.is-dark.is-inverted,html.theme--catppuccin-frappe .content kbd.button.is-inverted{background-color:#fff;color:#414559}html.theme--catppuccin-frappe .button.is-dark.is-inverted:hover,html.theme--catppuccin-frappe .content kbd.button.is-inverted:hover,html.theme--catppuccin-frappe .button.is-dark.is-inverted.is-hovered,html.theme--catppuccin-frappe .content kbd.button.is-inverted.is-hovered{background-color:#f2f2f2}html.theme--catppuccin-frappe .button.is-dark.is-inverted[disabled],html.theme--catppuccin-frappe .content kbd.button.is-inverted[disabled],fieldset[disabled] html.theme--catppuccin-frappe .button.is-dark.is-inverted,fieldset[disabled] html.theme--catppuccin-frappe .content kbd.button.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#414559}html.theme--catppuccin-frappe .button.is-dark.is-loading::after,html.theme--catppuccin-frappe .content kbd.button.is-loading::after{border-color:transparent transparent #fff #fff !important}html.theme--catppuccin-frappe .button.is-dark.is-outlined,html.theme--catppuccin-frappe .content kbd.button.is-outlined{background-color:transparent;border-color:#414559;color:#414559}html.theme--catppuccin-frappe .button.is-dark.is-outlined:hover,html.theme--catppuccin-frappe .content kbd.button.is-outlined:hover,html.theme--catppuccin-frappe .button.is-dark.is-outlined.is-hovered,html.theme--catppuccin-frappe .content kbd.button.is-outlined.is-hovered,html.theme--catppuccin-frappe .button.is-dark.is-outlined:focus,html.theme--catppuccin-frappe .content kbd.button.is-outlined:focus,html.theme--catppuccin-frappe .button.is-dark.is-outlined.is-focused,html.theme--catppuccin-frappe .content kbd.button.is-outlined.is-focused{background-color:#414559;border-color:#414559;color:#fff}html.theme--catppuccin-frappe .button.is-dark.is-outlined.is-loading::after,html.theme--catppuccin-frappe .content kbd.button.is-outlined.is-loading::after{border-color:transparent transparent #414559 #414559 !important}html.theme--catppuccin-frappe .button.is-dark.is-outlined.is-loading:hover::after,html.theme--catppuccin-frappe .content kbd.button.is-outlined.is-loading:hover::after,html.theme--catppuccin-frappe .button.is-dark.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-frappe .content kbd.button.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-frappe .button.is-dark.is-outlined.is-loading:focus::after,html.theme--catppuccin-frappe .content kbd.button.is-outlined.is-loading:focus::after,html.theme--catppuccin-frappe .button.is-dark.is-outlined.is-loading.is-focused::after,html.theme--catppuccin-frappe .content kbd.button.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #fff #fff !important}html.theme--catppuccin-frappe .button.is-dark.is-outlined[disabled],html.theme--catppuccin-frappe .content kbd.button.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-frappe .button.is-dark.is-outlined,fieldset[disabled] html.theme--catppuccin-frappe .content kbd.button.is-outlined{background-color:transparent;border-color:#414559;box-shadow:none;color:#414559}html.theme--catppuccin-frappe .button.is-dark.is-inverted.is-outlined,html.theme--catppuccin-frappe .content kbd.button.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}html.theme--catppuccin-frappe .button.is-dark.is-inverted.is-outlined:hover,html.theme--catppuccin-frappe .content kbd.button.is-inverted.is-outlined:hover,html.theme--catppuccin-frappe .button.is-dark.is-inverted.is-outlined.is-hovered,html.theme--catppuccin-frappe .content kbd.button.is-inverted.is-outlined.is-hovered,html.theme--catppuccin-frappe .button.is-dark.is-inverted.is-outlined:focus,html.theme--catppuccin-frappe .content kbd.button.is-inverted.is-outlined:focus,html.theme--catppuccin-frappe .button.is-dark.is-inverted.is-outlined.is-focused,html.theme--catppuccin-frappe .content kbd.button.is-inverted.is-outlined.is-focused{background-color:#fff;color:#414559}html.theme--catppuccin-frappe .button.is-dark.is-inverted.is-outlined.is-loading:hover::after,html.theme--catppuccin-frappe .content kbd.button.is-inverted.is-outlined.is-loading:hover::after,html.theme--catppuccin-frappe .button.is-dark.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-frappe .content kbd.button.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-frappe .button.is-dark.is-inverted.is-outlined.is-loading:focus::after,html.theme--catppuccin-frappe .content kbd.button.is-inverted.is-outlined.is-loading:focus::after,html.theme--catppuccin-frappe .button.is-dark.is-inverted.is-outlined.is-loading.is-focused::after,html.theme--catppuccin-frappe .content kbd.button.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #414559 #414559 !important}html.theme--catppuccin-frappe .button.is-dark.is-inverted.is-outlined[disabled],html.theme--catppuccin-frappe .content kbd.button.is-inverted.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-frappe .button.is-dark.is-inverted.is-outlined,fieldset[disabled] html.theme--catppuccin-frappe .content kbd.button.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}html.theme--catppuccin-frappe .button.is-primary,html.theme--catppuccin-frappe .docstring>section>a.button.docs-sourcelink{background-color:#8caaee;border-color:transparent;color:#fff}html.theme--catppuccin-frappe .button.is-primary:hover,html.theme--catppuccin-frappe .docstring>section>a.button.docs-sourcelink:hover,html.theme--catppuccin-frappe .button.is-primary.is-hovered,html.theme--catppuccin-frappe .docstring>section>a.button.is-hovered.docs-sourcelink{background-color:#81a2ec;border-color:transparent;color:#fff}html.theme--catppuccin-frappe .button.is-primary:focus,html.theme--catppuccin-frappe .docstring>section>a.button.docs-sourcelink:focus,html.theme--catppuccin-frappe .button.is-primary.is-focused,html.theme--catppuccin-frappe .docstring>section>a.button.is-focused.docs-sourcelink{border-color:transparent;color:#fff}html.theme--catppuccin-frappe .button.is-primary:focus:not(:active),html.theme--catppuccin-frappe .docstring>section>a.button.docs-sourcelink:focus:not(:active),html.theme--catppuccin-frappe .button.is-primary.is-focused:not(:active),html.theme--catppuccin-frappe .docstring>section>a.button.is-focused.docs-sourcelink:not(:active){box-shadow:0 0 0 0.125em rgba(140,170,238,0.25)}html.theme--catppuccin-frappe .button.is-primary:active,html.theme--catppuccin-frappe .docstring>section>a.button.docs-sourcelink:active,html.theme--catppuccin-frappe .button.is-primary.is-active,html.theme--catppuccin-frappe .docstring>section>a.button.is-active.docs-sourcelink{background-color:#769aeb;border-color:transparent;color:#fff}html.theme--catppuccin-frappe .button.is-primary[disabled],html.theme--catppuccin-frappe .docstring>section>a.button.docs-sourcelink[disabled],fieldset[disabled] html.theme--catppuccin-frappe .button.is-primary,fieldset[disabled] html.theme--catppuccin-frappe .docstring>section>a.button.docs-sourcelink{background-color:#8caaee;border-color:#8caaee;box-shadow:none}html.theme--catppuccin-frappe .button.is-primary.is-inverted,html.theme--catppuccin-frappe .docstring>section>a.button.is-inverted.docs-sourcelink{background-color:#fff;color:#8caaee}html.theme--catppuccin-frappe .button.is-primary.is-inverted:hover,html.theme--catppuccin-frappe .docstring>section>a.button.is-inverted.docs-sourcelink:hover,html.theme--catppuccin-frappe .button.is-primary.is-inverted.is-hovered,html.theme--catppuccin-frappe .docstring>section>a.button.is-inverted.is-hovered.docs-sourcelink{background-color:#f2f2f2}html.theme--catppuccin-frappe .button.is-primary.is-inverted[disabled],html.theme--catppuccin-frappe .docstring>section>a.button.is-inverted.docs-sourcelink[disabled],fieldset[disabled] html.theme--catppuccin-frappe .button.is-primary.is-inverted,fieldset[disabled] html.theme--catppuccin-frappe .docstring>section>a.button.is-inverted.docs-sourcelink{background-color:#fff;border-color:transparent;box-shadow:none;color:#8caaee}html.theme--catppuccin-frappe .button.is-primary.is-loading::after,html.theme--catppuccin-frappe .docstring>section>a.button.is-loading.docs-sourcelink::after{border-color:transparent transparent #fff #fff !important}html.theme--catppuccin-frappe .button.is-primary.is-outlined,html.theme--catppuccin-frappe .docstring>section>a.button.is-outlined.docs-sourcelink{background-color:transparent;border-color:#8caaee;color:#8caaee}html.theme--catppuccin-frappe .button.is-primary.is-outlined:hover,html.theme--catppuccin-frappe .docstring>section>a.button.is-outlined.docs-sourcelink:hover,html.theme--catppuccin-frappe .button.is-primary.is-outlined.is-hovered,html.theme--catppuccin-frappe .docstring>section>a.button.is-outlined.is-hovered.docs-sourcelink,html.theme--catppuccin-frappe .button.is-primary.is-outlined:focus,html.theme--catppuccin-frappe .docstring>section>a.button.is-outlined.docs-sourcelink:focus,html.theme--catppuccin-frappe .button.is-primary.is-outlined.is-focused,html.theme--catppuccin-frappe .docstring>section>a.button.is-outlined.is-focused.docs-sourcelink{background-color:#8caaee;border-color:#8caaee;color:#fff}html.theme--catppuccin-frappe .button.is-primary.is-outlined.is-loading::after,html.theme--catppuccin-frappe .docstring>section>a.button.is-outlined.is-loading.docs-sourcelink::after{border-color:transparent transparent #8caaee #8caaee !important}html.theme--catppuccin-frappe .button.is-primary.is-outlined.is-loading:hover::after,html.theme--catppuccin-frappe .docstring>section>a.button.is-outlined.is-loading.docs-sourcelink:hover::after,html.theme--catppuccin-frappe .button.is-primary.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-frappe .docstring>section>a.button.is-outlined.is-loading.is-hovered.docs-sourcelink::after,html.theme--catppuccin-frappe .button.is-primary.is-outlined.is-loading:focus::after,html.theme--catppuccin-frappe .docstring>section>a.button.is-outlined.is-loading.docs-sourcelink:focus::after,html.theme--catppuccin-frappe .button.is-primary.is-outlined.is-loading.is-focused::after,html.theme--catppuccin-frappe .docstring>section>a.button.is-outlined.is-loading.is-focused.docs-sourcelink::after{border-color:transparent transparent #fff #fff !important}html.theme--catppuccin-frappe .button.is-primary.is-outlined[disabled],html.theme--catppuccin-frappe .docstring>section>a.button.is-outlined.docs-sourcelink[disabled],fieldset[disabled] html.theme--catppuccin-frappe .button.is-primary.is-outlined,fieldset[disabled] html.theme--catppuccin-frappe .docstring>section>a.button.is-outlined.docs-sourcelink{background-color:transparent;border-color:#8caaee;box-shadow:none;color:#8caaee}html.theme--catppuccin-frappe .button.is-primary.is-inverted.is-outlined,html.theme--catppuccin-frappe .docstring>section>a.button.is-inverted.is-outlined.docs-sourcelink{background-color:transparent;border-color:#fff;color:#fff}html.theme--catppuccin-frappe .button.is-primary.is-inverted.is-outlined:hover,html.theme--catppuccin-frappe .docstring>section>a.button.is-inverted.is-outlined.docs-sourcelink:hover,html.theme--catppuccin-frappe .button.is-primary.is-inverted.is-outlined.is-hovered,html.theme--catppuccin-frappe .docstring>section>a.button.is-inverted.is-outlined.is-hovered.docs-sourcelink,html.theme--catppuccin-frappe .button.is-primary.is-inverted.is-outlined:focus,html.theme--catppuccin-frappe .docstring>section>a.button.is-inverted.is-outlined.docs-sourcelink:focus,html.theme--catppuccin-frappe .button.is-primary.is-inverted.is-outlined.is-focused,html.theme--catppuccin-frappe .docstring>section>a.button.is-inverted.is-outlined.is-focused.docs-sourcelink{background-color:#fff;color:#8caaee}html.theme--catppuccin-frappe .button.is-primary.is-inverted.is-outlined.is-loading:hover::after,html.theme--catppuccin-frappe .docstring>section>a.button.is-inverted.is-outlined.is-loading.docs-sourcelink:hover::after,html.theme--catppuccin-frappe .button.is-primary.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-frappe .docstring>section>a.button.is-inverted.is-outlined.is-loading.is-hovered.docs-sourcelink::after,html.theme--catppuccin-frappe .button.is-primary.is-inverted.is-outlined.is-loading:focus::after,html.theme--catppuccin-frappe .docstring>section>a.button.is-inverted.is-outlined.is-loading.docs-sourcelink:focus::after,html.theme--catppuccin-frappe .button.is-primary.is-inverted.is-outlined.is-loading.is-focused::after,html.theme--catppuccin-frappe .docstring>section>a.button.is-inverted.is-outlined.is-loading.is-focused.docs-sourcelink::after{border-color:transparent transparent #8caaee #8caaee !important}html.theme--catppuccin-frappe .button.is-primary.is-inverted.is-outlined[disabled],html.theme--catppuccin-frappe .docstring>section>a.button.is-inverted.is-outlined.docs-sourcelink[disabled],fieldset[disabled] html.theme--catppuccin-frappe .button.is-primary.is-inverted.is-outlined,fieldset[disabled] html.theme--catppuccin-frappe .docstring>section>a.button.is-inverted.is-outlined.docs-sourcelink{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}html.theme--catppuccin-frappe .button.is-primary.is-light,html.theme--catppuccin-frappe .docstring>section>a.button.is-light.docs-sourcelink{background-color:#edf2fc;color:#153a8e}html.theme--catppuccin-frappe .button.is-primary.is-light:hover,html.theme--catppuccin-frappe .docstring>section>a.button.is-light.docs-sourcelink:hover,html.theme--catppuccin-frappe .button.is-primary.is-light.is-hovered,html.theme--catppuccin-frappe .docstring>section>a.button.is-light.is-hovered.docs-sourcelink{background-color:#e2eafb;border-color:transparent;color:#153a8e}html.theme--catppuccin-frappe .button.is-primary.is-light:active,html.theme--catppuccin-frappe .docstring>section>a.button.is-light.docs-sourcelink:active,html.theme--catppuccin-frappe .button.is-primary.is-light.is-active,html.theme--catppuccin-frappe .docstring>section>a.button.is-light.is-active.docs-sourcelink{background-color:#d7e1f9;border-color:transparent;color:#153a8e}html.theme--catppuccin-frappe .button.is-link{background-color:#8caaee;border-color:transparent;color:#fff}html.theme--catppuccin-frappe .button.is-link:hover,html.theme--catppuccin-frappe .button.is-link.is-hovered{background-color:#81a2ec;border-color:transparent;color:#fff}html.theme--catppuccin-frappe .button.is-link:focus,html.theme--catppuccin-frappe .button.is-link.is-focused{border-color:transparent;color:#fff}html.theme--catppuccin-frappe .button.is-link:focus:not(:active),html.theme--catppuccin-frappe .button.is-link.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(140,170,238,0.25)}html.theme--catppuccin-frappe .button.is-link:active,html.theme--catppuccin-frappe .button.is-link.is-active{background-color:#769aeb;border-color:transparent;color:#fff}html.theme--catppuccin-frappe .button.is-link[disabled],fieldset[disabled] html.theme--catppuccin-frappe .button.is-link{background-color:#8caaee;border-color:#8caaee;box-shadow:none}html.theme--catppuccin-frappe .button.is-link.is-inverted{background-color:#fff;color:#8caaee}html.theme--catppuccin-frappe .button.is-link.is-inverted:hover,html.theme--catppuccin-frappe .button.is-link.is-inverted.is-hovered{background-color:#f2f2f2}html.theme--catppuccin-frappe .button.is-link.is-inverted[disabled],fieldset[disabled] html.theme--catppuccin-frappe .button.is-link.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#8caaee}html.theme--catppuccin-frappe .button.is-link.is-loading::after{border-color:transparent transparent #fff #fff !important}html.theme--catppuccin-frappe .button.is-link.is-outlined{background-color:transparent;border-color:#8caaee;color:#8caaee}html.theme--catppuccin-frappe .button.is-link.is-outlined:hover,html.theme--catppuccin-frappe .button.is-link.is-outlined.is-hovered,html.theme--catppuccin-frappe .button.is-link.is-outlined:focus,html.theme--catppuccin-frappe .button.is-link.is-outlined.is-focused{background-color:#8caaee;border-color:#8caaee;color:#fff}html.theme--catppuccin-frappe .button.is-link.is-outlined.is-loading::after{border-color:transparent transparent #8caaee #8caaee !important}html.theme--catppuccin-frappe .button.is-link.is-outlined.is-loading:hover::after,html.theme--catppuccin-frappe .button.is-link.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-frappe .button.is-link.is-outlined.is-loading:focus::after,html.theme--catppuccin-frappe .button.is-link.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #fff #fff !important}html.theme--catppuccin-frappe .button.is-link.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-frappe .button.is-link.is-outlined{background-color:transparent;border-color:#8caaee;box-shadow:none;color:#8caaee}html.theme--catppuccin-frappe .button.is-link.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}html.theme--catppuccin-frappe .button.is-link.is-inverted.is-outlined:hover,html.theme--catppuccin-frappe .button.is-link.is-inverted.is-outlined.is-hovered,html.theme--catppuccin-frappe .button.is-link.is-inverted.is-outlined:focus,html.theme--catppuccin-frappe .button.is-link.is-inverted.is-outlined.is-focused{background-color:#fff;color:#8caaee}html.theme--catppuccin-frappe .button.is-link.is-inverted.is-outlined.is-loading:hover::after,html.theme--catppuccin-frappe .button.is-link.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-frappe .button.is-link.is-inverted.is-outlined.is-loading:focus::after,html.theme--catppuccin-frappe .button.is-link.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #8caaee #8caaee !important}html.theme--catppuccin-frappe .button.is-link.is-inverted.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-frappe .button.is-link.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}html.theme--catppuccin-frappe .button.is-link.is-light{background-color:#edf2fc;color:#153a8e}html.theme--catppuccin-frappe .button.is-link.is-light:hover,html.theme--catppuccin-frappe .button.is-link.is-light.is-hovered{background-color:#e2eafb;border-color:transparent;color:#153a8e}html.theme--catppuccin-frappe .button.is-link.is-light:active,html.theme--catppuccin-frappe .button.is-link.is-light.is-active{background-color:#d7e1f9;border-color:transparent;color:#153a8e}html.theme--catppuccin-frappe .button.is-info{background-color:#81c8be;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .button.is-info:hover,html.theme--catppuccin-frappe .button.is-info.is-hovered{background-color:#78c4b9;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .button.is-info:focus,html.theme--catppuccin-frappe .button.is-info.is-focused{border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .button.is-info:focus:not(:active),html.theme--catppuccin-frappe .button.is-info.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(129,200,190,0.25)}html.theme--catppuccin-frappe .button.is-info:active,html.theme--catppuccin-frappe .button.is-info.is-active{background-color:#6fc0b5;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .button.is-info[disabled],fieldset[disabled] html.theme--catppuccin-frappe .button.is-info{background-color:#81c8be;border-color:#81c8be;box-shadow:none}html.theme--catppuccin-frappe .button.is-info.is-inverted{background-color:rgba(0,0,0,0.7);color:#81c8be}html.theme--catppuccin-frappe .button.is-info.is-inverted:hover,html.theme--catppuccin-frappe .button.is-info.is-inverted.is-hovered{background-color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .button.is-info.is-inverted[disabled],fieldset[disabled] html.theme--catppuccin-frappe .button.is-info.is-inverted{background-color:rgba(0,0,0,0.7);border-color:transparent;box-shadow:none;color:#81c8be}html.theme--catppuccin-frappe .button.is-info.is-loading::after{border-color:transparent transparent rgba(0,0,0,0.7) rgba(0,0,0,0.7) !important}html.theme--catppuccin-frappe .button.is-info.is-outlined{background-color:transparent;border-color:#81c8be;color:#81c8be}html.theme--catppuccin-frappe .button.is-info.is-outlined:hover,html.theme--catppuccin-frappe .button.is-info.is-outlined.is-hovered,html.theme--catppuccin-frappe .button.is-info.is-outlined:focus,html.theme--catppuccin-frappe .button.is-info.is-outlined.is-focused{background-color:#81c8be;border-color:#81c8be;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .button.is-info.is-outlined.is-loading::after{border-color:transparent transparent #81c8be #81c8be !important}html.theme--catppuccin-frappe .button.is-info.is-outlined.is-loading:hover::after,html.theme--catppuccin-frappe .button.is-info.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-frappe .button.is-info.is-outlined.is-loading:focus::after,html.theme--catppuccin-frappe .button.is-info.is-outlined.is-loading.is-focused::after{border-color:transparent transparent rgba(0,0,0,0.7) rgba(0,0,0,0.7) !important}html.theme--catppuccin-frappe .button.is-info.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-frappe .button.is-info.is-outlined{background-color:transparent;border-color:#81c8be;box-shadow:none;color:#81c8be}html.theme--catppuccin-frappe .button.is-info.is-inverted.is-outlined{background-color:transparent;border-color:rgba(0,0,0,0.7);color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .button.is-info.is-inverted.is-outlined:hover,html.theme--catppuccin-frappe .button.is-info.is-inverted.is-outlined.is-hovered,html.theme--catppuccin-frappe .button.is-info.is-inverted.is-outlined:focus,html.theme--catppuccin-frappe .button.is-info.is-inverted.is-outlined.is-focused{background-color:rgba(0,0,0,0.7);color:#81c8be}html.theme--catppuccin-frappe .button.is-info.is-inverted.is-outlined.is-loading:hover::after,html.theme--catppuccin-frappe .button.is-info.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-frappe .button.is-info.is-inverted.is-outlined.is-loading:focus::after,html.theme--catppuccin-frappe .button.is-info.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #81c8be #81c8be !important}html.theme--catppuccin-frappe .button.is-info.is-inverted.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-frappe .button.is-info.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)}html.theme--catppuccin-frappe .button.is-info.is-light{background-color:#f1f9f8;color:#2d675f}html.theme--catppuccin-frappe .button.is-info.is-light:hover,html.theme--catppuccin-frappe .button.is-info.is-light.is-hovered{background-color:#e8f5f3;border-color:transparent;color:#2d675f}html.theme--catppuccin-frappe .button.is-info.is-light:active,html.theme--catppuccin-frappe .button.is-info.is-light.is-active{background-color:#dff1ef;border-color:transparent;color:#2d675f}html.theme--catppuccin-frappe .button.is-success{background-color:#a6d189;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .button.is-success:hover,html.theme--catppuccin-frappe .button.is-success.is-hovered{background-color:#9fcd80;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .button.is-success:focus,html.theme--catppuccin-frappe .button.is-success.is-focused{border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .button.is-success:focus:not(:active),html.theme--catppuccin-frappe .button.is-success.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(166,209,137,0.25)}html.theme--catppuccin-frappe .button.is-success:active,html.theme--catppuccin-frappe .button.is-success.is-active{background-color:#98ca77;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .button.is-success[disabled],fieldset[disabled] html.theme--catppuccin-frappe .button.is-success{background-color:#a6d189;border-color:#a6d189;box-shadow:none}html.theme--catppuccin-frappe .button.is-success.is-inverted{background-color:rgba(0,0,0,0.7);color:#a6d189}html.theme--catppuccin-frappe .button.is-success.is-inverted:hover,html.theme--catppuccin-frappe .button.is-success.is-inverted.is-hovered{background-color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .button.is-success.is-inverted[disabled],fieldset[disabled] html.theme--catppuccin-frappe .button.is-success.is-inverted{background-color:rgba(0,0,0,0.7);border-color:transparent;box-shadow:none;color:#a6d189}html.theme--catppuccin-frappe .button.is-success.is-loading::after{border-color:transparent transparent rgba(0,0,0,0.7) rgba(0,0,0,0.7) !important}html.theme--catppuccin-frappe .button.is-success.is-outlined{background-color:transparent;border-color:#a6d189;color:#a6d189}html.theme--catppuccin-frappe .button.is-success.is-outlined:hover,html.theme--catppuccin-frappe .button.is-success.is-outlined.is-hovered,html.theme--catppuccin-frappe .button.is-success.is-outlined:focus,html.theme--catppuccin-frappe .button.is-success.is-outlined.is-focused{background-color:#a6d189;border-color:#a6d189;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .button.is-success.is-outlined.is-loading::after{border-color:transparent transparent #a6d189 #a6d189 !important}html.theme--catppuccin-frappe .button.is-success.is-outlined.is-loading:hover::after,html.theme--catppuccin-frappe .button.is-success.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-frappe .button.is-success.is-outlined.is-loading:focus::after,html.theme--catppuccin-frappe .button.is-success.is-outlined.is-loading.is-focused::after{border-color:transparent transparent rgba(0,0,0,0.7) rgba(0,0,0,0.7) !important}html.theme--catppuccin-frappe .button.is-success.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-frappe .button.is-success.is-outlined{background-color:transparent;border-color:#a6d189;box-shadow:none;color:#a6d189}html.theme--catppuccin-frappe .button.is-success.is-inverted.is-outlined{background-color:transparent;border-color:rgba(0,0,0,0.7);color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .button.is-success.is-inverted.is-outlined:hover,html.theme--catppuccin-frappe .button.is-success.is-inverted.is-outlined.is-hovered,html.theme--catppuccin-frappe .button.is-success.is-inverted.is-outlined:focus,html.theme--catppuccin-frappe .button.is-success.is-inverted.is-outlined.is-focused{background-color:rgba(0,0,0,0.7);color:#a6d189}html.theme--catppuccin-frappe .button.is-success.is-inverted.is-outlined.is-loading:hover::after,html.theme--catppuccin-frappe .button.is-success.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-frappe .button.is-success.is-inverted.is-outlined.is-loading:focus::after,html.theme--catppuccin-frappe .button.is-success.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #a6d189 #a6d189 !important}html.theme--catppuccin-frappe .button.is-success.is-inverted.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-frappe .button.is-success.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)}html.theme--catppuccin-frappe .button.is-success.is-light{background-color:#f4f9f0;color:#446a29}html.theme--catppuccin-frappe .button.is-success.is-light:hover,html.theme--catppuccin-frappe .button.is-success.is-light.is-hovered{background-color:#edf6e7;border-color:transparent;color:#446a29}html.theme--catppuccin-frappe .button.is-success.is-light:active,html.theme--catppuccin-frappe .button.is-success.is-light.is-active{background-color:#e6f2de;border-color:transparent;color:#446a29}html.theme--catppuccin-frappe .button.is-warning{background-color:#e5c890;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .button.is-warning:hover,html.theme--catppuccin-frappe .button.is-warning.is-hovered{background-color:#e3c386;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .button.is-warning:focus,html.theme--catppuccin-frappe .button.is-warning.is-focused{border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .button.is-warning:focus:not(:active),html.theme--catppuccin-frappe .button.is-warning.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(229,200,144,0.25)}html.theme--catppuccin-frappe .button.is-warning:active,html.theme--catppuccin-frappe .button.is-warning.is-active{background-color:#e0be7b;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .button.is-warning[disabled],fieldset[disabled] html.theme--catppuccin-frappe .button.is-warning{background-color:#e5c890;border-color:#e5c890;box-shadow:none}html.theme--catppuccin-frappe .button.is-warning.is-inverted{background-color:rgba(0,0,0,0.7);color:#e5c890}html.theme--catppuccin-frappe .button.is-warning.is-inverted:hover,html.theme--catppuccin-frappe .button.is-warning.is-inverted.is-hovered{background-color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .button.is-warning.is-inverted[disabled],fieldset[disabled] html.theme--catppuccin-frappe .button.is-warning.is-inverted{background-color:rgba(0,0,0,0.7);border-color:transparent;box-shadow:none;color:#e5c890}html.theme--catppuccin-frappe .button.is-warning.is-loading::after{border-color:transparent transparent rgba(0,0,0,0.7) rgba(0,0,0,0.7) !important}html.theme--catppuccin-frappe .button.is-warning.is-outlined{background-color:transparent;border-color:#e5c890;color:#e5c890}html.theme--catppuccin-frappe .button.is-warning.is-outlined:hover,html.theme--catppuccin-frappe .button.is-warning.is-outlined.is-hovered,html.theme--catppuccin-frappe .button.is-warning.is-outlined:focus,html.theme--catppuccin-frappe .button.is-warning.is-outlined.is-focused{background-color:#e5c890;border-color:#e5c890;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .button.is-warning.is-outlined.is-loading::after{border-color:transparent transparent #e5c890 #e5c890 !important}html.theme--catppuccin-frappe .button.is-warning.is-outlined.is-loading:hover::after,html.theme--catppuccin-frappe .button.is-warning.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-frappe .button.is-warning.is-outlined.is-loading:focus::after,html.theme--catppuccin-frappe .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}html.theme--catppuccin-frappe .button.is-warning.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-frappe .button.is-warning.is-outlined{background-color:transparent;border-color:#e5c890;box-shadow:none;color:#e5c890}html.theme--catppuccin-frappe .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)}html.theme--catppuccin-frappe .button.is-warning.is-inverted.is-outlined:hover,html.theme--catppuccin-frappe .button.is-warning.is-inverted.is-outlined.is-hovered,html.theme--catppuccin-frappe .button.is-warning.is-inverted.is-outlined:focus,html.theme--catppuccin-frappe .button.is-warning.is-inverted.is-outlined.is-focused{background-color:rgba(0,0,0,0.7);color:#e5c890}html.theme--catppuccin-frappe .button.is-warning.is-inverted.is-outlined.is-loading:hover::after,html.theme--catppuccin-frappe .button.is-warning.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-frappe .button.is-warning.is-inverted.is-outlined.is-loading:focus::after,html.theme--catppuccin-frappe .button.is-warning.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #e5c890 #e5c890 !important}html.theme--catppuccin-frappe .button.is-warning.is-inverted.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-frappe .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)}html.theme--catppuccin-frappe .button.is-warning.is-light{background-color:#fbf7ee;color:#78591c}html.theme--catppuccin-frappe .button.is-warning.is-light:hover,html.theme--catppuccin-frappe .button.is-warning.is-light.is-hovered{background-color:#f9f2e4;border-color:transparent;color:#78591c}html.theme--catppuccin-frappe .button.is-warning.is-light:active,html.theme--catppuccin-frappe .button.is-warning.is-light.is-active{background-color:#f6edda;border-color:transparent;color:#78591c}html.theme--catppuccin-frappe .button.is-danger{background-color:#e78284;border-color:transparent;color:#fff}html.theme--catppuccin-frappe .button.is-danger:hover,html.theme--catppuccin-frappe .button.is-danger.is-hovered{background-color:#e57779;border-color:transparent;color:#fff}html.theme--catppuccin-frappe .button.is-danger:focus,html.theme--catppuccin-frappe .button.is-danger.is-focused{border-color:transparent;color:#fff}html.theme--catppuccin-frappe .button.is-danger:focus:not(:active),html.theme--catppuccin-frappe .button.is-danger.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(231,130,132,0.25)}html.theme--catppuccin-frappe .button.is-danger:active,html.theme--catppuccin-frappe .button.is-danger.is-active{background-color:#e36d6f;border-color:transparent;color:#fff}html.theme--catppuccin-frappe .button.is-danger[disabled],fieldset[disabled] html.theme--catppuccin-frappe .button.is-danger{background-color:#e78284;border-color:#e78284;box-shadow:none}html.theme--catppuccin-frappe .button.is-danger.is-inverted{background-color:#fff;color:#e78284}html.theme--catppuccin-frappe .button.is-danger.is-inverted:hover,html.theme--catppuccin-frappe .button.is-danger.is-inverted.is-hovered{background-color:#f2f2f2}html.theme--catppuccin-frappe .button.is-danger.is-inverted[disabled],fieldset[disabled] html.theme--catppuccin-frappe .button.is-danger.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#e78284}html.theme--catppuccin-frappe .button.is-danger.is-loading::after{border-color:transparent transparent #fff #fff !important}html.theme--catppuccin-frappe .button.is-danger.is-outlined{background-color:transparent;border-color:#e78284;color:#e78284}html.theme--catppuccin-frappe .button.is-danger.is-outlined:hover,html.theme--catppuccin-frappe .button.is-danger.is-outlined.is-hovered,html.theme--catppuccin-frappe .button.is-danger.is-outlined:focus,html.theme--catppuccin-frappe .button.is-danger.is-outlined.is-focused{background-color:#e78284;border-color:#e78284;color:#fff}html.theme--catppuccin-frappe .button.is-danger.is-outlined.is-loading::after{border-color:transparent transparent #e78284 #e78284 !important}html.theme--catppuccin-frappe .button.is-danger.is-outlined.is-loading:hover::after,html.theme--catppuccin-frappe .button.is-danger.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-frappe .button.is-danger.is-outlined.is-loading:focus::after,html.theme--catppuccin-frappe .button.is-danger.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #fff #fff !important}html.theme--catppuccin-frappe .button.is-danger.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-frappe .button.is-danger.is-outlined{background-color:transparent;border-color:#e78284;box-shadow:none;color:#e78284}html.theme--catppuccin-frappe .button.is-danger.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}html.theme--catppuccin-frappe .button.is-danger.is-inverted.is-outlined:hover,html.theme--catppuccin-frappe .button.is-danger.is-inverted.is-outlined.is-hovered,html.theme--catppuccin-frappe .button.is-danger.is-inverted.is-outlined:focus,html.theme--catppuccin-frappe .button.is-danger.is-inverted.is-outlined.is-focused{background-color:#fff;color:#e78284}html.theme--catppuccin-frappe .button.is-danger.is-inverted.is-outlined.is-loading:hover::after,html.theme--catppuccin-frappe .button.is-danger.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-frappe .button.is-danger.is-inverted.is-outlined.is-loading:focus::after,html.theme--catppuccin-frappe .button.is-danger.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #e78284 #e78284 !important}html.theme--catppuccin-frappe .button.is-danger.is-inverted.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-frappe .button.is-danger.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}html.theme--catppuccin-frappe .button.is-danger.is-light{background-color:#fceeee;color:#9a1e20}html.theme--catppuccin-frappe .button.is-danger.is-light:hover,html.theme--catppuccin-frappe .button.is-danger.is-light.is-hovered{background-color:#fae3e4;border-color:transparent;color:#9a1e20}html.theme--catppuccin-frappe .button.is-danger.is-light:active,html.theme--catppuccin-frappe .button.is-danger.is-light.is-active{background-color:#f8d8d9;border-color:transparent;color:#9a1e20}html.theme--catppuccin-frappe .button.is-small,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.button{font-size:.75rem}html.theme--catppuccin-frappe .button.is-small:not(.is-rounded),html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.button:not(.is-rounded){border-radius:3px}html.theme--catppuccin-frappe .button.is-normal{font-size:1rem}html.theme--catppuccin-frappe .button.is-medium{font-size:1.25rem}html.theme--catppuccin-frappe .button.is-large{font-size:1.5rem}html.theme--catppuccin-frappe .button[disabled],fieldset[disabled] html.theme--catppuccin-frappe .button{background-color:#737994;border-color:#626880;box-shadow:none;opacity:.5}html.theme--catppuccin-frappe .button.is-fullwidth{display:flex;width:100%}html.theme--catppuccin-frappe .button.is-loading{color:transparent !important;pointer-events:none}html.theme--catppuccin-frappe .button.is-loading::after{position:absolute;left:calc(50% - (1em * 0.5));top:calc(50% - (1em * 0.5));position:absolute !important}html.theme--catppuccin-frappe .button.is-static{background-color:#292c3c;border-color:#626880;color:#838ba7;box-shadow:none;pointer-events:none}html.theme--catppuccin-frappe .button.is-rounded,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.button{border-radius:9999px;padding-left:calc(1em + 0.25em);padding-right:calc(1em + 0.25em)}html.theme--catppuccin-frappe .buttons{align-items:center;display:flex;flex-wrap:wrap;justify-content:flex-start}html.theme--catppuccin-frappe .buttons .button{margin-bottom:0.5rem}html.theme--catppuccin-frappe .buttons .button:not(:last-child):not(.is-fullwidth){margin-right:.5rem}html.theme--catppuccin-frappe .buttons:last-child{margin-bottom:-0.5rem}html.theme--catppuccin-frappe .buttons:not(:last-child){margin-bottom:1rem}html.theme--catppuccin-frappe .buttons.are-small .button:not(.is-normal):not(.is-medium):not(.is-large){font-size:.75rem}html.theme--catppuccin-frappe .buttons.are-small .button:not(.is-normal):not(.is-medium):not(.is-large):not(.is-rounded){border-radius:3px}html.theme--catppuccin-frappe .buttons.are-medium .button:not(.is-small):not(.is-normal):not(.is-large){font-size:1.25rem}html.theme--catppuccin-frappe .buttons.are-large .button:not(.is-small):not(.is-normal):not(.is-medium){font-size:1.5rem}html.theme--catppuccin-frappe .buttons.has-addons .button:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}html.theme--catppuccin-frappe .buttons.has-addons .button:not(:last-child){border-bottom-right-radius:0;border-top-right-radius:0;margin-right:-1px}html.theme--catppuccin-frappe .buttons.has-addons .button:last-child{margin-right:0}html.theme--catppuccin-frappe .buttons.has-addons .button:hover,html.theme--catppuccin-frappe .buttons.has-addons .button.is-hovered{z-index:2}html.theme--catppuccin-frappe .buttons.has-addons .button:focus,html.theme--catppuccin-frappe .buttons.has-addons .button.is-focused,html.theme--catppuccin-frappe .buttons.has-addons .button:active,html.theme--catppuccin-frappe .buttons.has-addons .button.is-active,html.theme--catppuccin-frappe .buttons.has-addons .button.is-selected{z-index:3}html.theme--catppuccin-frappe .buttons.has-addons .button:focus:hover,html.theme--catppuccin-frappe .buttons.has-addons .button.is-focused:hover,html.theme--catppuccin-frappe .buttons.has-addons .button:active:hover,html.theme--catppuccin-frappe .buttons.has-addons .button.is-active:hover,html.theme--catppuccin-frappe .buttons.has-addons .button.is-selected:hover{z-index:4}html.theme--catppuccin-frappe .buttons.has-addons .button.is-expanded{flex-grow:1;flex-shrink:1}html.theme--catppuccin-frappe .buttons.is-centered{justify-content:center}html.theme--catppuccin-frappe .buttons.is-centered:not(.has-addons) .button:not(.is-fullwidth){margin-left:0.25rem;margin-right:0.25rem}html.theme--catppuccin-frappe .buttons.is-right{justify-content:flex-end}html.theme--catppuccin-frappe .buttons.is-right:not(.has-addons) .button:not(.is-fullwidth){margin-left:0.25rem;margin-right:0.25rem}@media screen and (max-width: 768px){html.theme--catppuccin-frappe .button.is-responsive.is-small,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-responsive{font-size:.5625rem}html.theme--catppuccin-frappe .button.is-responsive,html.theme--catppuccin-frappe .button.is-responsive.is-normal{font-size:.65625rem}html.theme--catppuccin-frappe .button.is-responsive.is-medium{font-size:.75rem}html.theme--catppuccin-frappe .button.is-responsive.is-large{font-size:1rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--catppuccin-frappe .button.is-responsive.is-small,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-responsive{font-size:.65625rem}html.theme--catppuccin-frappe .button.is-responsive,html.theme--catppuccin-frappe .button.is-responsive.is-normal{font-size:.75rem}html.theme--catppuccin-frappe .button.is-responsive.is-medium{font-size:1rem}html.theme--catppuccin-frappe .button.is-responsive.is-large{font-size:1.25rem}}html.theme--catppuccin-frappe .container{flex-grow:1;margin:0 auto;position:relative;width:auto}html.theme--catppuccin-frappe .container.is-fluid{max-width:none !important;padding-left:32px;padding-right:32px;width:100%}@media screen and (min-width: 1056px){html.theme--catppuccin-frappe .container{max-width:992px}}@media screen and (max-width: 1215px){html.theme--catppuccin-frappe .container.is-widescreen:not(.is-max-desktop){max-width:1152px}}@media screen and (max-width: 1407px){html.theme--catppuccin-frappe .container.is-fullhd:not(.is-max-desktop):not(.is-max-widescreen){max-width:1344px}}@media screen and (min-width: 1216px){html.theme--catppuccin-frappe .container:not(.is-max-desktop){max-width:1152px}}@media screen and (min-width: 1408px){html.theme--catppuccin-frappe .container:not(.is-max-desktop):not(.is-max-widescreen){max-width:1344px}}html.theme--catppuccin-frappe .content li+li{margin-top:0.25em}html.theme--catppuccin-frappe .content p:not(:last-child),html.theme--catppuccin-frappe .content dl:not(:last-child),html.theme--catppuccin-frappe .content ol:not(:last-child),html.theme--catppuccin-frappe .content ul:not(:last-child),html.theme--catppuccin-frappe .content blockquote:not(:last-child),html.theme--catppuccin-frappe .content pre:not(:last-child),html.theme--catppuccin-frappe .content table:not(:last-child){margin-bottom:1em}html.theme--catppuccin-frappe .content h1,html.theme--catppuccin-frappe .content h2,html.theme--catppuccin-frappe .content h3,html.theme--catppuccin-frappe .content h4,html.theme--catppuccin-frappe .content h5,html.theme--catppuccin-frappe .content h6{color:#c6d0f5;font-weight:600;line-height:1.125}html.theme--catppuccin-frappe .content h1{font-size:2em;margin-bottom:0.5em}html.theme--catppuccin-frappe .content h1:not(:first-child){margin-top:1em}html.theme--catppuccin-frappe .content h2{font-size:1.75em;margin-bottom:0.5714em}html.theme--catppuccin-frappe .content h2:not(:first-child){margin-top:1.1428em}html.theme--catppuccin-frappe .content h3{font-size:1.5em;margin-bottom:0.6666em}html.theme--catppuccin-frappe .content h3:not(:first-child){margin-top:1.3333em}html.theme--catppuccin-frappe .content h4{font-size:1.25em;margin-bottom:0.8em}html.theme--catppuccin-frappe .content h5{font-size:1.125em;margin-bottom:0.8888em}html.theme--catppuccin-frappe .content h6{font-size:1em;margin-bottom:1em}html.theme--catppuccin-frappe .content blockquote{background-color:#292c3c;border-left:5px solid #626880;padding:1.25em 1.5em}html.theme--catppuccin-frappe .content ol{list-style-position:outside;margin-left:2em;margin-top:1em}html.theme--catppuccin-frappe .content ol:not([type]){list-style-type:decimal}html.theme--catppuccin-frappe .content ol.is-lower-alpha:not([type]){list-style-type:lower-alpha}html.theme--catppuccin-frappe .content ol.is-lower-roman:not([type]){list-style-type:lower-roman}html.theme--catppuccin-frappe .content ol.is-upper-alpha:not([type]){list-style-type:upper-alpha}html.theme--catppuccin-frappe .content ol.is-upper-roman:not([type]){list-style-type:upper-roman}html.theme--catppuccin-frappe .content ul{list-style:disc outside;margin-left:2em;margin-top:1em}html.theme--catppuccin-frappe .content ul ul{list-style-type:circle;margin-top:0.5em}html.theme--catppuccin-frappe .content ul ul ul{list-style-type:square}html.theme--catppuccin-frappe .content dd{margin-left:2em}html.theme--catppuccin-frappe .content figure{margin-left:2em;margin-right:2em;text-align:center}html.theme--catppuccin-frappe .content figure:not(:first-child){margin-top:2em}html.theme--catppuccin-frappe .content figure:not(:last-child){margin-bottom:2em}html.theme--catppuccin-frappe .content figure img{display:inline-block}html.theme--catppuccin-frappe .content figure figcaption{font-style:italic}html.theme--catppuccin-frappe .content pre{-webkit-overflow-scrolling:touch;overflow-x:auto;padding:0;white-space:pre;word-wrap:normal}html.theme--catppuccin-frappe .content sup,html.theme--catppuccin-frappe .content sub{font-size:75%}html.theme--catppuccin-frappe .content table{width:100%}html.theme--catppuccin-frappe .content table td,html.theme--catppuccin-frappe .content table th{border:1px solid #626880;border-width:0 0 1px;padding:0.5em 0.75em;vertical-align:top}html.theme--catppuccin-frappe .content table th{color:#b0bef1}html.theme--catppuccin-frappe .content table th:not([align]){text-align:inherit}html.theme--catppuccin-frappe .content table thead td,html.theme--catppuccin-frappe .content table thead th{border-width:0 0 2px;color:#b0bef1}html.theme--catppuccin-frappe .content table tfoot td,html.theme--catppuccin-frappe .content table tfoot th{border-width:2px 0 0;color:#b0bef1}html.theme--catppuccin-frappe .content table tbody tr:last-child td,html.theme--catppuccin-frappe .content table tbody tr:last-child th{border-bottom-width:0}html.theme--catppuccin-frappe .content .tabs li+li{margin-top:0}html.theme--catppuccin-frappe .content.is-small,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.content{font-size:.75rem}html.theme--catppuccin-frappe .content.is-normal{font-size:1rem}html.theme--catppuccin-frappe .content.is-medium{font-size:1.25rem}html.theme--catppuccin-frappe .content.is-large{font-size:1.5rem}html.theme--catppuccin-frappe .icon{align-items:center;display:inline-flex;justify-content:center;height:1.5rem;width:1.5rem}html.theme--catppuccin-frappe .icon.is-small,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.icon{height:1rem;width:1rem}html.theme--catppuccin-frappe .icon.is-medium{height:2rem;width:2rem}html.theme--catppuccin-frappe .icon.is-large{height:3rem;width:3rem}html.theme--catppuccin-frappe .icon-text{align-items:flex-start;color:inherit;display:inline-flex;flex-wrap:wrap;line-height:1.5rem;vertical-align:top}html.theme--catppuccin-frappe .icon-text .icon{flex-grow:0;flex-shrink:0}html.theme--catppuccin-frappe .icon-text .icon:not(:last-child){margin-right:.25em}html.theme--catppuccin-frappe .icon-text .icon:not(:first-child){margin-left:.25em}html.theme--catppuccin-frappe div.icon-text{display:flex}html.theme--catppuccin-frappe .image,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img{display:block;position:relative}html.theme--catppuccin-frappe .image img,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img img{display:block;height:auto;width:100%}html.theme--catppuccin-frappe .image img.is-rounded,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img img.is-rounded{border-radius:9999px}html.theme--catppuccin-frappe .image.is-fullwidth,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-fullwidth{width:100%}html.theme--catppuccin-frappe .image.is-square img,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-square img,html.theme--catppuccin-frappe .image.is-square .has-ratio,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-square .has-ratio,html.theme--catppuccin-frappe .image.is-1by1 img,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-1by1 img,html.theme--catppuccin-frappe .image.is-1by1 .has-ratio,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-1by1 .has-ratio,html.theme--catppuccin-frappe .image.is-5by4 img,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-5by4 img,html.theme--catppuccin-frappe .image.is-5by4 .has-ratio,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-5by4 .has-ratio,html.theme--catppuccin-frappe .image.is-4by3 img,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-4by3 img,html.theme--catppuccin-frappe .image.is-4by3 .has-ratio,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-4by3 .has-ratio,html.theme--catppuccin-frappe .image.is-3by2 img,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-3by2 img,html.theme--catppuccin-frappe .image.is-3by2 .has-ratio,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-3by2 .has-ratio,html.theme--catppuccin-frappe .image.is-5by3 img,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-5by3 img,html.theme--catppuccin-frappe .image.is-5by3 .has-ratio,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-5by3 .has-ratio,html.theme--catppuccin-frappe .image.is-16by9 img,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-16by9 img,html.theme--catppuccin-frappe .image.is-16by9 .has-ratio,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-16by9 .has-ratio,html.theme--catppuccin-frappe .image.is-2by1 img,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-2by1 img,html.theme--catppuccin-frappe .image.is-2by1 .has-ratio,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-2by1 .has-ratio,html.theme--catppuccin-frappe .image.is-3by1 img,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-3by1 img,html.theme--catppuccin-frappe .image.is-3by1 .has-ratio,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-3by1 .has-ratio,html.theme--catppuccin-frappe .image.is-4by5 img,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-4by5 img,html.theme--catppuccin-frappe .image.is-4by5 .has-ratio,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-4by5 .has-ratio,html.theme--catppuccin-frappe .image.is-3by4 img,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-3by4 img,html.theme--catppuccin-frappe .image.is-3by4 .has-ratio,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-3by4 .has-ratio,html.theme--catppuccin-frappe .image.is-2by3 img,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-2by3 img,html.theme--catppuccin-frappe .image.is-2by3 .has-ratio,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-2by3 .has-ratio,html.theme--catppuccin-frappe .image.is-3by5 img,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-3by5 img,html.theme--catppuccin-frappe .image.is-3by5 .has-ratio,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-3by5 .has-ratio,html.theme--catppuccin-frappe .image.is-9by16 img,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-9by16 img,html.theme--catppuccin-frappe .image.is-9by16 .has-ratio,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-9by16 .has-ratio,html.theme--catppuccin-frappe .image.is-1by2 img,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-1by2 img,html.theme--catppuccin-frappe .image.is-1by2 .has-ratio,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-1by2 .has-ratio,html.theme--catppuccin-frappe .image.is-1by3 img,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-1by3 img,html.theme--catppuccin-frappe .image.is-1by3 .has-ratio,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-1by3 .has-ratio{height:100%;width:100%}html.theme--catppuccin-frappe .image.is-square,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-square,html.theme--catppuccin-frappe .image.is-1by1,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-1by1{padding-top:100%}html.theme--catppuccin-frappe .image.is-5by4,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-5by4{padding-top:80%}html.theme--catppuccin-frappe .image.is-4by3,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-4by3{padding-top:75%}html.theme--catppuccin-frappe .image.is-3by2,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-3by2{padding-top:66.6666%}html.theme--catppuccin-frappe .image.is-5by3,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-5by3{padding-top:60%}html.theme--catppuccin-frappe .image.is-16by9,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-16by9{padding-top:56.25%}html.theme--catppuccin-frappe .image.is-2by1,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-2by1{padding-top:50%}html.theme--catppuccin-frappe .image.is-3by1,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-3by1{padding-top:33.3333%}html.theme--catppuccin-frappe .image.is-4by5,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-4by5{padding-top:125%}html.theme--catppuccin-frappe .image.is-3by4,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-3by4{padding-top:133.3333%}html.theme--catppuccin-frappe .image.is-2by3,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-2by3{padding-top:150%}html.theme--catppuccin-frappe .image.is-3by5,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-3by5{padding-top:166.6666%}html.theme--catppuccin-frappe .image.is-9by16,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-9by16{padding-top:177.7777%}html.theme--catppuccin-frappe .image.is-1by2,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-1by2{padding-top:200%}html.theme--catppuccin-frappe .image.is-1by3,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-1by3{padding-top:300%}html.theme--catppuccin-frappe .image.is-16x16,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-16x16{height:16px;width:16px}html.theme--catppuccin-frappe .image.is-24x24,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-24x24{height:24px;width:24px}html.theme--catppuccin-frappe .image.is-32x32,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-32x32{height:32px;width:32px}html.theme--catppuccin-frappe .image.is-48x48,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-48x48{height:48px;width:48px}html.theme--catppuccin-frappe .image.is-64x64,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-64x64{height:64px;width:64px}html.theme--catppuccin-frappe .image.is-96x96,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-96x96{height:96px;width:96px}html.theme--catppuccin-frappe .image.is-128x128,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-128x128{height:128px;width:128px}html.theme--catppuccin-frappe .notification{background-color:#292c3c;border-radius:.4em;position:relative;padding:1.25rem 2.5rem 1.25rem 1.5rem}html.theme--catppuccin-frappe .notification a:not(.button):not(.dropdown-item){color:currentColor;text-decoration:underline}html.theme--catppuccin-frappe .notification strong{color:currentColor}html.theme--catppuccin-frappe .notification code,html.theme--catppuccin-frappe .notification pre{background:#fff}html.theme--catppuccin-frappe .notification pre code{background:transparent}html.theme--catppuccin-frappe .notification>.delete{right:.5rem;position:absolute;top:0.5rem}html.theme--catppuccin-frappe .notification .title,html.theme--catppuccin-frappe .notification .subtitle,html.theme--catppuccin-frappe .notification .content{color:currentColor}html.theme--catppuccin-frappe .notification.is-white{background-color:#fff;color:#0a0a0a}html.theme--catppuccin-frappe .notification.is-black{background-color:#0a0a0a;color:#fff}html.theme--catppuccin-frappe .notification.is-light{background-color:#f5f5f5;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .notification.is-dark,html.theme--catppuccin-frappe .content kbd.notification{background-color:#414559;color:#fff}html.theme--catppuccin-frappe .notification.is-primary,html.theme--catppuccin-frappe .docstring>section>a.notification.docs-sourcelink{background-color:#8caaee;color:#fff}html.theme--catppuccin-frappe .notification.is-primary.is-light,html.theme--catppuccin-frappe .docstring>section>a.notification.is-light.docs-sourcelink{background-color:#edf2fc;color:#153a8e}html.theme--catppuccin-frappe .notification.is-link{background-color:#8caaee;color:#fff}html.theme--catppuccin-frappe .notification.is-link.is-light{background-color:#edf2fc;color:#153a8e}html.theme--catppuccin-frappe .notification.is-info{background-color:#81c8be;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .notification.is-info.is-light{background-color:#f1f9f8;color:#2d675f}html.theme--catppuccin-frappe .notification.is-success{background-color:#a6d189;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .notification.is-success.is-light{background-color:#f4f9f0;color:#446a29}html.theme--catppuccin-frappe .notification.is-warning{background-color:#e5c890;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .notification.is-warning.is-light{background-color:#fbf7ee;color:#78591c}html.theme--catppuccin-frappe .notification.is-danger{background-color:#e78284;color:#fff}html.theme--catppuccin-frappe .notification.is-danger.is-light{background-color:#fceeee;color:#9a1e20}html.theme--catppuccin-frappe .progress{-moz-appearance:none;-webkit-appearance:none;border:none;border-radius:9999px;display:block;height:1rem;overflow:hidden;padding:0;width:100%}html.theme--catppuccin-frappe .progress::-webkit-progress-bar{background-color:#51576d}html.theme--catppuccin-frappe .progress::-webkit-progress-value{background-color:#838ba7}html.theme--catppuccin-frappe .progress::-moz-progress-bar{background-color:#838ba7}html.theme--catppuccin-frappe .progress::-ms-fill{background-color:#838ba7;border:none}html.theme--catppuccin-frappe .progress.is-white::-webkit-progress-value{background-color:#fff}html.theme--catppuccin-frappe .progress.is-white::-moz-progress-bar{background-color:#fff}html.theme--catppuccin-frappe .progress.is-white::-ms-fill{background-color:#fff}html.theme--catppuccin-frappe .progress.is-white:indeterminate{background-image:linear-gradient(to right, #fff 30%, #51576d 30%)}html.theme--catppuccin-frappe .progress.is-black::-webkit-progress-value{background-color:#0a0a0a}html.theme--catppuccin-frappe .progress.is-black::-moz-progress-bar{background-color:#0a0a0a}html.theme--catppuccin-frappe .progress.is-black::-ms-fill{background-color:#0a0a0a}html.theme--catppuccin-frappe .progress.is-black:indeterminate{background-image:linear-gradient(to right, #0a0a0a 30%, #51576d 30%)}html.theme--catppuccin-frappe .progress.is-light::-webkit-progress-value{background-color:#f5f5f5}html.theme--catppuccin-frappe .progress.is-light::-moz-progress-bar{background-color:#f5f5f5}html.theme--catppuccin-frappe .progress.is-light::-ms-fill{background-color:#f5f5f5}html.theme--catppuccin-frappe .progress.is-light:indeterminate{background-image:linear-gradient(to right, #f5f5f5 30%, #51576d 30%)}html.theme--catppuccin-frappe .progress.is-dark::-webkit-progress-value,html.theme--catppuccin-frappe .content kbd.progress::-webkit-progress-value{background-color:#414559}html.theme--catppuccin-frappe .progress.is-dark::-moz-progress-bar,html.theme--catppuccin-frappe .content kbd.progress::-moz-progress-bar{background-color:#414559}html.theme--catppuccin-frappe .progress.is-dark::-ms-fill,html.theme--catppuccin-frappe .content kbd.progress::-ms-fill{background-color:#414559}html.theme--catppuccin-frappe .progress.is-dark:indeterminate,html.theme--catppuccin-frappe .content kbd.progress:indeterminate{background-image:linear-gradient(to right, #414559 30%, #51576d 30%)}html.theme--catppuccin-frappe .progress.is-primary::-webkit-progress-value,html.theme--catppuccin-frappe .docstring>section>a.progress.docs-sourcelink::-webkit-progress-value{background-color:#8caaee}html.theme--catppuccin-frappe .progress.is-primary::-moz-progress-bar,html.theme--catppuccin-frappe .docstring>section>a.progress.docs-sourcelink::-moz-progress-bar{background-color:#8caaee}html.theme--catppuccin-frappe .progress.is-primary::-ms-fill,html.theme--catppuccin-frappe .docstring>section>a.progress.docs-sourcelink::-ms-fill{background-color:#8caaee}html.theme--catppuccin-frappe .progress.is-primary:indeterminate,html.theme--catppuccin-frappe .docstring>section>a.progress.docs-sourcelink:indeterminate{background-image:linear-gradient(to right, #8caaee 30%, #51576d 30%)}html.theme--catppuccin-frappe .progress.is-link::-webkit-progress-value{background-color:#8caaee}html.theme--catppuccin-frappe .progress.is-link::-moz-progress-bar{background-color:#8caaee}html.theme--catppuccin-frappe .progress.is-link::-ms-fill{background-color:#8caaee}html.theme--catppuccin-frappe .progress.is-link:indeterminate{background-image:linear-gradient(to right, #8caaee 30%, #51576d 30%)}html.theme--catppuccin-frappe .progress.is-info::-webkit-progress-value{background-color:#81c8be}html.theme--catppuccin-frappe .progress.is-info::-moz-progress-bar{background-color:#81c8be}html.theme--catppuccin-frappe .progress.is-info::-ms-fill{background-color:#81c8be}html.theme--catppuccin-frappe .progress.is-info:indeterminate{background-image:linear-gradient(to right, #81c8be 30%, #51576d 30%)}html.theme--catppuccin-frappe .progress.is-success::-webkit-progress-value{background-color:#a6d189}html.theme--catppuccin-frappe .progress.is-success::-moz-progress-bar{background-color:#a6d189}html.theme--catppuccin-frappe .progress.is-success::-ms-fill{background-color:#a6d189}html.theme--catppuccin-frappe .progress.is-success:indeterminate{background-image:linear-gradient(to right, #a6d189 30%, #51576d 30%)}html.theme--catppuccin-frappe .progress.is-warning::-webkit-progress-value{background-color:#e5c890}html.theme--catppuccin-frappe .progress.is-warning::-moz-progress-bar{background-color:#e5c890}html.theme--catppuccin-frappe .progress.is-warning::-ms-fill{background-color:#e5c890}html.theme--catppuccin-frappe .progress.is-warning:indeterminate{background-image:linear-gradient(to right, #e5c890 30%, #51576d 30%)}html.theme--catppuccin-frappe .progress.is-danger::-webkit-progress-value{background-color:#e78284}html.theme--catppuccin-frappe .progress.is-danger::-moz-progress-bar{background-color:#e78284}html.theme--catppuccin-frappe .progress.is-danger::-ms-fill{background-color:#e78284}html.theme--catppuccin-frappe .progress.is-danger:indeterminate{background-image:linear-gradient(to right, #e78284 30%, #51576d 30%)}html.theme--catppuccin-frappe .progress:indeterminate{animation-duration:1.5s;animation-iteration-count:infinite;animation-name:moveIndeterminate;animation-timing-function:linear;background-color:#51576d;background-image:linear-gradient(to right, #c6d0f5 30%, #51576d 30%);background-position:top left;background-repeat:no-repeat;background-size:150% 150%}html.theme--catppuccin-frappe .progress:indeterminate::-webkit-progress-bar{background-color:transparent}html.theme--catppuccin-frappe .progress:indeterminate::-moz-progress-bar{background-color:transparent}html.theme--catppuccin-frappe .progress:indeterminate::-ms-fill{animation-name:none}html.theme--catppuccin-frappe .progress.is-small,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.progress{height:.75rem}html.theme--catppuccin-frappe .progress.is-medium{height:1.25rem}html.theme--catppuccin-frappe .progress.is-large{height:1.5rem}@keyframes moveIndeterminate{from{background-position:200% 0}to{background-position:-200% 0}}html.theme--catppuccin-frappe .table{background-color:#51576d;color:#c6d0f5}html.theme--catppuccin-frappe .table td,html.theme--catppuccin-frappe .table th{border:1px solid #626880;border-width:0 0 1px;padding:0.5em 0.75em;vertical-align:top}html.theme--catppuccin-frappe .table td.is-white,html.theme--catppuccin-frappe .table th.is-white{background-color:#fff;border-color:#fff;color:#0a0a0a}html.theme--catppuccin-frappe .table td.is-black,html.theme--catppuccin-frappe .table th.is-black{background-color:#0a0a0a;border-color:#0a0a0a;color:#fff}html.theme--catppuccin-frappe .table td.is-light,html.theme--catppuccin-frappe .table th.is-light{background-color:#f5f5f5;border-color:#f5f5f5;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .table td.is-dark,html.theme--catppuccin-frappe .table th.is-dark{background-color:#414559;border-color:#414559;color:#fff}html.theme--catppuccin-frappe .table td.is-primary,html.theme--catppuccin-frappe .table th.is-primary{background-color:#8caaee;border-color:#8caaee;color:#fff}html.theme--catppuccin-frappe .table td.is-link,html.theme--catppuccin-frappe .table th.is-link{background-color:#8caaee;border-color:#8caaee;color:#fff}html.theme--catppuccin-frappe .table td.is-info,html.theme--catppuccin-frappe .table th.is-info{background-color:#81c8be;border-color:#81c8be;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .table td.is-success,html.theme--catppuccin-frappe .table th.is-success{background-color:#a6d189;border-color:#a6d189;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .table td.is-warning,html.theme--catppuccin-frappe .table th.is-warning{background-color:#e5c890;border-color:#e5c890;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .table td.is-danger,html.theme--catppuccin-frappe .table th.is-danger{background-color:#e78284;border-color:#e78284;color:#fff}html.theme--catppuccin-frappe .table td.is-narrow,html.theme--catppuccin-frappe .table th.is-narrow{white-space:nowrap;width:1%}html.theme--catppuccin-frappe .table td.is-selected,html.theme--catppuccin-frappe .table th.is-selected{background-color:#8caaee;color:#fff}html.theme--catppuccin-frappe .table td.is-selected a,html.theme--catppuccin-frappe .table td.is-selected strong,html.theme--catppuccin-frappe .table th.is-selected a,html.theme--catppuccin-frappe .table th.is-selected strong{color:currentColor}html.theme--catppuccin-frappe .table td.is-vcentered,html.theme--catppuccin-frappe .table th.is-vcentered{vertical-align:middle}html.theme--catppuccin-frappe .table th{color:#b0bef1}html.theme--catppuccin-frappe .table th:not([align]){text-align:left}html.theme--catppuccin-frappe .table tr.is-selected{background-color:#8caaee;color:#fff}html.theme--catppuccin-frappe .table tr.is-selected a,html.theme--catppuccin-frappe .table tr.is-selected strong{color:currentColor}html.theme--catppuccin-frappe .table tr.is-selected td,html.theme--catppuccin-frappe .table tr.is-selected th{border-color:#fff;color:currentColor}html.theme--catppuccin-frappe .table thead{background-color:rgba(0,0,0,0)}html.theme--catppuccin-frappe .table thead td,html.theme--catppuccin-frappe .table thead th{border-width:0 0 2px;color:#b0bef1}html.theme--catppuccin-frappe .table tfoot{background-color:rgba(0,0,0,0)}html.theme--catppuccin-frappe .table tfoot td,html.theme--catppuccin-frappe .table tfoot th{border-width:2px 0 0;color:#b0bef1}html.theme--catppuccin-frappe .table tbody{background-color:rgba(0,0,0,0)}html.theme--catppuccin-frappe .table tbody tr:last-child td,html.theme--catppuccin-frappe .table tbody tr:last-child th{border-bottom-width:0}html.theme--catppuccin-frappe .table.is-bordered td,html.theme--catppuccin-frappe .table.is-bordered th{border-width:1px}html.theme--catppuccin-frappe .table.is-bordered tr:last-child td,html.theme--catppuccin-frappe .table.is-bordered tr:last-child th{border-bottom-width:1px}html.theme--catppuccin-frappe .table.is-fullwidth{width:100%}html.theme--catppuccin-frappe .table.is-hoverable tbody tr:not(.is-selected):hover{background-color:#414559}html.theme--catppuccin-frappe .table.is-hoverable.is-striped tbody tr:not(.is-selected):hover{background-color:#414559}html.theme--catppuccin-frappe .table.is-hoverable.is-striped tbody tr:not(.is-selected):hover:nth-child(even){background-color:#454a5f}html.theme--catppuccin-frappe .table.is-narrow td,html.theme--catppuccin-frappe .table.is-narrow th{padding:0.25em 0.5em}html.theme--catppuccin-frappe .table.is-striped tbody tr:not(.is-selected):nth-child(even){background-color:#414559}html.theme--catppuccin-frappe .table-container{-webkit-overflow-scrolling:touch;overflow:auto;overflow-y:hidden;max-width:100%}html.theme--catppuccin-frappe .tags{align-items:center;display:flex;flex-wrap:wrap;justify-content:flex-start}html.theme--catppuccin-frappe .tags .tag,html.theme--catppuccin-frappe .tags .content kbd,html.theme--catppuccin-frappe .content .tags kbd,html.theme--catppuccin-frappe .tags .docstring>section>a.docs-sourcelink{margin-bottom:0.5rem}html.theme--catppuccin-frappe .tags .tag:not(:last-child),html.theme--catppuccin-frappe .tags .content kbd:not(:last-child),html.theme--catppuccin-frappe .content .tags kbd:not(:last-child),html.theme--catppuccin-frappe .tags .docstring>section>a.docs-sourcelink:not(:last-child){margin-right:.5rem}html.theme--catppuccin-frappe .tags:last-child{margin-bottom:-0.5rem}html.theme--catppuccin-frappe .tags:not(:last-child){margin-bottom:1rem}html.theme--catppuccin-frappe .tags.are-medium .tag:not(.is-normal):not(.is-large),html.theme--catppuccin-frappe .tags.are-medium .content kbd:not(.is-normal):not(.is-large),html.theme--catppuccin-frappe .content .tags.are-medium kbd:not(.is-normal):not(.is-large),html.theme--catppuccin-frappe .tags.are-medium .docstring>section>a.docs-sourcelink:not(.is-normal):not(.is-large){font-size:1rem}html.theme--catppuccin-frappe .tags.are-large .tag:not(.is-normal):not(.is-medium),html.theme--catppuccin-frappe .tags.are-large .content kbd:not(.is-normal):not(.is-medium),html.theme--catppuccin-frappe .content .tags.are-large kbd:not(.is-normal):not(.is-medium),html.theme--catppuccin-frappe .tags.are-large .docstring>section>a.docs-sourcelink:not(.is-normal):not(.is-medium){font-size:1.25rem}html.theme--catppuccin-frappe .tags.is-centered{justify-content:center}html.theme--catppuccin-frappe .tags.is-centered .tag,html.theme--catppuccin-frappe .tags.is-centered .content kbd,html.theme--catppuccin-frappe .content .tags.is-centered kbd,html.theme--catppuccin-frappe .tags.is-centered .docstring>section>a.docs-sourcelink{margin-right:0.25rem;margin-left:0.25rem}html.theme--catppuccin-frappe .tags.is-right{justify-content:flex-end}html.theme--catppuccin-frappe .tags.is-right .tag:not(:first-child),html.theme--catppuccin-frappe .tags.is-right .content kbd:not(:first-child),html.theme--catppuccin-frappe .content .tags.is-right kbd:not(:first-child),html.theme--catppuccin-frappe .tags.is-right .docstring>section>a.docs-sourcelink:not(:first-child){margin-left:0.5rem}html.theme--catppuccin-frappe .tags.is-right .tag:not(:last-child),html.theme--catppuccin-frappe .tags.is-right .content kbd:not(:last-child),html.theme--catppuccin-frappe .content .tags.is-right kbd:not(:last-child),html.theme--catppuccin-frappe .tags.is-right .docstring>section>a.docs-sourcelink:not(:last-child){margin-right:0}html.theme--catppuccin-frappe .tags.has-addons .tag,html.theme--catppuccin-frappe .tags.has-addons .content kbd,html.theme--catppuccin-frappe .content .tags.has-addons kbd,html.theme--catppuccin-frappe .tags.has-addons .docstring>section>a.docs-sourcelink{margin-right:0}html.theme--catppuccin-frappe .tags.has-addons .tag:not(:first-child),html.theme--catppuccin-frappe .tags.has-addons .content kbd:not(:first-child),html.theme--catppuccin-frappe .content .tags.has-addons kbd:not(:first-child),html.theme--catppuccin-frappe .tags.has-addons .docstring>section>a.docs-sourcelink:not(:first-child){margin-left:0;border-top-left-radius:0;border-bottom-left-radius:0}html.theme--catppuccin-frappe .tags.has-addons .tag:not(:last-child),html.theme--catppuccin-frappe .tags.has-addons .content kbd:not(:last-child),html.theme--catppuccin-frappe .content .tags.has-addons kbd:not(:last-child),html.theme--catppuccin-frappe .tags.has-addons .docstring>section>a.docs-sourcelink:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}html.theme--catppuccin-frappe .tag:not(body),html.theme--catppuccin-frappe .content kbd:not(body),html.theme--catppuccin-frappe .docstring>section>a.docs-sourcelink:not(body){align-items:center;background-color:#292c3c;border-radius:.4em;color:#c6d0f5;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}html.theme--catppuccin-frappe .tag:not(body) .delete,html.theme--catppuccin-frappe .content kbd:not(body) .delete,html.theme--catppuccin-frappe .docstring>section>a.docs-sourcelink:not(body) .delete{margin-left:.25rem;margin-right:-.375rem}html.theme--catppuccin-frappe .tag.is-white:not(body),html.theme--catppuccin-frappe .content kbd.is-white:not(body),html.theme--catppuccin-frappe .docstring>section>a.docs-sourcelink.is-white:not(body){background-color:#fff;color:#0a0a0a}html.theme--catppuccin-frappe .tag.is-black:not(body),html.theme--catppuccin-frappe .content kbd.is-black:not(body),html.theme--catppuccin-frappe .docstring>section>a.docs-sourcelink.is-black:not(body){background-color:#0a0a0a;color:#fff}html.theme--catppuccin-frappe .tag.is-light:not(body),html.theme--catppuccin-frappe .content kbd.is-light:not(body),html.theme--catppuccin-frappe .docstring>section>a.docs-sourcelink.is-light:not(body){background-color:#f5f5f5;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .tag.is-dark:not(body),html.theme--catppuccin-frappe .content kbd:not(body),html.theme--catppuccin-frappe .docstring>section>a.docs-sourcelink.is-dark:not(body),html.theme--catppuccin-frappe .content .docstring>section>kbd:not(body){background-color:#414559;color:#fff}html.theme--catppuccin-frappe .tag.is-primary:not(body),html.theme--catppuccin-frappe .content kbd.is-primary:not(body),html.theme--catppuccin-frappe .docstring>section>a.docs-sourcelink:not(body){background-color:#8caaee;color:#fff}html.theme--catppuccin-frappe .tag.is-primary.is-light:not(body),html.theme--catppuccin-frappe .content kbd.is-primary.is-light:not(body),html.theme--catppuccin-frappe .docstring>section>a.docs-sourcelink.is-light:not(body){background-color:#edf2fc;color:#153a8e}html.theme--catppuccin-frappe .tag.is-link:not(body),html.theme--catppuccin-frappe .content kbd.is-link:not(body),html.theme--catppuccin-frappe .docstring>section>a.docs-sourcelink.is-link:not(body){background-color:#8caaee;color:#fff}html.theme--catppuccin-frappe .tag.is-link.is-light:not(body),html.theme--catppuccin-frappe .content kbd.is-link.is-light:not(body),html.theme--catppuccin-frappe .docstring>section>a.docs-sourcelink.is-link.is-light:not(body){background-color:#edf2fc;color:#153a8e}html.theme--catppuccin-frappe .tag.is-info:not(body),html.theme--catppuccin-frappe .content kbd.is-info:not(body),html.theme--catppuccin-frappe .docstring>section>a.docs-sourcelink.is-info:not(body){background-color:#81c8be;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .tag.is-info.is-light:not(body),html.theme--catppuccin-frappe .content kbd.is-info.is-light:not(body),html.theme--catppuccin-frappe .docstring>section>a.docs-sourcelink.is-info.is-light:not(body){background-color:#f1f9f8;color:#2d675f}html.theme--catppuccin-frappe .tag.is-success:not(body),html.theme--catppuccin-frappe .content kbd.is-success:not(body),html.theme--catppuccin-frappe .docstring>section>a.docs-sourcelink.is-success:not(body){background-color:#a6d189;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .tag.is-success.is-light:not(body),html.theme--catppuccin-frappe .content kbd.is-success.is-light:not(body),html.theme--catppuccin-frappe .docstring>section>a.docs-sourcelink.is-success.is-light:not(body){background-color:#f4f9f0;color:#446a29}html.theme--catppuccin-frappe .tag.is-warning:not(body),html.theme--catppuccin-frappe .content kbd.is-warning:not(body),html.theme--catppuccin-frappe .docstring>section>a.docs-sourcelink.is-warning:not(body){background-color:#e5c890;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .tag.is-warning.is-light:not(body),html.theme--catppuccin-frappe .content kbd.is-warning.is-light:not(body),html.theme--catppuccin-frappe .docstring>section>a.docs-sourcelink.is-warning.is-light:not(body){background-color:#fbf7ee;color:#78591c}html.theme--catppuccin-frappe .tag.is-danger:not(body),html.theme--catppuccin-frappe .content kbd.is-danger:not(body),html.theme--catppuccin-frappe .docstring>section>a.docs-sourcelink.is-danger:not(body){background-color:#e78284;color:#fff}html.theme--catppuccin-frappe .tag.is-danger.is-light:not(body),html.theme--catppuccin-frappe .content kbd.is-danger.is-light:not(body),html.theme--catppuccin-frappe .docstring>section>a.docs-sourcelink.is-danger.is-light:not(body){background-color:#fceeee;color:#9a1e20}html.theme--catppuccin-frappe .tag.is-normal:not(body),html.theme--catppuccin-frappe .content kbd.is-normal:not(body),html.theme--catppuccin-frappe .docstring>section>a.docs-sourcelink.is-normal:not(body){font-size:.75rem}html.theme--catppuccin-frappe .tag.is-medium:not(body),html.theme--catppuccin-frappe .content kbd.is-medium:not(body),html.theme--catppuccin-frappe .docstring>section>a.docs-sourcelink.is-medium:not(body){font-size:1rem}html.theme--catppuccin-frappe .tag.is-large:not(body),html.theme--catppuccin-frappe .content kbd.is-large:not(body),html.theme--catppuccin-frappe .docstring>section>a.docs-sourcelink.is-large:not(body){font-size:1.25rem}html.theme--catppuccin-frappe .tag:not(body) .icon:first-child:not(:last-child),html.theme--catppuccin-frappe .content kbd:not(body) .icon:first-child:not(:last-child),html.theme--catppuccin-frappe .docstring>section>a.docs-sourcelink:not(body) .icon:first-child:not(:last-child){margin-left:-.375em;margin-right:.1875em}html.theme--catppuccin-frappe .tag:not(body) .icon:last-child:not(:first-child),html.theme--catppuccin-frappe .content kbd:not(body) .icon:last-child:not(:first-child),html.theme--catppuccin-frappe .docstring>section>a.docs-sourcelink:not(body) .icon:last-child:not(:first-child){margin-left:.1875em;margin-right:-.375em}html.theme--catppuccin-frappe .tag:not(body) .icon:first-child:last-child,html.theme--catppuccin-frappe .content kbd:not(body) .icon:first-child:last-child,html.theme--catppuccin-frappe .docstring>section>a.docs-sourcelink:not(body) .icon:first-child:last-child{margin-left:-.375em;margin-right:-.375em}html.theme--catppuccin-frappe .tag.is-delete:not(body),html.theme--catppuccin-frappe .content kbd.is-delete:not(body),html.theme--catppuccin-frappe .docstring>section>a.docs-sourcelink.is-delete:not(body){margin-left:1px;padding:0;position:relative;width:2em}html.theme--catppuccin-frappe .tag.is-delete:not(body)::before,html.theme--catppuccin-frappe .content kbd.is-delete:not(body)::before,html.theme--catppuccin-frappe .docstring>section>a.docs-sourcelink.is-delete:not(body)::before,html.theme--catppuccin-frappe .tag.is-delete:not(body)::after,html.theme--catppuccin-frappe .content kbd.is-delete:not(body)::after,html.theme--catppuccin-frappe .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--catppuccin-frappe .tag.is-delete:not(body)::before,html.theme--catppuccin-frappe .content kbd.is-delete:not(body)::before,html.theme--catppuccin-frappe .docstring>section>a.docs-sourcelink.is-delete:not(body)::before{height:1px;width:50%}html.theme--catppuccin-frappe .tag.is-delete:not(body)::after,html.theme--catppuccin-frappe .content kbd.is-delete:not(body)::after,html.theme--catppuccin-frappe .docstring>section>a.docs-sourcelink.is-delete:not(body)::after{height:50%;width:1px}html.theme--catppuccin-frappe .tag.is-delete:not(body):hover,html.theme--catppuccin-frappe .content kbd.is-delete:not(body):hover,html.theme--catppuccin-frappe .docstring>section>a.docs-sourcelink.is-delete:not(body):hover,html.theme--catppuccin-frappe .tag.is-delete:not(body):focus,html.theme--catppuccin-frappe .content kbd.is-delete:not(body):focus,html.theme--catppuccin-frappe .docstring>section>a.docs-sourcelink.is-delete:not(body):focus{background-color:#1f212d}html.theme--catppuccin-frappe .tag.is-delete:not(body):active,html.theme--catppuccin-frappe .content kbd.is-delete:not(body):active,html.theme--catppuccin-frappe .docstring>section>a.docs-sourcelink.is-delete:not(body):active{background-color:#14161e}html.theme--catppuccin-frappe .tag.is-rounded:not(body),html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input:not(body),html.theme--catppuccin-frappe .content kbd.is-rounded:not(body),html.theme--catppuccin-frappe #documenter .docs-sidebar .content form.docs-search>input:not(body),html.theme--catppuccin-frappe .docstring>section>a.docs-sourcelink.is-rounded:not(body){border-radius:9999px}html.theme--catppuccin-frappe a.tag:hover,html.theme--catppuccin-frappe .docstring>section>a.docs-sourcelink:hover{text-decoration:underline}html.theme--catppuccin-frappe .title,html.theme--catppuccin-frappe .subtitle{word-break:break-word}html.theme--catppuccin-frappe .title em,html.theme--catppuccin-frappe .title span,html.theme--catppuccin-frappe .subtitle em,html.theme--catppuccin-frappe .subtitle span{font-weight:inherit}html.theme--catppuccin-frappe .title sub,html.theme--catppuccin-frappe .subtitle sub{font-size:.75em}html.theme--catppuccin-frappe .title sup,html.theme--catppuccin-frappe .subtitle sup{font-size:.75em}html.theme--catppuccin-frappe .title .tag,html.theme--catppuccin-frappe .title .content kbd,html.theme--catppuccin-frappe .content .title kbd,html.theme--catppuccin-frappe .title .docstring>section>a.docs-sourcelink,html.theme--catppuccin-frappe .subtitle .tag,html.theme--catppuccin-frappe .subtitle .content kbd,html.theme--catppuccin-frappe .content .subtitle kbd,html.theme--catppuccin-frappe .subtitle .docstring>section>a.docs-sourcelink{vertical-align:middle}html.theme--catppuccin-frappe .title{color:#fff;font-size:2rem;font-weight:500;line-height:1.125}html.theme--catppuccin-frappe .title strong{color:inherit;font-weight:inherit}html.theme--catppuccin-frappe .title:not(.is-spaced)+.subtitle{margin-top:-1.25rem}html.theme--catppuccin-frappe .title.is-1{font-size:3rem}html.theme--catppuccin-frappe .title.is-2{font-size:2.5rem}html.theme--catppuccin-frappe .title.is-3{font-size:2rem}html.theme--catppuccin-frappe .title.is-4{font-size:1.5rem}html.theme--catppuccin-frappe .title.is-5{font-size:1.25rem}html.theme--catppuccin-frappe .title.is-6{font-size:1rem}html.theme--catppuccin-frappe .title.is-7{font-size:.75rem}html.theme--catppuccin-frappe .subtitle{color:#737994;font-size:1.25rem;font-weight:400;line-height:1.25}html.theme--catppuccin-frappe .subtitle strong{color:#737994;font-weight:600}html.theme--catppuccin-frappe .subtitle:not(.is-spaced)+.title{margin-top:-1.25rem}html.theme--catppuccin-frappe .subtitle.is-1{font-size:3rem}html.theme--catppuccin-frappe .subtitle.is-2{font-size:2.5rem}html.theme--catppuccin-frappe .subtitle.is-3{font-size:2rem}html.theme--catppuccin-frappe .subtitle.is-4{font-size:1.5rem}html.theme--catppuccin-frappe .subtitle.is-5{font-size:1.25rem}html.theme--catppuccin-frappe .subtitle.is-6{font-size:1rem}html.theme--catppuccin-frappe .subtitle.is-7{font-size:.75rem}html.theme--catppuccin-frappe .heading{display:block;font-size:11px;letter-spacing:1px;margin-bottom:5px;text-transform:uppercase}html.theme--catppuccin-frappe .number{align-items:center;background-color:#292c3c;border-radius:9999px;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--catppuccin-frappe .select select,html.theme--catppuccin-frappe .textarea,html.theme--catppuccin-frappe .input,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input{background-color:#303446;border-color:#626880;border-radius:.4em;color:#838ba7}html.theme--catppuccin-frappe .select select::-moz-placeholder,html.theme--catppuccin-frappe .textarea::-moz-placeholder,html.theme--catppuccin-frappe .input::-moz-placeholder,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input::-moz-placeholder{color:#868c98}html.theme--catppuccin-frappe .select select::-webkit-input-placeholder,html.theme--catppuccin-frappe .textarea::-webkit-input-placeholder,html.theme--catppuccin-frappe .input::-webkit-input-placeholder,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input::-webkit-input-placeholder{color:#868c98}html.theme--catppuccin-frappe .select select:-moz-placeholder,html.theme--catppuccin-frappe .textarea:-moz-placeholder,html.theme--catppuccin-frappe .input:-moz-placeholder,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input:-moz-placeholder{color:#868c98}html.theme--catppuccin-frappe .select select:-ms-input-placeholder,html.theme--catppuccin-frappe .textarea:-ms-input-placeholder,html.theme--catppuccin-frappe .input:-ms-input-placeholder,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input:-ms-input-placeholder{color:#868c98}html.theme--catppuccin-frappe .select select:hover,html.theme--catppuccin-frappe .textarea:hover,html.theme--catppuccin-frappe .input:hover,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input:hover,html.theme--catppuccin-frappe .select select.is-hovered,html.theme--catppuccin-frappe .is-hovered.textarea,html.theme--catppuccin-frappe .is-hovered.input,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-hovered{border-color:#737994}html.theme--catppuccin-frappe .select select:focus,html.theme--catppuccin-frappe .textarea:focus,html.theme--catppuccin-frappe .input:focus,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input:focus,html.theme--catppuccin-frappe .select select.is-focused,html.theme--catppuccin-frappe .is-focused.textarea,html.theme--catppuccin-frappe .is-focused.input,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--catppuccin-frappe .select select:active,html.theme--catppuccin-frappe .textarea:active,html.theme--catppuccin-frappe .input:active,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input:active,html.theme--catppuccin-frappe .select select.is-active,html.theme--catppuccin-frappe .is-active.textarea,html.theme--catppuccin-frappe .is-active.input,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-active{border-color:#8caaee;box-shadow:0 0 0 0.125em rgba(140,170,238,0.25)}html.theme--catppuccin-frappe .select select[disabled],html.theme--catppuccin-frappe .textarea[disabled],html.theme--catppuccin-frappe .input[disabled],html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input[disabled],fieldset[disabled] html.theme--catppuccin-frappe .select select,fieldset[disabled] html.theme--catppuccin-frappe .textarea,fieldset[disabled] html.theme--catppuccin-frappe .input,fieldset[disabled] html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input{background-color:#737994;border-color:#292c3c;box-shadow:none;color:#f1f4fd}html.theme--catppuccin-frappe .select select[disabled]::-moz-placeholder,html.theme--catppuccin-frappe .textarea[disabled]::-moz-placeholder,html.theme--catppuccin-frappe .input[disabled]::-moz-placeholder,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input[disabled]::-moz-placeholder,fieldset[disabled] html.theme--catppuccin-frappe .select select::-moz-placeholder,fieldset[disabled] html.theme--catppuccin-frappe .textarea::-moz-placeholder,fieldset[disabled] html.theme--catppuccin-frappe .input::-moz-placeholder,fieldset[disabled] html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input::-moz-placeholder{color:rgba(241,244,253,0.3)}html.theme--catppuccin-frappe .select select[disabled]::-webkit-input-placeholder,html.theme--catppuccin-frappe .textarea[disabled]::-webkit-input-placeholder,html.theme--catppuccin-frappe .input[disabled]::-webkit-input-placeholder,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input[disabled]::-webkit-input-placeholder,fieldset[disabled] html.theme--catppuccin-frappe .select select::-webkit-input-placeholder,fieldset[disabled] html.theme--catppuccin-frappe .textarea::-webkit-input-placeholder,fieldset[disabled] html.theme--catppuccin-frappe .input::-webkit-input-placeholder,fieldset[disabled] html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input::-webkit-input-placeholder{color:rgba(241,244,253,0.3)}html.theme--catppuccin-frappe .select select[disabled]:-moz-placeholder,html.theme--catppuccin-frappe .textarea[disabled]:-moz-placeholder,html.theme--catppuccin-frappe .input[disabled]:-moz-placeholder,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input[disabled]:-moz-placeholder,fieldset[disabled] html.theme--catppuccin-frappe .select select:-moz-placeholder,fieldset[disabled] html.theme--catppuccin-frappe .textarea:-moz-placeholder,fieldset[disabled] html.theme--catppuccin-frappe .input:-moz-placeholder,fieldset[disabled] html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input:-moz-placeholder{color:rgba(241,244,253,0.3)}html.theme--catppuccin-frappe .select select[disabled]:-ms-input-placeholder,html.theme--catppuccin-frappe .textarea[disabled]:-ms-input-placeholder,html.theme--catppuccin-frappe .input[disabled]:-ms-input-placeholder,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input[disabled]:-ms-input-placeholder,fieldset[disabled] html.theme--catppuccin-frappe .select select:-ms-input-placeholder,fieldset[disabled] html.theme--catppuccin-frappe .textarea:-ms-input-placeholder,fieldset[disabled] html.theme--catppuccin-frappe .input:-ms-input-placeholder,fieldset[disabled] html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input:-ms-input-placeholder{color:rgba(241,244,253,0.3)}html.theme--catppuccin-frappe .textarea,html.theme--catppuccin-frappe .input,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input{box-shadow:inset 0 0.0625em 0.125em rgba(10,10,10,0.05);max-width:100%;width:100%}html.theme--catppuccin-frappe .textarea[readonly],html.theme--catppuccin-frappe .input[readonly],html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input[readonly]{box-shadow:none}html.theme--catppuccin-frappe .is-white.textarea,html.theme--catppuccin-frappe .is-white.input,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-white{border-color:#fff}html.theme--catppuccin-frappe .is-white.textarea:focus,html.theme--catppuccin-frappe .is-white.input:focus,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-white:focus,html.theme--catppuccin-frappe .is-white.is-focused.textarea,html.theme--catppuccin-frappe .is-white.is-focused.input,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--catppuccin-frappe .is-white.textarea:active,html.theme--catppuccin-frappe .is-white.input:active,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-white:active,html.theme--catppuccin-frappe .is-white.is-active.textarea,html.theme--catppuccin-frappe .is-white.is-active.input,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(255,255,255,0.25)}html.theme--catppuccin-frappe .is-black.textarea,html.theme--catppuccin-frappe .is-black.input,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-black{border-color:#0a0a0a}html.theme--catppuccin-frappe .is-black.textarea:focus,html.theme--catppuccin-frappe .is-black.input:focus,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-black:focus,html.theme--catppuccin-frappe .is-black.is-focused.textarea,html.theme--catppuccin-frappe .is-black.is-focused.input,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--catppuccin-frappe .is-black.textarea:active,html.theme--catppuccin-frappe .is-black.input:active,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-black:active,html.theme--catppuccin-frappe .is-black.is-active.textarea,html.theme--catppuccin-frappe .is-black.is-active.input,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(10,10,10,0.25)}html.theme--catppuccin-frappe .is-light.textarea,html.theme--catppuccin-frappe .is-light.input,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-light{border-color:#f5f5f5}html.theme--catppuccin-frappe .is-light.textarea:focus,html.theme--catppuccin-frappe .is-light.input:focus,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-light:focus,html.theme--catppuccin-frappe .is-light.is-focused.textarea,html.theme--catppuccin-frappe .is-light.is-focused.input,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--catppuccin-frappe .is-light.textarea:active,html.theme--catppuccin-frappe .is-light.input:active,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-light:active,html.theme--catppuccin-frappe .is-light.is-active.textarea,html.theme--catppuccin-frappe .is-light.is-active.input,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(245,245,245,0.25)}html.theme--catppuccin-frappe .is-dark.textarea,html.theme--catppuccin-frappe .content kbd.textarea,html.theme--catppuccin-frappe .is-dark.input,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-dark,html.theme--catppuccin-frappe .content kbd.input{border-color:#414559}html.theme--catppuccin-frappe .is-dark.textarea:focus,html.theme--catppuccin-frappe .content kbd.textarea:focus,html.theme--catppuccin-frappe .is-dark.input:focus,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-dark:focus,html.theme--catppuccin-frappe .content kbd.input:focus,html.theme--catppuccin-frappe .is-dark.is-focused.textarea,html.theme--catppuccin-frappe .content kbd.is-focused.textarea,html.theme--catppuccin-frappe .is-dark.is-focused.input,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--catppuccin-frappe .content kbd.is-focused.input,html.theme--catppuccin-frappe #documenter .docs-sidebar .content form.docs-search>input.is-focused,html.theme--catppuccin-frappe .is-dark.textarea:active,html.theme--catppuccin-frappe .content kbd.textarea:active,html.theme--catppuccin-frappe .is-dark.input:active,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-dark:active,html.theme--catppuccin-frappe .content kbd.input:active,html.theme--catppuccin-frappe .is-dark.is-active.textarea,html.theme--catppuccin-frappe .content kbd.is-active.textarea,html.theme--catppuccin-frappe .is-dark.is-active.input,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-active,html.theme--catppuccin-frappe .content kbd.is-active.input,html.theme--catppuccin-frappe #documenter .docs-sidebar .content form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(65,69,89,0.25)}html.theme--catppuccin-frappe .is-primary.textarea,html.theme--catppuccin-frappe .docstring>section>a.textarea.docs-sourcelink,html.theme--catppuccin-frappe .is-primary.input,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-primary,html.theme--catppuccin-frappe .docstring>section>a.input.docs-sourcelink{border-color:#8caaee}html.theme--catppuccin-frappe .is-primary.textarea:focus,html.theme--catppuccin-frappe .docstring>section>a.textarea.docs-sourcelink:focus,html.theme--catppuccin-frappe .is-primary.input:focus,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-primary:focus,html.theme--catppuccin-frappe .docstring>section>a.input.docs-sourcelink:focus,html.theme--catppuccin-frappe .is-primary.is-focused.textarea,html.theme--catppuccin-frappe .docstring>section>a.is-focused.textarea.docs-sourcelink,html.theme--catppuccin-frappe .is-primary.is-focused.input,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--catppuccin-frappe .docstring>section>a.is-focused.input.docs-sourcelink,html.theme--catppuccin-frappe .is-primary.textarea:active,html.theme--catppuccin-frappe .docstring>section>a.textarea.docs-sourcelink:active,html.theme--catppuccin-frappe .is-primary.input:active,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-primary:active,html.theme--catppuccin-frappe .docstring>section>a.input.docs-sourcelink:active,html.theme--catppuccin-frappe .is-primary.is-active.textarea,html.theme--catppuccin-frappe .docstring>section>a.is-active.textarea.docs-sourcelink,html.theme--catppuccin-frappe .is-primary.is-active.input,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-active,html.theme--catppuccin-frappe .docstring>section>a.is-active.input.docs-sourcelink{box-shadow:0 0 0 0.125em rgba(140,170,238,0.25)}html.theme--catppuccin-frappe .is-link.textarea,html.theme--catppuccin-frappe .is-link.input,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-link{border-color:#8caaee}html.theme--catppuccin-frappe .is-link.textarea:focus,html.theme--catppuccin-frappe .is-link.input:focus,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-link:focus,html.theme--catppuccin-frappe .is-link.is-focused.textarea,html.theme--catppuccin-frappe .is-link.is-focused.input,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--catppuccin-frappe .is-link.textarea:active,html.theme--catppuccin-frappe .is-link.input:active,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-link:active,html.theme--catppuccin-frappe .is-link.is-active.textarea,html.theme--catppuccin-frappe .is-link.is-active.input,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(140,170,238,0.25)}html.theme--catppuccin-frappe .is-info.textarea,html.theme--catppuccin-frappe .is-info.input,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-info{border-color:#81c8be}html.theme--catppuccin-frappe .is-info.textarea:focus,html.theme--catppuccin-frappe .is-info.input:focus,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-info:focus,html.theme--catppuccin-frappe .is-info.is-focused.textarea,html.theme--catppuccin-frappe .is-info.is-focused.input,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--catppuccin-frappe .is-info.textarea:active,html.theme--catppuccin-frappe .is-info.input:active,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-info:active,html.theme--catppuccin-frappe .is-info.is-active.textarea,html.theme--catppuccin-frappe .is-info.is-active.input,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(129,200,190,0.25)}html.theme--catppuccin-frappe .is-success.textarea,html.theme--catppuccin-frappe .is-success.input,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-success{border-color:#a6d189}html.theme--catppuccin-frappe .is-success.textarea:focus,html.theme--catppuccin-frappe .is-success.input:focus,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-success:focus,html.theme--catppuccin-frappe .is-success.is-focused.textarea,html.theme--catppuccin-frappe .is-success.is-focused.input,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--catppuccin-frappe .is-success.textarea:active,html.theme--catppuccin-frappe .is-success.input:active,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-success:active,html.theme--catppuccin-frappe .is-success.is-active.textarea,html.theme--catppuccin-frappe .is-success.is-active.input,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(166,209,137,0.25)}html.theme--catppuccin-frappe .is-warning.textarea,html.theme--catppuccin-frappe .is-warning.input,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-warning{border-color:#e5c890}html.theme--catppuccin-frappe .is-warning.textarea:focus,html.theme--catppuccin-frappe .is-warning.input:focus,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-warning:focus,html.theme--catppuccin-frappe .is-warning.is-focused.textarea,html.theme--catppuccin-frappe .is-warning.is-focused.input,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--catppuccin-frappe .is-warning.textarea:active,html.theme--catppuccin-frappe .is-warning.input:active,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-warning:active,html.theme--catppuccin-frappe .is-warning.is-active.textarea,html.theme--catppuccin-frappe .is-warning.is-active.input,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(229,200,144,0.25)}html.theme--catppuccin-frappe .is-danger.textarea,html.theme--catppuccin-frappe .is-danger.input,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-danger{border-color:#e78284}html.theme--catppuccin-frappe .is-danger.textarea:focus,html.theme--catppuccin-frappe .is-danger.input:focus,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-danger:focus,html.theme--catppuccin-frappe .is-danger.is-focused.textarea,html.theme--catppuccin-frappe .is-danger.is-focused.input,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--catppuccin-frappe .is-danger.textarea:active,html.theme--catppuccin-frappe .is-danger.input:active,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-danger:active,html.theme--catppuccin-frappe .is-danger.is-active.textarea,html.theme--catppuccin-frappe .is-danger.is-active.input,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(231,130,132,0.25)}html.theme--catppuccin-frappe .is-small.textarea,html.theme--catppuccin-frappe .is-small.input,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input{border-radius:3px;font-size:.75rem}html.theme--catppuccin-frappe .is-medium.textarea,html.theme--catppuccin-frappe .is-medium.input,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-medium{font-size:1.25rem}html.theme--catppuccin-frappe .is-large.textarea,html.theme--catppuccin-frappe .is-large.input,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-large{font-size:1.5rem}html.theme--catppuccin-frappe .is-fullwidth.textarea,html.theme--catppuccin-frappe .is-fullwidth.input,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-fullwidth{display:block;width:100%}html.theme--catppuccin-frappe .is-inline.textarea,html.theme--catppuccin-frappe .is-inline.input,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-inline{display:inline;width:auto}html.theme--catppuccin-frappe .input.is-rounded,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input{border-radius:9999px;padding-left:calc(calc(0.75em - 1px) + 0.375em);padding-right:calc(calc(0.75em - 1px) + 0.375em)}html.theme--catppuccin-frappe .input.is-static,html.theme--catppuccin-frappe #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--catppuccin-frappe .textarea{display:block;max-width:100%;min-width:100%;padding:calc(0.75em - 1px);resize:vertical}html.theme--catppuccin-frappe .textarea:not([rows]){max-height:40em;min-height:8em}html.theme--catppuccin-frappe .textarea[rows]{height:initial}html.theme--catppuccin-frappe .textarea.has-fixed-size{resize:none}html.theme--catppuccin-frappe .radio,html.theme--catppuccin-frappe .checkbox{cursor:pointer;display:inline-block;line-height:1.25;position:relative}html.theme--catppuccin-frappe .radio input,html.theme--catppuccin-frappe .checkbox input{cursor:pointer}html.theme--catppuccin-frappe .radio:hover,html.theme--catppuccin-frappe .checkbox:hover{color:#99d1db}html.theme--catppuccin-frappe .radio[disabled],html.theme--catppuccin-frappe .checkbox[disabled],fieldset[disabled] html.theme--catppuccin-frappe .radio,fieldset[disabled] html.theme--catppuccin-frappe .checkbox,html.theme--catppuccin-frappe .radio input[disabled],html.theme--catppuccin-frappe .checkbox input[disabled]{color:#f1f4fd;cursor:not-allowed}html.theme--catppuccin-frappe .radio+.radio{margin-left:.5em}html.theme--catppuccin-frappe .select{display:inline-block;max-width:100%;position:relative;vertical-align:top}html.theme--catppuccin-frappe .select:not(.is-multiple){height:2.5em}html.theme--catppuccin-frappe .select:not(.is-multiple):not(.is-loading)::after{border-color:#8caaee;right:1.125em;z-index:4}html.theme--catppuccin-frappe .select.is-rounded select,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.select select{border-radius:9999px;padding-left:1em}html.theme--catppuccin-frappe .select select{cursor:pointer;display:block;font-size:1em;max-width:100%;outline:none}html.theme--catppuccin-frappe .select select::-ms-expand{display:none}html.theme--catppuccin-frappe .select select[disabled]:hover,fieldset[disabled] html.theme--catppuccin-frappe .select select:hover{border-color:#292c3c}html.theme--catppuccin-frappe .select select:not([multiple]){padding-right:2.5em}html.theme--catppuccin-frappe .select select[multiple]{height:auto;padding:0}html.theme--catppuccin-frappe .select select[multiple] option{padding:0.5em 1em}html.theme--catppuccin-frappe .select:not(.is-multiple):not(.is-loading):hover::after{border-color:#99d1db}html.theme--catppuccin-frappe .select.is-white:not(:hover)::after{border-color:#fff}html.theme--catppuccin-frappe .select.is-white select{border-color:#fff}html.theme--catppuccin-frappe .select.is-white select:hover,html.theme--catppuccin-frappe .select.is-white select.is-hovered{border-color:#f2f2f2}html.theme--catppuccin-frappe .select.is-white select:focus,html.theme--catppuccin-frappe .select.is-white select.is-focused,html.theme--catppuccin-frappe .select.is-white select:active,html.theme--catppuccin-frappe .select.is-white select.is-active{box-shadow:0 0 0 0.125em rgba(255,255,255,0.25)}html.theme--catppuccin-frappe .select.is-black:not(:hover)::after{border-color:#0a0a0a}html.theme--catppuccin-frappe .select.is-black select{border-color:#0a0a0a}html.theme--catppuccin-frappe .select.is-black select:hover,html.theme--catppuccin-frappe .select.is-black select.is-hovered{border-color:#000}html.theme--catppuccin-frappe .select.is-black select:focus,html.theme--catppuccin-frappe .select.is-black select.is-focused,html.theme--catppuccin-frappe .select.is-black select:active,html.theme--catppuccin-frappe .select.is-black select.is-active{box-shadow:0 0 0 0.125em rgba(10,10,10,0.25)}html.theme--catppuccin-frappe .select.is-light:not(:hover)::after{border-color:#f5f5f5}html.theme--catppuccin-frappe .select.is-light select{border-color:#f5f5f5}html.theme--catppuccin-frappe .select.is-light select:hover,html.theme--catppuccin-frappe .select.is-light select.is-hovered{border-color:#e8e8e8}html.theme--catppuccin-frappe .select.is-light select:focus,html.theme--catppuccin-frappe .select.is-light select.is-focused,html.theme--catppuccin-frappe .select.is-light select:active,html.theme--catppuccin-frappe .select.is-light select.is-active{box-shadow:0 0 0 0.125em rgba(245,245,245,0.25)}html.theme--catppuccin-frappe .select.is-dark:not(:hover)::after,html.theme--catppuccin-frappe .content kbd.select:not(:hover)::after{border-color:#414559}html.theme--catppuccin-frappe .select.is-dark select,html.theme--catppuccin-frappe .content kbd.select select{border-color:#414559}html.theme--catppuccin-frappe .select.is-dark select:hover,html.theme--catppuccin-frappe .content kbd.select select:hover,html.theme--catppuccin-frappe .select.is-dark select.is-hovered,html.theme--catppuccin-frappe .content kbd.select select.is-hovered{border-color:#363a4a}html.theme--catppuccin-frappe .select.is-dark select:focus,html.theme--catppuccin-frappe .content kbd.select select:focus,html.theme--catppuccin-frappe .select.is-dark select.is-focused,html.theme--catppuccin-frappe .content kbd.select select.is-focused,html.theme--catppuccin-frappe .select.is-dark select:active,html.theme--catppuccin-frappe .content kbd.select select:active,html.theme--catppuccin-frappe .select.is-dark select.is-active,html.theme--catppuccin-frappe .content kbd.select select.is-active{box-shadow:0 0 0 0.125em rgba(65,69,89,0.25)}html.theme--catppuccin-frappe .select.is-primary:not(:hover)::after,html.theme--catppuccin-frappe .docstring>section>a.select.docs-sourcelink:not(:hover)::after{border-color:#8caaee}html.theme--catppuccin-frappe .select.is-primary select,html.theme--catppuccin-frappe .docstring>section>a.select.docs-sourcelink select{border-color:#8caaee}html.theme--catppuccin-frappe .select.is-primary select:hover,html.theme--catppuccin-frappe .docstring>section>a.select.docs-sourcelink select:hover,html.theme--catppuccin-frappe .select.is-primary select.is-hovered,html.theme--catppuccin-frappe .docstring>section>a.select.docs-sourcelink select.is-hovered{border-color:#769aeb}html.theme--catppuccin-frappe .select.is-primary select:focus,html.theme--catppuccin-frappe .docstring>section>a.select.docs-sourcelink select:focus,html.theme--catppuccin-frappe .select.is-primary select.is-focused,html.theme--catppuccin-frappe .docstring>section>a.select.docs-sourcelink select.is-focused,html.theme--catppuccin-frappe .select.is-primary select:active,html.theme--catppuccin-frappe .docstring>section>a.select.docs-sourcelink select:active,html.theme--catppuccin-frappe .select.is-primary select.is-active,html.theme--catppuccin-frappe .docstring>section>a.select.docs-sourcelink select.is-active{box-shadow:0 0 0 0.125em rgba(140,170,238,0.25)}html.theme--catppuccin-frappe .select.is-link:not(:hover)::after{border-color:#8caaee}html.theme--catppuccin-frappe .select.is-link select{border-color:#8caaee}html.theme--catppuccin-frappe .select.is-link select:hover,html.theme--catppuccin-frappe .select.is-link select.is-hovered{border-color:#769aeb}html.theme--catppuccin-frappe .select.is-link select:focus,html.theme--catppuccin-frappe .select.is-link select.is-focused,html.theme--catppuccin-frappe .select.is-link select:active,html.theme--catppuccin-frappe .select.is-link select.is-active{box-shadow:0 0 0 0.125em rgba(140,170,238,0.25)}html.theme--catppuccin-frappe .select.is-info:not(:hover)::after{border-color:#81c8be}html.theme--catppuccin-frappe .select.is-info select{border-color:#81c8be}html.theme--catppuccin-frappe .select.is-info select:hover,html.theme--catppuccin-frappe .select.is-info select.is-hovered{border-color:#6fc0b5}html.theme--catppuccin-frappe .select.is-info select:focus,html.theme--catppuccin-frappe .select.is-info select.is-focused,html.theme--catppuccin-frappe .select.is-info select:active,html.theme--catppuccin-frappe .select.is-info select.is-active{box-shadow:0 0 0 0.125em rgba(129,200,190,0.25)}html.theme--catppuccin-frappe .select.is-success:not(:hover)::after{border-color:#a6d189}html.theme--catppuccin-frappe .select.is-success select{border-color:#a6d189}html.theme--catppuccin-frappe .select.is-success select:hover,html.theme--catppuccin-frappe .select.is-success select.is-hovered{border-color:#98ca77}html.theme--catppuccin-frappe .select.is-success select:focus,html.theme--catppuccin-frappe .select.is-success select.is-focused,html.theme--catppuccin-frappe .select.is-success select:active,html.theme--catppuccin-frappe .select.is-success select.is-active{box-shadow:0 0 0 0.125em rgba(166,209,137,0.25)}html.theme--catppuccin-frappe .select.is-warning:not(:hover)::after{border-color:#e5c890}html.theme--catppuccin-frappe .select.is-warning select{border-color:#e5c890}html.theme--catppuccin-frappe .select.is-warning select:hover,html.theme--catppuccin-frappe .select.is-warning select.is-hovered{border-color:#e0be7b}html.theme--catppuccin-frappe .select.is-warning select:focus,html.theme--catppuccin-frappe .select.is-warning select.is-focused,html.theme--catppuccin-frappe .select.is-warning select:active,html.theme--catppuccin-frappe .select.is-warning select.is-active{box-shadow:0 0 0 0.125em rgba(229,200,144,0.25)}html.theme--catppuccin-frappe .select.is-danger:not(:hover)::after{border-color:#e78284}html.theme--catppuccin-frappe .select.is-danger select{border-color:#e78284}html.theme--catppuccin-frappe .select.is-danger select:hover,html.theme--catppuccin-frappe .select.is-danger select.is-hovered{border-color:#e36d6f}html.theme--catppuccin-frappe .select.is-danger select:focus,html.theme--catppuccin-frappe .select.is-danger select.is-focused,html.theme--catppuccin-frappe .select.is-danger select:active,html.theme--catppuccin-frappe .select.is-danger select.is-active{box-shadow:0 0 0 0.125em rgba(231,130,132,0.25)}html.theme--catppuccin-frappe .select.is-small,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.select{border-radius:3px;font-size:.75rem}html.theme--catppuccin-frappe .select.is-medium{font-size:1.25rem}html.theme--catppuccin-frappe .select.is-large{font-size:1.5rem}html.theme--catppuccin-frappe .select.is-disabled::after{border-color:#f1f4fd !important;opacity:0.5}html.theme--catppuccin-frappe .select.is-fullwidth{width:100%}html.theme--catppuccin-frappe .select.is-fullwidth select{width:100%}html.theme--catppuccin-frappe .select.is-loading::after{margin-top:0;position:absolute;right:.625em;top:0.625em;transform:none}html.theme--catppuccin-frappe .select.is-loading.is-small:after,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-loading:after{font-size:.75rem}html.theme--catppuccin-frappe .select.is-loading.is-medium:after{font-size:1.25rem}html.theme--catppuccin-frappe .select.is-loading.is-large:after{font-size:1.5rem}html.theme--catppuccin-frappe .file{align-items:stretch;display:flex;justify-content:flex-start;position:relative}html.theme--catppuccin-frappe .file.is-white .file-cta{background-color:#fff;border-color:transparent;color:#0a0a0a}html.theme--catppuccin-frappe .file.is-white:hover .file-cta,html.theme--catppuccin-frappe .file.is-white.is-hovered .file-cta{background-color:#f9f9f9;border-color:transparent;color:#0a0a0a}html.theme--catppuccin-frappe .file.is-white:focus .file-cta,html.theme--catppuccin-frappe .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--catppuccin-frappe .file.is-white:active .file-cta,html.theme--catppuccin-frappe .file.is-white.is-active .file-cta{background-color:#f2f2f2;border-color:transparent;color:#0a0a0a}html.theme--catppuccin-frappe .file.is-black .file-cta{background-color:#0a0a0a;border-color:transparent;color:#fff}html.theme--catppuccin-frappe .file.is-black:hover .file-cta,html.theme--catppuccin-frappe .file.is-black.is-hovered .file-cta{background-color:#040404;border-color:transparent;color:#fff}html.theme--catppuccin-frappe .file.is-black:focus .file-cta,html.theme--catppuccin-frappe .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--catppuccin-frappe .file.is-black:active .file-cta,html.theme--catppuccin-frappe .file.is-black.is-active .file-cta{background-color:#000;border-color:transparent;color:#fff}html.theme--catppuccin-frappe .file.is-light .file-cta{background-color:#f5f5f5;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .file.is-light:hover .file-cta,html.theme--catppuccin-frappe .file.is-light.is-hovered .file-cta{background-color:#eee;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .file.is-light:focus .file-cta,html.theme--catppuccin-frappe .file.is-light.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(245,245,245,0.25);color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .file.is-light:active .file-cta,html.theme--catppuccin-frappe .file.is-light.is-active .file-cta{background-color:#e8e8e8;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .file.is-dark .file-cta,html.theme--catppuccin-frappe .content kbd.file .file-cta{background-color:#414559;border-color:transparent;color:#fff}html.theme--catppuccin-frappe .file.is-dark:hover .file-cta,html.theme--catppuccin-frappe .content kbd.file:hover .file-cta,html.theme--catppuccin-frappe .file.is-dark.is-hovered .file-cta,html.theme--catppuccin-frappe .content kbd.file.is-hovered .file-cta{background-color:#3c3f52;border-color:transparent;color:#fff}html.theme--catppuccin-frappe .file.is-dark:focus .file-cta,html.theme--catppuccin-frappe .content kbd.file:focus .file-cta,html.theme--catppuccin-frappe .file.is-dark.is-focused .file-cta,html.theme--catppuccin-frappe .content kbd.file.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(65,69,89,0.25);color:#fff}html.theme--catppuccin-frappe .file.is-dark:active .file-cta,html.theme--catppuccin-frappe .content kbd.file:active .file-cta,html.theme--catppuccin-frappe .file.is-dark.is-active .file-cta,html.theme--catppuccin-frappe .content kbd.file.is-active .file-cta{background-color:#363a4a;border-color:transparent;color:#fff}html.theme--catppuccin-frappe .file.is-primary .file-cta,html.theme--catppuccin-frappe .docstring>section>a.file.docs-sourcelink .file-cta{background-color:#8caaee;border-color:transparent;color:#fff}html.theme--catppuccin-frappe .file.is-primary:hover .file-cta,html.theme--catppuccin-frappe .docstring>section>a.file.docs-sourcelink:hover .file-cta,html.theme--catppuccin-frappe .file.is-primary.is-hovered .file-cta,html.theme--catppuccin-frappe .docstring>section>a.file.is-hovered.docs-sourcelink .file-cta{background-color:#81a2ec;border-color:transparent;color:#fff}html.theme--catppuccin-frappe .file.is-primary:focus .file-cta,html.theme--catppuccin-frappe .docstring>section>a.file.docs-sourcelink:focus .file-cta,html.theme--catppuccin-frappe .file.is-primary.is-focused .file-cta,html.theme--catppuccin-frappe .docstring>section>a.file.is-focused.docs-sourcelink .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(140,170,238,0.25);color:#fff}html.theme--catppuccin-frappe .file.is-primary:active .file-cta,html.theme--catppuccin-frappe .docstring>section>a.file.docs-sourcelink:active .file-cta,html.theme--catppuccin-frappe .file.is-primary.is-active .file-cta,html.theme--catppuccin-frappe .docstring>section>a.file.is-active.docs-sourcelink .file-cta{background-color:#769aeb;border-color:transparent;color:#fff}html.theme--catppuccin-frappe .file.is-link .file-cta{background-color:#8caaee;border-color:transparent;color:#fff}html.theme--catppuccin-frappe .file.is-link:hover .file-cta,html.theme--catppuccin-frappe .file.is-link.is-hovered .file-cta{background-color:#81a2ec;border-color:transparent;color:#fff}html.theme--catppuccin-frappe .file.is-link:focus .file-cta,html.theme--catppuccin-frappe .file.is-link.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(140,170,238,0.25);color:#fff}html.theme--catppuccin-frappe .file.is-link:active .file-cta,html.theme--catppuccin-frappe .file.is-link.is-active .file-cta{background-color:#769aeb;border-color:transparent;color:#fff}html.theme--catppuccin-frappe .file.is-info .file-cta{background-color:#81c8be;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .file.is-info:hover .file-cta,html.theme--catppuccin-frappe .file.is-info.is-hovered .file-cta{background-color:#78c4b9;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .file.is-info:focus .file-cta,html.theme--catppuccin-frappe .file.is-info.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(129,200,190,0.25);color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .file.is-info:active .file-cta,html.theme--catppuccin-frappe .file.is-info.is-active .file-cta{background-color:#6fc0b5;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .file.is-success .file-cta{background-color:#a6d189;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .file.is-success:hover .file-cta,html.theme--catppuccin-frappe .file.is-success.is-hovered .file-cta{background-color:#9fcd80;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .file.is-success:focus .file-cta,html.theme--catppuccin-frappe .file.is-success.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(166,209,137,0.25);color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .file.is-success:active .file-cta,html.theme--catppuccin-frappe .file.is-success.is-active .file-cta{background-color:#98ca77;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .file.is-warning .file-cta{background-color:#e5c890;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .file.is-warning:hover .file-cta,html.theme--catppuccin-frappe .file.is-warning.is-hovered .file-cta{background-color:#e3c386;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .file.is-warning:focus .file-cta,html.theme--catppuccin-frappe .file.is-warning.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(229,200,144,0.25);color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .file.is-warning:active .file-cta,html.theme--catppuccin-frappe .file.is-warning.is-active .file-cta{background-color:#e0be7b;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .file.is-danger .file-cta{background-color:#e78284;border-color:transparent;color:#fff}html.theme--catppuccin-frappe .file.is-danger:hover .file-cta,html.theme--catppuccin-frappe .file.is-danger.is-hovered .file-cta{background-color:#e57779;border-color:transparent;color:#fff}html.theme--catppuccin-frappe .file.is-danger:focus .file-cta,html.theme--catppuccin-frappe .file.is-danger.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(231,130,132,0.25);color:#fff}html.theme--catppuccin-frappe .file.is-danger:active .file-cta,html.theme--catppuccin-frappe .file.is-danger.is-active .file-cta{background-color:#e36d6f;border-color:transparent;color:#fff}html.theme--catppuccin-frappe .file.is-small,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.file{font-size:.75rem}html.theme--catppuccin-frappe .file.is-normal{font-size:1rem}html.theme--catppuccin-frappe .file.is-medium{font-size:1.25rem}html.theme--catppuccin-frappe .file.is-medium .file-icon .fa{font-size:21px}html.theme--catppuccin-frappe .file.is-large{font-size:1.5rem}html.theme--catppuccin-frappe .file.is-large .file-icon .fa{font-size:28px}html.theme--catppuccin-frappe .file.has-name .file-cta{border-bottom-right-radius:0;border-top-right-radius:0}html.theme--catppuccin-frappe .file.has-name .file-name{border-bottom-left-radius:0;border-top-left-radius:0}html.theme--catppuccin-frappe .file.has-name.is-empty .file-cta{border-radius:.4em}html.theme--catppuccin-frappe .file.has-name.is-empty .file-name{display:none}html.theme--catppuccin-frappe .file.is-boxed .file-label{flex-direction:column}html.theme--catppuccin-frappe .file.is-boxed .file-cta{flex-direction:column;height:auto;padding:1em 3em}html.theme--catppuccin-frappe .file.is-boxed .file-name{border-width:0 1px 1px}html.theme--catppuccin-frappe .file.is-boxed .file-icon{height:1.5em;width:1.5em}html.theme--catppuccin-frappe .file.is-boxed .file-icon .fa{font-size:21px}html.theme--catppuccin-frappe .file.is-boxed.is-small .file-icon .fa,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-boxed .file-icon .fa{font-size:14px}html.theme--catppuccin-frappe .file.is-boxed.is-medium .file-icon .fa{font-size:28px}html.theme--catppuccin-frappe .file.is-boxed.is-large .file-icon .fa{font-size:35px}html.theme--catppuccin-frappe .file.is-boxed.has-name .file-cta{border-radius:.4em .4em 0 0}html.theme--catppuccin-frappe .file.is-boxed.has-name .file-name{border-radius:0 0 .4em .4em;border-width:0 1px 1px}html.theme--catppuccin-frappe .file.is-centered{justify-content:center}html.theme--catppuccin-frappe .file.is-fullwidth .file-label{width:100%}html.theme--catppuccin-frappe .file.is-fullwidth .file-name{flex-grow:1;max-width:none}html.theme--catppuccin-frappe .file.is-right{justify-content:flex-end}html.theme--catppuccin-frappe .file.is-right .file-cta{border-radius:0 .4em .4em 0}html.theme--catppuccin-frappe .file.is-right .file-name{border-radius:.4em 0 0 .4em;border-width:1px 0 1px 1px;order:-1}html.theme--catppuccin-frappe .file-label{align-items:stretch;display:flex;cursor:pointer;justify-content:flex-start;overflow:hidden;position:relative}html.theme--catppuccin-frappe .file-label:hover .file-cta{background-color:#3c3f52;color:#b0bef1}html.theme--catppuccin-frappe .file-label:hover .file-name{border-color:#5c6279}html.theme--catppuccin-frappe .file-label:active .file-cta{background-color:#363a4a;color:#b0bef1}html.theme--catppuccin-frappe .file-label:active .file-name{border-color:#575c72}html.theme--catppuccin-frappe .file-input{height:100%;left:0;opacity:0;outline:none;position:absolute;top:0;width:100%}html.theme--catppuccin-frappe .file-cta,html.theme--catppuccin-frappe .file-name{border-color:#626880;border-radius:.4em;font-size:1em;padding-left:1em;padding-right:1em;white-space:nowrap}html.theme--catppuccin-frappe .file-cta{background-color:#414559;color:#c6d0f5}html.theme--catppuccin-frappe .file-name{border-color:#626880;border-style:solid;border-width:1px 1px 1px 0;display:block;max-width:16em;overflow:hidden;text-align:inherit;text-overflow:ellipsis}html.theme--catppuccin-frappe .file-icon{align-items:center;display:flex;height:1em;justify-content:center;margin-right:.5em;width:1em}html.theme--catppuccin-frappe .file-icon .fa{font-size:14px}html.theme--catppuccin-frappe .label{color:#b0bef1;display:block;font-size:1rem;font-weight:700}html.theme--catppuccin-frappe .label:not(:last-child){margin-bottom:0.5em}html.theme--catppuccin-frappe .label.is-small,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.label{font-size:.75rem}html.theme--catppuccin-frappe .label.is-medium{font-size:1.25rem}html.theme--catppuccin-frappe .label.is-large{font-size:1.5rem}html.theme--catppuccin-frappe .help{display:block;font-size:.75rem;margin-top:0.25rem}html.theme--catppuccin-frappe .help.is-white{color:#fff}html.theme--catppuccin-frappe .help.is-black{color:#0a0a0a}html.theme--catppuccin-frappe .help.is-light{color:#f5f5f5}html.theme--catppuccin-frappe .help.is-dark,html.theme--catppuccin-frappe .content kbd.help{color:#414559}html.theme--catppuccin-frappe .help.is-primary,html.theme--catppuccin-frappe .docstring>section>a.help.docs-sourcelink{color:#8caaee}html.theme--catppuccin-frappe .help.is-link{color:#8caaee}html.theme--catppuccin-frappe .help.is-info{color:#81c8be}html.theme--catppuccin-frappe .help.is-success{color:#a6d189}html.theme--catppuccin-frappe .help.is-warning{color:#e5c890}html.theme--catppuccin-frappe .help.is-danger{color:#e78284}html.theme--catppuccin-frappe .field:not(:last-child){margin-bottom:0.75rem}html.theme--catppuccin-frappe .field.has-addons{display:flex;justify-content:flex-start}html.theme--catppuccin-frappe .field.has-addons .control:not(:last-child){margin-right:-1px}html.theme--catppuccin-frappe .field.has-addons .control:not(:first-child):not(:last-child) .button,html.theme--catppuccin-frappe .field.has-addons .control:not(:first-child):not(:last-child) .input,html.theme--catppuccin-frappe .field.has-addons .control:not(:first-child):not(:last-child) #documenter .docs-sidebar form.docs-search>input,html.theme--catppuccin-frappe #documenter .docs-sidebar .field.has-addons .control:not(:first-child):not(:last-child) form.docs-search>input,html.theme--catppuccin-frappe .field.has-addons .control:not(:first-child):not(:last-child) .select select{border-radius:0}html.theme--catppuccin-frappe .field.has-addons .control:first-child:not(:only-child) .button,html.theme--catppuccin-frappe .field.has-addons .control:first-child:not(:only-child) .input,html.theme--catppuccin-frappe .field.has-addons .control:first-child:not(:only-child) #documenter .docs-sidebar form.docs-search>input,html.theme--catppuccin-frappe #documenter .docs-sidebar .field.has-addons .control:first-child:not(:only-child) form.docs-search>input,html.theme--catppuccin-frappe .field.has-addons .control:first-child:not(:only-child) .select select{border-bottom-right-radius:0;border-top-right-radius:0}html.theme--catppuccin-frappe .field.has-addons .control:last-child:not(:only-child) .button,html.theme--catppuccin-frappe .field.has-addons .control:last-child:not(:only-child) .input,html.theme--catppuccin-frappe .field.has-addons .control:last-child:not(:only-child) #documenter .docs-sidebar form.docs-search>input,html.theme--catppuccin-frappe #documenter .docs-sidebar .field.has-addons .control:last-child:not(:only-child) form.docs-search>input,html.theme--catppuccin-frappe .field.has-addons .control:last-child:not(:only-child) .select select{border-bottom-left-radius:0;border-top-left-radius:0}html.theme--catppuccin-frappe .field.has-addons .control .button:not([disabled]):hover,html.theme--catppuccin-frappe .field.has-addons .control .button.is-hovered:not([disabled]),html.theme--catppuccin-frappe .field.has-addons .control .input:not([disabled]):hover,html.theme--catppuccin-frappe .field.has-addons .control #documenter .docs-sidebar form.docs-search>input:not([disabled]):hover,html.theme--catppuccin-frappe #documenter .docs-sidebar .field.has-addons .control form.docs-search>input:not([disabled]):hover,html.theme--catppuccin-frappe .field.has-addons .control .input.is-hovered:not([disabled]),html.theme--catppuccin-frappe .field.has-addons .control #documenter .docs-sidebar form.docs-search>input.is-hovered:not([disabled]),html.theme--catppuccin-frappe #documenter .docs-sidebar .field.has-addons .control form.docs-search>input.is-hovered:not([disabled]),html.theme--catppuccin-frappe .field.has-addons .control .select select:not([disabled]):hover,html.theme--catppuccin-frappe .field.has-addons .control .select select.is-hovered:not([disabled]){z-index:2}html.theme--catppuccin-frappe .field.has-addons .control .button:not([disabled]):focus,html.theme--catppuccin-frappe .field.has-addons .control .button.is-focused:not([disabled]),html.theme--catppuccin-frappe .field.has-addons .control .button:not([disabled]):active,html.theme--catppuccin-frappe .field.has-addons .control .button.is-active:not([disabled]),html.theme--catppuccin-frappe .field.has-addons .control .input:not([disabled]):focus,html.theme--catppuccin-frappe .field.has-addons .control #documenter .docs-sidebar form.docs-search>input:not([disabled]):focus,html.theme--catppuccin-frappe #documenter .docs-sidebar .field.has-addons .control form.docs-search>input:not([disabled]):focus,html.theme--catppuccin-frappe .field.has-addons .control .input.is-focused:not([disabled]),html.theme--catppuccin-frappe .field.has-addons .control #documenter .docs-sidebar form.docs-search>input.is-focused:not([disabled]),html.theme--catppuccin-frappe #documenter .docs-sidebar .field.has-addons .control form.docs-search>input.is-focused:not([disabled]),html.theme--catppuccin-frappe .field.has-addons .control .input:not([disabled]):active,html.theme--catppuccin-frappe .field.has-addons .control #documenter .docs-sidebar form.docs-search>input:not([disabled]):active,html.theme--catppuccin-frappe #documenter .docs-sidebar .field.has-addons .control form.docs-search>input:not([disabled]):active,html.theme--catppuccin-frappe .field.has-addons .control .input.is-active:not([disabled]),html.theme--catppuccin-frappe .field.has-addons .control #documenter .docs-sidebar form.docs-search>input.is-active:not([disabled]),html.theme--catppuccin-frappe #documenter .docs-sidebar .field.has-addons .control form.docs-search>input.is-active:not([disabled]),html.theme--catppuccin-frappe .field.has-addons .control .select select:not([disabled]):focus,html.theme--catppuccin-frappe .field.has-addons .control .select select.is-focused:not([disabled]),html.theme--catppuccin-frappe .field.has-addons .control .select select:not([disabled]):active,html.theme--catppuccin-frappe .field.has-addons .control .select select.is-active:not([disabled]){z-index:3}html.theme--catppuccin-frappe .field.has-addons .control .button:not([disabled]):focus:hover,html.theme--catppuccin-frappe .field.has-addons .control .button.is-focused:not([disabled]):hover,html.theme--catppuccin-frappe .field.has-addons .control .button:not([disabled]):active:hover,html.theme--catppuccin-frappe .field.has-addons .control .button.is-active:not([disabled]):hover,html.theme--catppuccin-frappe .field.has-addons .control .input:not([disabled]):focus:hover,html.theme--catppuccin-frappe .field.has-addons .control #documenter .docs-sidebar form.docs-search>input:not([disabled]):focus:hover,html.theme--catppuccin-frappe #documenter .docs-sidebar .field.has-addons .control form.docs-search>input:not([disabled]):focus:hover,html.theme--catppuccin-frappe .field.has-addons .control .input.is-focused:not([disabled]):hover,html.theme--catppuccin-frappe .field.has-addons .control #documenter .docs-sidebar form.docs-search>input.is-focused:not([disabled]):hover,html.theme--catppuccin-frappe #documenter .docs-sidebar .field.has-addons .control form.docs-search>input.is-focused:not([disabled]):hover,html.theme--catppuccin-frappe .field.has-addons .control .input:not([disabled]):active:hover,html.theme--catppuccin-frappe .field.has-addons .control #documenter .docs-sidebar form.docs-search>input:not([disabled]):active:hover,html.theme--catppuccin-frappe #documenter .docs-sidebar .field.has-addons .control form.docs-search>input:not([disabled]):active:hover,html.theme--catppuccin-frappe .field.has-addons .control .input.is-active:not([disabled]):hover,html.theme--catppuccin-frappe .field.has-addons .control #documenter .docs-sidebar form.docs-search>input.is-active:not([disabled]):hover,html.theme--catppuccin-frappe #documenter .docs-sidebar .field.has-addons .control form.docs-search>input.is-active:not([disabled]):hover,html.theme--catppuccin-frappe .field.has-addons .control .select select:not([disabled]):focus:hover,html.theme--catppuccin-frappe .field.has-addons .control .select select.is-focused:not([disabled]):hover,html.theme--catppuccin-frappe .field.has-addons .control .select select:not([disabled]):active:hover,html.theme--catppuccin-frappe .field.has-addons .control .select select.is-active:not([disabled]):hover{z-index:4}html.theme--catppuccin-frappe .field.has-addons .control.is-expanded{flex-grow:1;flex-shrink:1}html.theme--catppuccin-frappe .field.has-addons.has-addons-centered{justify-content:center}html.theme--catppuccin-frappe .field.has-addons.has-addons-right{justify-content:flex-end}html.theme--catppuccin-frappe .field.has-addons.has-addons-fullwidth .control{flex-grow:1;flex-shrink:0}html.theme--catppuccin-frappe .field.is-grouped{display:flex;justify-content:flex-start}html.theme--catppuccin-frappe .field.is-grouped>.control{flex-shrink:0}html.theme--catppuccin-frappe .field.is-grouped>.control:not(:last-child){margin-bottom:0;margin-right:.75rem}html.theme--catppuccin-frappe .field.is-grouped>.control.is-expanded{flex-grow:1;flex-shrink:1}html.theme--catppuccin-frappe .field.is-grouped.is-grouped-centered{justify-content:center}html.theme--catppuccin-frappe .field.is-grouped.is-grouped-right{justify-content:flex-end}html.theme--catppuccin-frappe .field.is-grouped.is-grouped-multiline{flex-wrap:wrap}html.theme--catppuccin-frappe .field.is-grouped.is-grouped-multiline>.control:last-child,html.theme--catppuccin-frappe .field.is-grouped.is-grouped-multiline>.control:not(:last-child){margin-bottom:0.75rem}html.theme--catppuccin-frappe .field.is-grouped.is-grouped-multiline:last-child{margin-bottom:-0.75rem}html.theme--catppuccin-frappe .field.is-grouped.is-grouped-multiline:not(:last-child){margin-bottom:0}@media screen and (min-width: 769px),print{html.theme--catppuccin-frappe .field.is-horizontal{display:flex}}html.theme--catppuccin-frappe .field-label .label{font-size:inherit}@media screen and (max-width: 768px){html.theme--catppuccin-frappe .field-label{margin-bottom:0.5rem}}@media screen and (min-width: 769px),print{html.theme--catppuccin-frappe .field-label{flex-basis:0;flex-grow:1;flex-shrink:0;margin-right:1.5rem;text-align:right}html.theme--catppuccin-frappe .field-label.is-small,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.field-label{font-size:.75rem;padding-top:0.375em}html.theme--catppuccin-frappe .field-label.is-normal{padding-top:0.375em}html.theme--catppuccin-frappe .field-label.is-medium{font-size:1.25rem;padding-top:0.375em}html.theme--catppuccin-frappe .field-label.is-large{font-size:1.5rem;padding-top:0.375em}}html.theme--catppuccin-frappe .field-body .field .field{margin-bottom:0}@media screen and (min-width: 769px),print{html.theme--catppuccin-frappe .field-body{display:flex;flex-basis:0;flex-grow:5;flex-shrink:1}html.theme--catppuccin-frappe .field-body .field{margin-bottom:0}html.theme--catppuccin-frappe .field-body>.field{flex-shrink:1}html.theme--catppuccin-frappe .field-body>.field:not(.is-narrow){flex-grow:1}html.theme--catppuccin-frappe .field-body>.field:not(:last-child){margin-right:.75rem}}html.theme--catppuccin-frappe .control{box-sizing:border-box;clear:both;font-size:1rem;position:relative;text-align:inherit}html.theme--catppuccin-frappe .control.has-icons-left .input:focus~.icon,html.theme--catppuccin-frappe .control.has-icons-left #documenter .docs-sidebar form.docs-search>input:focus~.icon,html.theme--catppuccin-frappe #documenter .docs-sidebar .control.has-icons-left form.docs-search>input:focus~.icon,html.theme--catppuccin-frappe .control.has-icons-left .select:focus~.icon,html.theme--catppuccin-frappe .control.has-icons-right .input:focus~.icon,html.theme--catppuccin-frappe .control.has-icons-right #documenter .docs-sidebar form.docs-search>input:focus~.icon,html.theme--catppuccin-frappe #documenter .docs-sidebar .control.has-icons-right form.docs-search>input:focus~.icon,html.theme--catppuccin-frappe .control.has-icons-right .select:focus~.icon{color:#414559}html.theme--catppuccin-frappe .control.has-icons-left .input.is-small~.icon,html.theme--catppuccin-frappe .control.has-icons-left #documenter .docs-sidebar form.docs-search>input~.icon,html.theme--catppuccin-frappe #documenter .docs-sidebar .control.has-icons-left form.docs-search>input~.icon,html.theme--catppuccin-frappe .control.has-icons-left .select.is-small~.icon,html.theme--catppuccin-frappe .control.has-icons-right .input.is-small~.icon,html.theme--catppuccin-frappe .control.has-icons-right #documenter .docs-sidebar form.docs-search>input~.icon,html.theme--catppuccin-frappe #documenter .docs-sidebar .control.has-icons-right form.docs-search>input~.icon,html.theme--catppuccin-frappe .control.has-icons-right .select.is-small~.icon{font-size:.75rem}html.theme--catppuccin-frappe .control.has-icons-left .input.is-medium~.icon,html.theme--catppuccin-frappe .control.has-icons-left #documenter .docs-sidebar form.docs-search>input.is-medium~.icon,html.theme--catppuccin-frappe #documenter .docs-sidebar .control.has-icons-left form.docs-search>input.is-medium~.icon,html.theme--catppuccin-frappe .control.has-icons-left .select.is-medium~.icon,html.theme--catppuccin-frappe .control.has-icons-right .input.is-medium~.icon,html.theme--catppuccin-frappe .control.has-icons-right #documenter .docs-sidebar form.docs-search>input.is-medium~.icon,html.theme--catppuccin-frappe #documenter .docs-sidebar .control.has-icons-right form.docs-search>input.is-medium~.icon,html.theme--catppuccin-frappe .control.has-icons-right .select.is-medium~.icon{font-size:1.25rem}html.theme--catppuccin-frappe .control.has-icons-left .input.is-large~.icon,html.theme--catppuccin-frappe .control.has-icons-left #documenter .docs-sidebar form.docs-search>input.is-large~.icon,html.theme--catppuccin-frappe #documenter .docs-sidebar .control.has-icons-left form.docs-search>input.is-large~.icon,html.theme--catppuccin-frappe .control.has-icons-left .select.is-large~.icon,html.theme--catppuccin-frappe .control.has-icons-right .input.is-large~.icon,html.theme--catppuccin-frappe .control.has-icons-right #documenter .docs-sidebar form.docs-search>input.is-large~.icon,html.theme--catppuccin-frappe #documenter .docs-sidebar .control.has-icons-right form.docs-search>input.is-large~.icon,html.theme--catppuccin-frappe .control.has-icons-right .select.is-large~.icon{font-size:1.5rem}html.theme--catppuccin-frappe .control.has-icons-left .icon,html.theme--catppuccin-frappe .control.has-icons-right .icon{color:#626880;height:2.5em;pointer-events:none;position:absolute;top:0;width:2.5em;z-index:4}html.theme--catppuccin-frappe .control.has-icons-left .input,html.theme--catppuccin-frappe .control.has-icons-left #documenter .docs-sidebar form.docs-search>input,html.theme--catppuccin-frappe #documenter .docs-sidebar .control.has-icons-left form.docs-search>input,html.theme--catppuccin-frappe .control.has-icons-left .select select{padding-left:2.5em}html.theme--catppuccin-frappe .control.has-icons-left .icon.is-left{left:0}html.theme--catppuccin-frappe .control.has-icons-right .input,html.theme--catppuccin-frappe .control.has-icons-right #documenter .docs-sidebar form.docs-search>input,html.theme--catppuccin-frappe #documenter .docs-sidebar .control.has-icons-right form.docs-search>input,html.theme--catppuccin-frappe .control.has-icons-right .select select{padding-right:2.5em}html.theme--catppuccin-frappe .control.has-icons-right .icon.is-right{right:0}html.theme--catppuccin-frappe .control.is-loading::after{position:absolute !important;right:.625em;top:0.625em;z-index:4}html.theme--catppuccin-frappe .control.is-loading.is-small:after,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-loading:after{font-size:.75rem}html.theme--catppuccin-frappe .control.is-loading.is-medium:after{font-size:1.25rem}html.theme--catppuccin-frappe .control.is-loading.is-large:after{font-size:1.5rem}html.theme--catppuccin-frappe .breadcrumb{font-size:1rem;white-space:nowrap}html.theme--catppuccin-frappe .breadcrumb a{align-items:center;color:#8caaee;display:flex;justify-content:center;padding:0 .75em}html.theme--catppuccin-frappe .breadcrumb a:hover{color:#99d1db}html.theme--catppuccin-frappe .breadcrumb li{align-items:center;display:flex}html.theme--catppuccin-frappe .breadcrumb li:first-child a{padding-left:0}html.theme--catppuccin-frappe .breadcrumb li.is-active a{color:#b0bef1;cursor:default;pointer-events:none}html.theme--catppuccin-frappe .breadcrumb li+li::before{color:#737994;content:"\0002f"}html.theme--catppuccin-frappe .breadcrumb ul,html.theme--catppuccin-frappe .breadcrumb ol{align-items:flex-start;display:flex;flex-wrap:wrap;justify-content:flex-start}html.theme--catppuccin-frappe .breadcrumb .icon:first-child{margin-right:.5em}html.theme--catppuccin-frappe .breadcrumb .icon:last-child{margin-left:.5em}html.theme--catppuccin-frappe .breadcrumb.is-centered ol,html.theme--catppuccin-frappe .breadcrumb.is-centered ul{justify-content:center}html.theme--catppuccin-frappe .breadcrumb.is-right ol,html.theme--catppuccin-frappe .breadcrumb.is-right ul{justify-content:flex-end}html.theme--catppuccin-frappe .breadcrumb.is-small,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.breadcrumb{font-size:.75rem}html.theme--catppuccin-frappe .breadcrumb.is-medium{font-size:1.25rem}html.theme--catppuccin-frappe .breadcrumb.is-large{font-size:1.5rem}html.theme--catppuccin-frappe .breadcrumb.has-arrow-separator li+li::before{content:"\02192"}html.theme--catppuccin-frappe .breadcrumb.has-bullet-separator li+li::before{content:"\02022"}html.theme--catppuccin-frappe .breadcrumb.has-dot-separator li+li::before{content:"\000b7"}html.theme--catppuccin-frappe .breadcrumb.has-succeeds-separator li+li::before{content:"\0227B"}html.theme--catppuccin-frappe .card{background-color:#fff;border-radius:.25rem;box-shadow:#171717;color:#c6d0f5;max-width:100%;position:relative}html.theme--catppuccin-frappe .card-footer:first-child,html.theme--catppuccin-frappe .card-content:first-child,html.theme--catppuccin-frappe .card-header:first-child{border-top-left-radius:.25rem;border-top-right-radius:.25rem}html.theme--catppuccin-frappe .card-footer:last-child,html.theme--catppuccin-frappe .card-content:last-child,html.theme--catppuccin-frappe .card-header:last-child{border-bottom-left-radius:.25rem;border-bottom-right-radius:.25rem}html.theme--catppuccin-frappe .card-header{background-color:rgba(0,0,0,0);align-items:stretch;box-shadow:0 0.125em 0.25em rgba(10,10,10,0.1);display:flex}html.theme--catppuccin-frappe .card-header-title{align-items:center;color:#b0bef1;display:flex;flex-grow:1;font-weight:700;padding:0.75rem 1rem}html.theme--catppuccin-frappe .card-header-title.is-centered{justify-content:center}html.theme--catppuccin-frappe .card-header-icon{-moz-appearance:none;-webkit-appearance:none;appearance:none;background:none;border:none;color:currentColor;font-family:inherit;font-size:1em;margin:0;padding:0;align-items:center;cursor:pointer;display:flex;justify-content:center;padding:0.75rem 1rem}html.theme--catppuccin-frappe .card-image{display:block;position:relative}html.theme--catppuccin-frappe .card-image:first-child img{border-top-left-radius:.25rem;border-top-right-radius:.25rem}html.theme--catppuccin-frappe .card-image:last-child img{border-bottom-left-radius:.25rem;border-bottom-right-radius:.25rem}html.theme--catppuccin-frappe .card-content{background-color:rgba(0,0,0,0);padding:1.5rem}html.theme--catppuccin-frappe .card-footer{background-color:rgba(0,0,0,0);border-top:1px solid #ededed;align-items:stretch;display:flex}html.theme--catppuccin-frappe .card-footer-item{align-items:center;display:flex;flex-basis:0;flex-grow:1;flex-shrink:0;justify-content:center;padding:.75rem}html.theme--catppuccin-frappe .card-footer-item:not(:last-child){border-right:1px solid #ededed}html.theme--catppuccin-frappe .card .media:not(:last-child){margin-bottom:1.5rem}html.theme--catppuccin-frappe .dropdown{display:inline-flex;position:relative;vertical-align:top}html.theme--catppuccin-frappe .dropdown.is-active .dropdown-menu,html.theme--catppuccin-frappe .dropdown.is-hoverable:hover .dropdown-menu{display:block}html.theme--catppuccin-frappe .dropdown.is-right .dropdown-menu{left:auto;right:0}html.theme--catppuccin-frappe .dropdown.is-up .dropdown-menu{bottom:100%;padding-bottom:4px;padding-top:initial;top:auto}html.theme--catppuccin-frappe .dropdown-menu{display:none;left:0;min-width:12rem;padding-top:4px;position:absolute;top:100%;z-index:20}html.theme--catppuccin-frappe .dropdown-content{background-color:#292c3c;border-radius:.4em;box-shadow:#171717;padding-bottom:.5rem;padding-top:.5rem}html.theme--catppuccin-frappe .dropdown-item{color:#c6d0f5;display:block;font-size:0.875rem;line-height:1.5;padding:0.375rem 1rem;position:relative}html.theme--catppuccin-frappe a.dropdown-item,html.theme--catppuccin-frappe button.dropdown-item{padding-right:3rem;text-align:inherit;white-space:nowrap;width:100%}html.theme--catppuccin-frappe a.dropdown-item:hover,html.theme--catppuccin-frappe button.dropdown-item:hover{background-color:#292c3c;color:#0a0a0a}html.theme--catppuccin-frappe a.dropdown-item.is-active,html.theme--catppuccin-frappe button.dropdown-item.is-active{background-color:#8caaee;color:#fff}html.theme--catppuccin-frappe .dropdown-divider{background-color:#ededed;border:none;display:block;height:1px;margin:0.5rem 0}html.theme--catppuccin-frappe .level{align-items:center;justify-content:space-between}html.theme--catppuccin-frappe .level code{border-radius:.4em}html.theme--catppuccin-frappe .level img{display:inline-block;vertical-align:top}html.theme--catppuccin-frappe .level.is-mobile{display:flex}html.theme--catppuccin-frappe .level.is-mobile .level-left,html.theme--catppuccin-frappe .level.is-mobile .level-right{display:flex}html.theme--catppuccin-frappe .level.is-mobile .level-left+.level-right{margin-top:0}html.theme--catppuccin-frappe .level.is-mobile .level-item:not(:last-child){margin-bottom:0;margin-right:.75rem}html.theme--catppuccin-frappe .level.is-mobile .level-item:not(.is-narrow){flex-grow:1}@media screen and (min-width: 769px),print{html.theme--catppuccin-frappe .level{display:flex}html.theme--catppuccin-frappe .level>.level-item:not(.is-narrow){flex-grow:1}}html.theme--catppuccin-frappe .level-item{align-items:center;display:flex;flex-basis:auto;flex-grow:0;flex-shrink:0;justify-content:center}html.theme--catppuccin-frappe .level-item .title,html.theme--catppuccin-frappe .level-item .subtitle{margin-bottom:0}@media screen and (max-width: 768px){html.theme--catppuccin-frappe .level-item:not(:last-child){margin-bottom:.75rem}}html.theme--catppuccin-frappe .level-left,html.theme--catppuccin-frappe .level-right{flex-basis:auto;flex-grow:0;flex-shrink:0}html.theme--catppuccin-frappe .level-left .level-item.is-flexible,html.theme--catppuccin-frappe .level-right .level-item.is-flexible{flex-grow:1}@media screen and (min-width: 769px),print{html.theme--catppuccin-frappe .level-left .level-item:not(:last-child),html.theme--catppuccin-frappe .level-right .level-item:not(:last-child){margin-right:.75rem}}html.theme--catppuccin-frappe .level-left{align-items:center;justify-content:flex-start}@media screen and (max-width: 768px){html.theme--catppuccin-frappe .level-left+.level-right{margin-top:1.5rem}}@media screen and (min-width: 769px),print{html.theme--catppuccin-frappe .level-left{display:flex}}html.theme--catppuccin-frappe .level-right{align-items:center;justify-content:flex-end}@media screen and (min-width: 769px),print{html.theme--catppuccin-frappe .level-right{display:flex}}html.theme--catppuccin-frappe .media{align-items:flex-start;display:flex;text-align:inherit}html.theme--catppuccin-frappe .media .content:not(:last-child){margin-bottom:.75rem}html.theme--catppuccin-frappe .media .media{border-top:1px solid rgba(98,104,128,0.5);display:flex;padding-top:.75rem}html.theme--catppuccin-frappe .media .media .content:not(:last-child),html.theme--catppuccin-frappe .media .media .control:not(:last-child){margin-bottom:.5rem}html.theme--catppuccin-frappe .media .media .media{padding-top:.5rem}html.theme--catppuccin-frappe .media .media .media+.media{margin-top:.5rem}html.theme--catppuccin-frappe .media+.media{border-top:1px solid rgba(98,104,128,0.5);margin-top:1rem;padding-top:1rem}html.theme--catppuccin-frappe .media.is-large+.media{margin-top:1.5rem;padding-top:1.5rem}html.theme--catppuccin-frappe .media-left,html.theme--catppuccin-frappe .media-right{flex-basis:auto;flex-grow:0;flex-shrink:0}html.theme--catppuccin-frappe .media-left{margin-right:1rem}html.theme--catppuccin-frappe .media-right{margin-left:1rem}html.theme--catppuccin-frappe .media-content{flex-basis:auto;flex-grow:1;flex-shrink:1;text-align:inherit}@media screen and (max-width: 768px){html.theme--catppuccin-frappe .media-content{overflow-x:auto}}html.theme--catppuccin-frappe .menu{font-size:1rem}html.theme--catppuccin-frappe .menu.is-small,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.menu{font-size:.75rem}html.theme--catppuccin-frappe .menu.is-medium{font-size:1.25rem}html.theme--catppuccin-frappe .menu.is-large{font-size:1.5rem}html.theme--catppuccin-frappe .menu-list{line-height:1.25}html.theme--catppuccin-frappe .menu-list a{border-radius:3px;color:#c6d0f5;display:block;padding:0.5em 0.75em}html.theme--catppuccin-frappe .menu-list a:hover{background-color:#292c3c;color:#b0bef1}html.theme--catppuccin-frappe .menu-list a.is-active{background-color:#8caaee;color:#fff}html.theme--catppuccin-frappe .menu-list li ul{border-left:1px solid #626880;margin:.75em;padding-left:.75em}html.theme--catppuccin-frappe .menu-label{color:#f1f4fd;font-size:.75em;letter-spacing:.1em;text-transform:uppercase}html.theme--catppuccin-frappe .menu-label:not(:first-child){margin-top:1em}html.theme--catppuccin-frappe .menu-label:not(:last-child){margin-bottom:1em}html.theme--catppuccin-frappe .message{background-color:#292c3c;border-radius:.4em;font-size:1rem}html.theme--catppuccin-frappe .message strong{color:currentColor}html.theme--catppuccin-frappe .message a:not(.button):not(.tag):not(.dropdown-item){color:currentColor;text-decoration:underline}html.theme--catppuccin-frappe .message.is-small,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.message{font-size:.75rem}html.theme--catppuccin-frappe .message.is-medium{font-size:1.25rem}html.theme--catppuccin-frappe .message.is-large{font-size:1.5rem}html.theme--catppuccin-frappe .message.is-white{background-color:#fff}html.theme--catppuccin-frappe .message.is-white .message-header{background-color:#fff;color:#0a0a0a}html.theme--catppuccin-frappe .message.is-white .message-body{border-color:#fff}html.theme--catppuccin-frappe .message.is-black{background-color:#fafafa}html.theme--catppuccin-frappe .message.is-black .message-header{background-color:#0a0a0a;color:#fff}html.theme--catppuccin-frappe .message.is-black .message-body{border-color:#0a0a0a}html.theme--catppuccin-frappe .message.is-light{background-color:#fafafa}html.theme--catppuccin-frappe .message.is-light .message-header{background-color:#f5f5f5;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .message.is-light .message-body{border-color:#f5f5f5}html.theme--catppuccin-frappe .message.is-dark,html.theme--catppuccin-frappe .content kbd.message{background-color:#f9f9fb}html.theme--catppuccin-frappe .message.is-dark .message-header,html.theme--catppuccin-frappe .content kbd.message .message-header{background-color:#414559;color:#fff}html.theme--catppuccin-frappe .message.is-dark .message-body,html.theme--catppuccin-frappe .content kbd.message .message-body{border-color:#414559}html.theme--catppuccin-frappe .message.is-primary,html.theme--catppuccin-frappe .docstring>section>a.message.docs-sourcelink{background-color:#edf2fc}html.theme--catppuccin-frappe .message.is-primary .message-header,html.theme--catppuccin-frappe .docstring>section>a.message.docs-sourcelink .message-header{background-color:#8caaee;color:#fff}html.theme--catppuccin-frappe .message.is-primary .message-body,html.theme--catppuccin-frappe .docstring>section>a.message.docs-sourcelink .message-body{border-color:#8caaee;color:#153a8e}html.theme--catppuccin-frappe .message.is-link{background-color:#edf2fc}html.theme--catppuccin-frappe .message.is-link .message-header{background-color:#8caaee;color:#fff}html.theme--catppuccin-frappe .message.is-link .message-body{border-color:#8caaee;color:#153a8e}html.theme--catppuccin-frappe .message.is-info{background-color:#f1f9f8}html.theme--catppuccin-frappe .message.is-info .message-header{background-color:#81c8be;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .message.is-info .message-body{border-color:#81c8be;color:#2d675f}html.theme--catppuccin-frappe .message.is-success{background-color:#f4f9f0}html.theme--catppuccin-frappe .message.is-success .message-header{background-color:#a6d189;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .message.is-success .message-body{border-color:#a6d189;color:#446a29}html.theme--catppuccin-frappe .message.is-warning{background-color:#fbf7ee}html.theme--catppuccin-frappe .message.is-warning .message-header{background-color:#e5c890;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .message.is-warning .message-body{border-color:#e5c890;color:#78591c}html.theme--catppuccin-frappe .message.is-danger{background-color:#fceeee}html.theme--catppuccin-frappe .message.is-danger .message-header{background-color:#e78284;color:#fff}html.theme--catppuccin-frappe .message.is-danger .message-body{border-color:#e78284;color:#9a1e20}html.theme--catppuccin-frappe .message-header{align-items:center;background-color:#c6d0f5;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--catppuccin-frappe .message-header .delete{flex-grow:0;flex-shrink:0;margin-left:.75em}html.theme--catppuccin-frappe .message-header+.message-body{border-width:0;border-top-left-radius:0;border-top-right-radius:0}html.theme--catppuccin-frappe .message-body{border-color:#626880;border-radius:.4em;border-style:solid;border-width:0 0 0 4px;color:#c6d0f5;padding:1.25em 1.5em}html.theme--catppuccin-frappe .message-body code,html.theme--catppuccin-frappe .message-body pre{background-color:#fff}html.theme--catppuccin-frappe .message-body pre code{background-color:rgba(0,0,0,0)}html.theme--catppuccin-frappe .modal{align-items:center;display:none;flex-direction:column;justify-content:center;overflow:hidden;position:fixed;z-index:40}html.theme--catppuccin-frappe .modal.is-active{display:flex}html.theme--catppuccin-frappe .modal-background{background-color:rgba(10,10,10,0.86)}html.theme--catppuccin-frappe .modal-content,html.theme--catppuccin-frappe .modal-card{margin:0 20px;max-height:calc(100vh - 160px);overflow:auto;position:relative;width:100%}@media screen and (min-width: 769px){html.theme--catppuccin-frappe .modal-content,html.theme--catppuccin-frappe .modal-card{margin:0 auto;max-height:calc(100vh - 40px);width:640px}}html.theme--catppuccin-frappe .modal-close{background:none;height:40px;position:fixed;right:20px;top:20px;width:40px}html.theme--catppuccin-frappe .modal-card{display:flex;flex-direction:column;max-height:calc(100vh - 40px);overflow:hidden;-ms-overflow-y:visible}html.theme--catppuccin-frappe .modal-card-head,html.theme--catppuccin-frappe .modal-card-foot{align-items:center;background-color:#292c3c;display:flex;flex-shrink:0;justify-content:flex-start;padding:20px;position:relative}html.theme--catppuccin-frappe .modal-card-head{border-bottom:1px solid #626880;border-top-left-radius:8px;border-top-right-radius:8px}html.theme--catppuccin-frappe .modal-card-title{color:#c6d0f5;flex-grow:1;flex-shrink:0;font-size:1.5rem;line-height:1}html.theme--catppuccin-frappe .modal-card-foot{border-bottom-left-radius:8px;border-bottom-right-radius:8px;border-top:1px solid #626880}html.theme--catppuccin-frappe .modal-card-foot .button:not(:last-child){margin-right:.5em}html.theme--catppuccin-frappe .modal-card-body{-webkit-overflow-scrolling:touch;background-color:#303446;flex-grow:1;flex-shrink:1;overflow:auto;padding:20px}html.theme--catppuccin-frappe .navbar{background-color:#8caaee;min-height:4rem;position:relative;z-index:30}html.theme--catppuccin-frappe .navbar.is-white{background-color:#fff;color:#0a0a0a}html.theme--catppuccin-frappe .navbar.is-white .navbar-brand>.navbar-item,html.theme--catppuccin-frappe .navbar.is-white .navbar-brand .navbar-link{color:#0a0a0a}html.theme--catppuccin-frappe .navbar.is-white .navbar-brand>a.navbar-item:focus,html.theme--catppuccin-frappe .navbar.is-white .navbar-brand>a.navbar-item:hover,html.theme--catppuccin-frappe .navbar.is-white .navbar-brand>a.navbar-item.is-active,html.theme--catppuccin-frappe .navbar.is-white .navbar-brand .navbar-link:focus,html.theme--catppuccin-frappe .navbar.is-white .navbar-brand .navbar-link:hover,html.theme--catppuccin-frappe .navbar.is-white .navbar-brand .navbar-link.is-active{background-color:#f2f2f2;color:#0a0a0a}html.theme--catppuccin-frappe .navbar.is-white .navbar-brand .navbar-link::after{border-color:#0a0a0a}html.theme--catppuccin-frappe .navbar.is-white .navbar-burger{color:#0a0a0a}@media screen and (min-width: 1056px){html.theme--catppuccin-frappe .navbar.is-white .navbar-start>.navbar-item,html.theme--catppuccin-frappe .navbar.is-white .navbar-start .navbar-link,html.theme--catppuccin-frappe .navbar.is-white .navbar-end>.navbar-item,html.theme--catppuccin-frappe .navbar.is-white .navbar-end .navbar-link{color:#0a0a0a}html.theme--catppuccin-frappe .navbar.is-white .navbar-start>a.navbar-item:focus,html.theme--catppuccin-frappe .navbar.is-white .navbar-start>a.navbar-item:hover,html.theme--catppuccin-frappe .navbar.is-white .navbar-start>a.navbar-item.is-active,html.theme--catppuccin-frappe .navbar.is-white .navbar-start .navbar-link:focus,html.theme--catppuccin-frappe .navbar.is-white .navbar-start .navbar-link:hover,html.theme--catppuccin-frappe .navbar.is-white .navbar-start .navbar-link.is-active,html.theme--catppuccin-frappe .navbar.is-white .navbar-end>a.navbar-item:focus,html.theme--catppuccin-frappe .navbar.is-white .navbar-end>a.navbar-item:hover,html.theme--catppuccin-frappe .navbar.is-white .navbar-end>a.navbar-item.is-active,html.theme--catppuccin-frappe .navbar.is-white .navbar-end .navbar-link:focus,html.theme--catppuccin-frappe .navbar.is-white .navbar-end .navbar-link:hover,html.theme--catppuccin-frappe .navbar.is-white .navbar-end .navbar-link.is-active{background-color:#f2f2f2;color:#0a0a0a}html.theme--catppuccin-frappe .navbar.is-white .navbar-start .navbar-link::after,html.theme--catppuccin-frappe .navbar.is-white .navbar-end .navbar-link::after{border-color:#0a0a0a}html.theme--catppuccin-frappe .navbar.is-white .navbar-item.has-dropdown:focus .navbar-link,html.theme--catppuccin-frappe .navbar.is-white .navbar-item.has-dropdown:hover .navbar-link,html.theme--catppuccin-frappe .navbar.is-white .navbar-item.has-dropdown.is-active .navbar-link{background-color:#f2f2f2;color:#0a0a0a}html.theme--catppuccin-frappe .navbar.is-white .navbar-dropdown a.navbar-item.is-active{background-color:#fff;color:#0a0a0a}}html.theme--catppuccin-frappe .navbar.is-black{background-color:#0a0a0a;color:#fff}html.theme--catppuccin-frappe .navbar.is-black .navbar-brand>.navbar-item,html.theme--catppuccin-frappe .navbar.is-black .navbar-brand .navbar-link{color:#fff}html.theme--catppuccin-frappe .navbar.is-black .navbar-brand>a.navbar-item:focus,html.theme--catppuccin-frappe .navbar.is-black .navbar-brand>a.navbar-item:hover,html.theme--catppuccin-frappe .navbar.is-black .navbar-brand>a.navbar-item.is-active,html.theme--catppuccin-frappe .navbar.is-black .navbar-brand .navbar-link:focus,html.theme--catppuccin-frappe .navbar.is-black .navbar-brand .navbar-link:hover,html.theme--catppuccin-frappe .navbar.is-black .navbar-brand .navbar-link.is-active{background-color:#000;color:#fff}html.theme--catppuccin-frappe .navbar.is-black .navbar-brand .navbar-link::after{border-color:#fff}html.theme--catppuccin-frappe .navbar.is-black .navbar-burger{color:#fff}@media screen and (min-width: 1056px){html.theme--catppuccin-frappe .navbar.is-black .navbar-start>.navbar-item,html.theme--catppuccin-frappe .navbar.is-black .navbar-start .navbar-link,html.theme--catppuccin-frappe .navbar.is-black .navbar-end>.navbar-item,html.theme--catppuccin-frappe .navbar.is-black .navbar-end .navbar-link{color:#fff}html.theme--catppuccin-frappe .navbar.is-black .navbar-start>a.navbar-item:focus,html.theme--catppuccin-frappe .navbar.is-black .navbar-start>a.navbar-item:hover,html.theme--catppuccin-frappe .navbar.is-black .navbar-start>a.navbar-item.is-active,html.theme--catppuccin-frappe .navbar.is-black .navbar-start .navbar-link:focus,html.theme--catppuccin-frappe .navbar.is-black .navbar-start .navbar-link:hover,html.theme--catppuccin-frappe .navbar.is-black .navbar-start .navbar-link.is-active,html.theme--catppuccin-frappe .navbar.is-black .navbar-end>a.navbar-item:focus,html.theme--catppuccin-frappe .navbar.is-black .navbar-end>a.navbar-item:hover,html.theme--catppuccin-frappe .navbar.is-black .navbar-end>a.navbar-item.is-active,html.theme--catppuccin-frappe .navbar.is-black .navbar-end .navbar-link:focus,html.theme--catppuccin-frappe .navbar.is-black .navbar-end .navbar-link:hover,html.theme--catppuccin-frappe .navbar.is-black .navbar-end .navbar-link.is-active{background-color:#000;color:#fff}html.theme--catppuccin-frappe .navbar.is-black .navbar-start .navbar-link::after,html.theme--catppuccin-frappe .navbar.is-black .navbar-end .navbar-link::after{border-color:#fff}html.theme--catppuccin-frappe .navbar.is-black .navbar-item.has-dropdown:focus .navbar-link,html.theme--catppuccin-frappe .navbar.is-black .navbar-item.has-dropdown:hover .navbar-link,html.theme--catppuccin-frappe .navbar.is-black .navbar-item.has-dropdown.is-active .navbar-link{background-color:#000;color:#fff}html.theme--catppuccin-frappe .navbar.is-black .navbar-dropdown a.navbar-item.is-active{background-color:#0a0a0a;color:#fff}}html.theme--catppuccin-frappe .navbar.is-light{background-color:#f5f5f5;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .navbar.is-light .navbar-brand>.navbar-item,html.theme--catppuccin-frappe .navbar.is-light .navbar-brand .navbar-link{color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .navbar.is-light .navbar-brand>a.navbar-item:focus,html.theme--catppuccin-frappe .navbar.is-light .navbar-brand>a.navbar-item:hover,html.theme--catppuccin-frappe .navbar.is-light .navbar-brand>a.navbar-item.is-active,html.theme--catppuccin-frappe .navbar.is-light .navbar-brand .navbar-link:focus,html.theme--catppuccin-frappe .navbar.is-light .navbar-brand .navbar-link:hover,html.theme--catppuccin-frappe .navbar.is-light .navbar-brand .navbar-link.is-active{background-color:#e8e8e8;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .navbar.is-light .navbar-brand .navbar-link::after{border-color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .navbar.is-light .navbar-burger{color:rgba(0,0,0,0.7)}@media screen and (min-width: 1056px){html.theme--catppuccin-frappe .navbar.is-light .navbar-start>.navbar-item,html.theme--catppuccin-frappe .navbar.is-light .navbar-start .navbar-link,html.theme--catppuccin-frappe .navbar.is-light .navbar-end>.navbar-item,html.theme--catppuccin-frappe .navbar.is-light .navbar-end .navbar-link{color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .navbar.is-light .navbar-start>a.navbar-item:focus,html.theme--catppuccin-frappe .navbar.is-light .navbar-start>a.navbar-item:hover,html.theme--catppuccin-frappe .navbar.is-light .navbar-start>a.navbar-item.is-active,html.theme--catppuccin-frappe .navbar.is-light .navbar-start .navbar-link:focus,html.theme--catppuccin-frappe .navbar.is-light .navbar-start .navbar-link:hover,html.theme--catppuccin-frappe .navbar.is-light .navbar-start .navbar-link.is-active,html.theme--catppuccin-frappe .navbar.is-light .navbar-end>a.navbar-item:focus,html.theme--catppuccin-frappe .navbar.is-light .navbar-end>a.navbar-item:hover,html.theme--catppuccin-frappe .navbar.is-light .navbar-end>a.navbar-item.is-active,html.theme--catppuccin-frappe .navbar.is-light .navbar-end .navbar-link:focus,html.theme--catppuccin-frappe .navbar.is-light .navbar-end .navbar-link:hover,html.theme--catppuccin-frappe .navbar.is-light .navbar-end .navbar-link.is-active{background-color:#e8e8e8;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .navbar.is-light .navbar-start .navbar-link::after,html.theme--catppuccin-frappe .navbar.is-light .navbar-end .navbar-link::after{border-color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .navbar.is-light .navbar-item.has-dropdown:focus .navbar-link,html.theme--catppuccin-frappe .navbar.is-light .navbar-item.has-dropdown:hover .navbar-link,html.theme--catppuccin-frappe .navbar.is-light .navbar-item.has-dropdown.is-active .navbar-link{background-color:#e8e8e8;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .navbar.is-light .navbar-dropdown a.navbar-item.is-active{background-color:#f5f5f5;color:rgba(0,0,0,0.7)}}html.theme--catppuccin-frappe .navbar.is-dark,html.theme--catppuccin-frappe .content kbd.navbar{background-color:#414559;color:#fff}html.theme--catppuccin-frappe .navbar.is-dark .navbar-brand>.navbar-item,html.theme--catppuccin-frappe .content kbd.navbar .navbar-brand>.navbar-item,html.theme--catppuccin-frappe .navbar.is-dark .navbar-brand .navbar-link,html.theme--catppuccin-frappe .content kbd.navbar .navbar-brand .navbar-link{color:#fff}html.theme--catppuccin-frappe .navbar.is-dark .navbar-brand>a.navbar-item:focus,html.theme--catppuccin-frappe .content kbd.navbar .navbar-brand>a.navbar-item:focus,html.theme--catppuccin-frappe .navbar.is-dark .navbar-brand>a.navbar-item:hover,html.theme--catppuccin-frappe .content kbd.navbar .navbar-brand>a.navbar-item:hover,html.theme--catppuccin-frappe .navbar.is-dark .navbar-brand>a.navbar-item.is-active,html.theme--catppuccin-frappe .content kbd.navbar .navbar-brand>a.navbar-item.is-active,html.theme--catppuccin-frappe .navbar.is-dark .navbar-brand .navbar-link:focus,html.theme--catppuccin-frappe .content kbd.navbar .navbar-brand .navbar-link:focus,html.theme--catppuccin-frappe .navbar.is-dark .navbar-brand .navbar-link:hover,html.theme--catppuccin-frappe .content kbd.navbar .navbar-brand .navbar-link:hover,html.theme--catppuccin-frappe .navbar.is-dark .navbar-brand .navbar-link.is-active,html.theme--catppuccin-frappe .content kbd.navbar .navbar-brand .navbar-link.is-active{background-color:#363a4a;color:#fff}html.theme--catppuccin-frappe .navbar.is-dark .navbar-brand .navbar-link::after,html.theme--catppuccin-frappe .content kbd.navbar .navbar-brand .navbar-link::after{border-color:#fff}html.theme--catppuccin-frappe .navbar.is-dark .navbar-burger,html.theme--catppuccin-frappe .content kbd.navbar .navbar-burger{color:#fff}@media screen and (min-width: 1056px){html.theme--catppuccin-frappe .navbar.is-dark .navbar-start>.navbar-item,html.theme--catppuccin-frappe .content kbd.navbar .navbar-start>.navbar-item,html.theme--catppuccin-frappe .navbar.is-dark .navbar-start .navbar-link,html.theme--catppuccin-frappe .content kbd.navbar .navbar-start .navbar-link,html.theme--catppuccin-frappe .navbar.is-dark .navbar-end>.navbar-item,html.theme--catppuccin-frappe .content kbd.navbar .navbar-end>.navbar-item,html.theme--catppuccin-frappe .navbar.is-dark .navbar-end .navbar-link,html.theme--catppuccin-frappe .content kbd.navbar .navbar-end .navbar-link{color:#fff}html.theme--catppuccin-frappe .navbar.is-dark .navbar-start>a.navbar-item:focus,html.theme--catppuccin-frappe .content kbd.navbar .navbar-start>a.navbar-item:focus,html.theme--catppuccin-frappe .navbar.is-dark .navbar-start>a.navbar-item:hover,html.theme--catppuccin-frappe .content kbd.navbar .navbar-start>a.navbar-item:hover,html.theme--catppuccin-frappe .navbar.is-dark .navbar-start>a.navbar-item.is-active,html.theme--catppuccin-frappe .content kbd.navbar .navbar-start>a.navbar-item.is-active,html.theme--catppuccin-frappe .navbar.is-dark .navbar-start .navbar-link:focus,html.theme--catppuccin-frappe .content kbd.navbar .navbar-start .navbar-link:focus,html.theme--catppuccin-frappe .navbar.is-dark .navbar-start .navbar-link:hover,html.theme--catppuccin-frappe .content kbd.navbar .navbar-start .navbar-link:hover,html.theme--catppuccin-frappe .navbar.is-dark .navbar-start .navbar-link.is-active,html.theme--catppuccin-frappe .content kbd.navbar .navbar-start .navbar-link.is-active,html.theme--catppuccin-frappe .navbar.is-dark .navbar-end>a.navbar-item:focus,html.theme--catppuccin-frappe .content kbd.navbar .navbar-end>a.navbar-item:focus,html.theme--catppuccin-frappe .navbar.is-dark .navbar-end>a.navbar-item:hover,html.theme--catppuccin-frappe .content kbd.navbar .navbar-end>a.navbar-item:hover,html.theme--catppuccin-frappe .navbar.is-dark .navbar-end>a.navbar-item.is-active,html.theme--catppuccin-frappe .content kbd.navbar .navbar-end>a.navbar-item.is-active,html.theme--catppuccin-frappe .navbar.is-dark .navbar-end .navbar-link:focus,html.theme--catppuccin-frappe .content kbd.navbar .navbar-end .navbar-link:focus,html.theme--catppuccin-frappe .navbar.is-dark .navbar-end .navbar-link:hover,html.theme--catppuccin-frappe .content kbd.navbar .navbar-end .navbar-link:hover,html.theme--catppuccin-frappe .navbar.is-dark .navbar-end .navbar-link.is-active,html.theme--catppuccin-frappe .content kbd.navbar .navbar-end .navbar-link.is-active{background-color:#363a4a;color:#fff}html.theme--catppuccin-frappe .navbar.is-dark .navbar-start .navbar-link::after,html.theme--catppuccin-frappe .content kbd.navbar .navbar-start .navbar-link::after,html.theme--catppuccin-frappe .navbar.is-dark .navbar-end .navbar-link::after,html.theme--catppuccin-frappe .content kbd.navbar .navbar-end .navbar-link::after{border-color:#fff}html.theme--catppuccin-frappe .navbar.is-dark .navbar-item.has-dropdown:focus .navbar-link,html.theme--catppuccin-frappe .content kbd.navbar .navbar-item.has-dropdown:focus .navbar-link,html.theme--catppuccin-frappe .navbar.is-dark .navbar-item.has-dropdown:hover .navbar-link,html.theme--catppuccin-frappe .content kbd.navbar .navbar-item.has-dropdown:hover .navbar-link,html.theme--catppuccin-frappe .navbar.is-dark .navbar-item.has-dropdown.is-active .navbar-link,html.theme--catppuccin-frappe .content kbd.navbar .navbar-item.has-dropdown.is-active .navbar-link{background-color:#363a4a;color:#fff}html.theme--catppuccin-frappe .navbar.is-dark .navbar-dropdown a.navbar-item.is-active,html.theme--catppuccin-frappe .content kbd.navbar .navbar-dropdown a.navbar-item.is-active{background-color:#414559;color:#fff}}html.theme--catppuccin-frappe .navbar.is-primary,html.theme--catppuccin-frappe .docstring>section>a.navbar.docs-sourcelink{background-color:#8caaee;color:#fff}html.theme--catppuccin-frappe .navbar.is-primary .navbar-brand>.navbar-item,html.theme--catppuccin-frappe .docstring>section>a.navbar.docs-sourcelink .navbar-brand>.navbar-item,html.theme--catppuccin-frappe .navbar.is-primary .navbar-brand .navbar-link,html.theme--catppuccin-frappe .docstring>section>a.navbar.docs-sourcelink .navbar-brand .navbar-link{color:#fff}html.theme--catppuccin-frappe .navbar.is-primary .navbar-brand>a.navbar-item:focus,html.theme--catppuccin-frappe .docstring>section>a.navbar.docs-sourcelink .navbar-brand>a.navbar-item:focus,html.theme--catppuccin-frappe .navbar.is-primary .navbar-brand>a.navbar-item:hover,html.theme--catppuccin-frappe .docstring>section>a.navbar.docs-sourcelink .navbar-brand>a.navbar-item:hover,html.theme--catppuccin-frappe .navbar.is-primary .navbar-brand>a.navbar-item.is-active,html.theme--catppuccin-frappe .docstring>section>a.navbar.docs-sourcelink .navbar-brand>a.navbar-item.is-active,html.theme--catppuccin-frappe .navbar.is-primary .navbar-brand .navbar-link:focus,html.theme--catppuccin-frappe .docstring>section>a.navbar.docs-sourcelink .navbar-brand .navbar-link:focus,html.theme--catppuccin-frappe .navbar.is-primary .navbar-brand .navbar-link:hover,html.theme--catppuccin-frappe .docstring>section>a.navbar.docs-sourcelink .navbar-brand .navbar-link:hover,html.theme--catppuccin-frappe .navbar.is-primary .navbar-brand .navbar-link.is-active,html.theme--catppuccin-frappe .docstring>section>a.navbar.docs-sourcelink .navbar-brand .navbar-link.is-active{background-color:#769aeb;color:#fff}html.theme--catppuccin-frappe .navbar.is-primary .navbar-brand .navbar-link::after,html.theme--catppuccin-frappe .docstring>section>a.navbar.docs-sourcelink .navbar-brand .navbar-link::after{border-color:#fff}html.theme--catppuccin-frappe .navbar.is-primary .navbar-burger,html.theme--catppuccin-frappe .docstring>section>a.navbar.docs-sourcelink .navbar-burger{color:#fff}@media screen and (min-width: 1056px){html.theme--catppuccin-frappe .navbar.is-primary .navbar-start>.navbar-item,html.theme--catppuccin-frappe .docstring>section>a.navbar.docs-sourcelink .navbar-start>.navbar-item,html.theme--catppuccin-frappe .navbar.is-primary .navbar-start .navbar-link,html.theme--catppuccin-frappe .docstring>section>a.navbar.docs-sourcelink .navbar-start .navbar-link,html.theme--catppuccin-frappe .navbar.is-primary .navbar-end>.navbar-item,html.theme--catppuccin-frappe .docstring>section>a.navbar.docs-sourcelink .navbar-end>.navbar-item,html.theme--catppuccin-frappe .navbar.is-primary .navbar-end .navbar-link,html.theme--catppuccin-frappe .docstring>section>a.navbar.docs-sourcelink .navbar-end .navbar-link{color:#fff}html.theme--catppuccin-frappe .navbar.is-primary .navbar-start>a.navbar-item:focus,html.theme--catppuccin-frappe .docstring>section>a.navbar.docs-sourcelink .navbar-start>a.navbar-item:focus,html.theme--catppuccin-frappe .navbar.is-primary .navbar-start>a.navbar-item:hover,html.theme--catppuccin-frappe .docstring>section>a.navbar.docs-sourcelink .navbar-start>a.navbar-item:hover,html.theme--catppuccin-frappe .navbar.is-primary .navbar-start>a.navbar-item.is-active,html.theme--catppuccin-frappe .docstring>section>a.navbar.docs-sourcelink .navbar-start>a.navbar-item.is-active,html.theme--catppuccin-frappe .navbar.is-primary .navbar-start .navbar-link:focus,html.theme--catppuccin-frappe .docstring>section>a.navbar.docs-sourcelink .navbar-start .navbar-link:focus,html.theme--catppuccin-frappe .navbar.is-primary .navbar-start .navbar-link:hover,html.theme--catppuccin-frappe .docstring>section>a.navbar.docs-sourcelink .navbar-start .navbar-link:hover,html.theme--catppuccin-frappe .navbar.is-primary .navbar-start .navbar-link.is-active,html.theme--catppuccin-frappe .docstring>section>a.navbar.docs-sourcelink .navbar-start .navbar-link.is-active,html.theme--catppuccin-frappe .navbar.is-primary .navbar-end>a.navbar-item:focus,html.theme--catppuccin-frappe .docstring>section>a.navbar.docs-sourcelink .navbar-end>a.navbar-item:focus,html.theme--catppuccin-frappe .navbar.is-primary .navbar-end>a.navbar-item:hover,html.theme--catppuccin-frappe .docstring>section>a.navbar.docs-sourcelink .navbar-end>a.navbar-item:hover,html.theme--catppuccin-frappe .navbar.is-primary .navbar-end>a.navbar-item.is-active,html.theme--catppuccin-frappe .docstring>section>a.navbar.docs-sourcelink .navbar-end>a.navbar-item.is-active,html.theme--catppuccin-frappe .navbar.is-primary .navbar-end .navbar-link:focus,html.theme--catppuccin-frappe .docstring>section>a.navbar.docs-sourcelink .navbar-end .navbar-link:focus,html.theme--catppuccin-frappe .navbar.is-primary .navbar-end .navbar-link:hover,html.theme--catppuccin-frappe .docstring>section>a.navbar.docs-sourcelink .navbar-end .navbar-link:hover,html.theme--catppuccin-frappe .navbar.is-primary .navbar-end .navbar-link.is-active,html.theme--catppuccin-frappe .docstring>section>a.navbar.docs-sourcelink .navbar-end .navbar-link.is-active{background-color:#769aeb;color:#fff}html.theme--catppuccin-frappe .navbar.is-primary .navbar-start .navbar-link::after,html.theme--catppuccin-frappe .docstring>section>a.navbar.docs-sourcelink .navbar-start .navbar-link::after,html.theme--catppuccin-frappe .navbar.is-primary .navbar-end .navbar-link::after,html.theme--catppuccin-frappe .docstring>section>a.navbar.docs-sourcelink .navbar-end .navbar-link::after{border-color:#fff}html.theme--catppuccin-frappe .navbar.is-primary .navbar-item.has-dropdown:focus .navbar-link,html.theme--catppuccin-frappe .docstring>section>a.navbar.docs-sourcelink .navbar-item.has-dropdown:focus .navbar-link,html.theme--catppuccin-frappe .navbar.is-primary .navbar-item.has-dropdown:hover .navbar-link,html.theme--catppuccin-frappe .docstring>section>a.navbar.docs-sourcelink .navbar-item.has-dropdown:hover .navbar-link,html.theme--catppuccin-frappe .navbar.is-primary .navbar-item.has-dropdown.is-active .navbar-link,html.theme--catppuccin-frappe .docstring>section>a.navbar.docs-sourcelink .navbar-item.has-dropdown.is-active .navbar-link{background-color:#769aeb;color:#fff}html.theme--catppuccin-frappe .navbar.is-primary .navbar-dropdown a.navbar-item.is-active,html.theme--catppuccin-frappe .docstring>section>a.navbar.docs-sourcelink .navbar-dropdown a.navbar-item.is-active{background-color:#8caaee;color:#fff}}html.theme--catppuccin-frappe .navbar.is-link{background-color:#8caaee;color:#fff}html.theme--catppuccin-frappe .navbar.is-link .navbar-brand>.navbar-item,html.theme--catppuccin-frappe .navbar.is-link .navbar-brand .navbar-link{color:#fff}html.theme--catppuccin-frappe .navbar.is-link .navbar-brand>a.navbar-item:focus,html.theme--catppuccin-frappe .navbar.is-link .navbar-brand>a.navbar-item:hover,html.theme--catppuccin-frappe .navbar.is-link .navbar-brand>a.navbar-item.is-active,html.theme--catppuccin-frappe .navbar.is-link .navbar-brand .navbar-link:focus,html.theme--catppuccin-frappe .navbar.is-link .navbar-brand .navbar-link:hover,html.theme--catppuccin-frappe .navbar.is-link .navbar-brand .navbar-link.is-active{background-color:#769aeb;color:#fff}html.theme--catppuccin-frappe .navbar.is-link .navbar-brand .navbar-link::after{border-color:#fff}html.theme--catppuccin-frappe .navbar.is-link .navbar-burger{color:#fff}@media screen and (min-width: 1056px){html.theme--catppuccin-frappe .navbar.is-link .navbar-start>.navbar-item,html.theme--catppuccin-frappe .navbar.is-link .navbar-start .navbar-link,html.theme--catppuccin-frappe .navbar.is-link .navbar-end>.navbar-item,html.theme--catppuccin-frappe .navbar.is-link .navbar-end .navbar-link{color:#fff}html.theme--catppuccin-frappe .navbar.is-link .navbar-start>a.navbar-item:focus,html.theme--catppuccin-frappe .navbar.is-link .navbar-start>a.navbar-item:hover,html.theme--catppuccin-frappe .navbar.is-link .navbar-start>a.navbar-item.is-active,html.theme--catppuccin-frappe .navbar.is-link .navbar-start .navbar-link:focus,html.theme--catppuccin-frappe .navbar.is-link .navbar-start .navbar-link:hover,html.theme--catppuccin-frappe .navbar.is-link .navbar-start .navbar-link.is-active,html.theme--catppuccin-frappe .navbar.is-link .navbar-end>a.navbar-item:focus,html.theme--catppuccin-frappe .navbar.is-link .navbar-end>a.navbar-item:hover,html.theme--catppuccin-frappe .navbar.is-link .navbar-end>a.navbar-item.is-active,html.theme--catppuccin-frappe .navbar.is-link .navbar-end .navbar-link:focus,html.theme--catppuccin-frappe .navbar.is-link .navbar-end .navbar-link:hover,html.theme--catppuccin-frappe .navbar.is-link .navbar-end .navbar-link.is-active{background-color:#769aeb;color:#fff}html.theme--catppuccin-frappe .navbar.is-link .navbar-start .navbar-link::after,html.theme--catppuccin-frappe .navbar.is-link .navbar-end .navbar-link::after{border-color:#fff}html.theme--catppuccin-frappe .navbar.is-link .navbar-item.has-dropdown:focus .navbar-link,html.theme--catppuccin-frappe .navbar.is-link .navbar-item.has-dropdown:hover .navbar-link,html.theme--catppuccin-frappe .navbar.is-link .navbar-item.has-dropdown.is-active .navbar-link{background-color:#769aeb;color:#fff}html.theme--catppuccin-frappe .navbar.is-link .navbar-dropdown a.navbar-item.is-active{background-color:#8caaee;color:#fff}}html.theme--catppuccin-frappe .navbar.is-info{background-color:#81c8be;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .navbar.is-info .navbar-brand>.navbar-item,html.theme--catppuccin-frappe .navbar.is-info .navbar-brand .navbar-link{color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .navbar.is-info .navbar-brand>a.navbar-item:focus,html.theme--catppuccin-frappe .navbar.is-info .navbar-brand>a.navbar-item:hover,html.theme--catppuccin-frappe .navbar.is-info .navbar-brand>a.navbar-item.is-active,html.theme--catppuccin-frappe .navbar.is-info .navbar-brand .navbar-link:focus,html.theme--catppuccin-frappe .navbar.is-info .navbar-brand .navbar-link:hover,html.theme--catppuccin-frappe .navbar.is-info .navbar-brand .navbar-link.is-active{background-color:#6fc0b5;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .navbar.is-info .navbar-brand .navbar-link::after{border-color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .navbar.is-info .navbar-burger{color:rgba(0,0,0,0.7)}@media screen and (min-width: 1056px){html.theme--catppuccin-frappe .navbar.is-info .navbar-start>.navbar-item,html.theme--catppuccin-frappe .navbar.is-info .navbar-start .navbar-link,html.theme--catppuccin-frappe .navbar.is-info .navbar-end>.navbar-item,html.theme--catppuccin-frappe .navbar.is-info .navbar-end .navbar-link{color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .navbar.is-info .navbar-start>a.navbar-item:focus,html.theme--catppuccin-frappe .navbar.is-info .navbar-start>a.navbar-item:hover,html.theme--catppuccin-frappe .navbar.is-info .navbar-start>a.navbar-item.is-active,html.theme--catppuccin-frappe .navbar.is-info .navbar-start .navbar-link:focus,html.theme--catppuccin-frappe .navbar.is-info .navbar-start .navbar-link:hover,html.theme--catppuccin-frappe .navbar.is-info .navbar-start .navbar-link.is-active,html.theme--catppuccin-frappe .navbar.is-info .navbar-end>a.navbar-item:focus,html.theme--catppuccin-frappe .navbar.is-info .navbar-end>a.navbar-item:hover,html.theme--catppuccin-frappe .navbar.is-info .navbar-end>a.navbar-item.is-active,html.theme--catppuccin-frappe .navbar.is-info .navbar-end .navbar-link:focus,html.theme--catppuccin-frappe .navbar.is-info .navbar-end .navbar-link:hover,html.theme--catppuccin-frappe .navbar.is-info .navbar-end .navbar-link.is-active{background-color:#6fc0b5;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .navbar.is-info .navbar-start .navbar-link::after,html.theme--catppuccin-frappe .navbar.is-info .navbar-end .navbar-link::after{border-color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .navbar.is-info .navbar-item.has-dropdown:focus .navbar-link,html.theme--catppuccin-frappe .navbar.is-info .navbar-item.has-dropdown:hover .navbar-link,html.theme--catppuccin-frappe .navbar.is-info .navbar-item.has-dropdown.is-active .navbar-link{background-color:#6fc0b5;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .navbar.is-info .navbar-dropdown a.navbar-item.is-active{background-color:#81c8be;color:rgba(0,0,0,0.7)}}html.theme--catppuccin-frappe .navbar.is-success{background-color:#a6d189;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .navbar.is-success .navbar-brand>.navbar-item,html.theme--catppuccin-frappe .navbar.is-success .navbar-brand .navbar-link{color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .navbar.is-success .navbar-brand>a.navbar-item:focus,html.theme--catppuccin-frappe .navbar.is-success .navbar-brand>a.navbar-item:hover,html.theme--catppuccin-frappe .navbar.is-success .navbar-brand>a.navbar-item.is-active,html.theme--catppuccin-frappe .navbar.is-success .navbar-brand .navbar-link:focus,html.theme--catppuccin-frappe .navbar.is-success .navbar-brand .navbar-link:hover,html.theme--catppuccin-frappe .navbar.is-success .navbar-brand .navbar-link.is-active{background-color:#98ca77;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .navbar.is-success .navbar-brand .navbar-link::after{border-color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .navbar.is-success .navbar-burger{color:rgba(0,0,0,0.7)}@media screen and (min-width: 1056px){html.theme--catppuccin-frappe .navbar.is-success .navbar-start>.navbar-item,html.theme--catppuccin-frappe .navbar.is-success .navbar-start .navbar-link,html.theme--catppuccin-frappe .navbar.is-success .navbar-end>.navbar-item,html.theme--catppuccin-frappe .navbar.is-success .navbar-end .navbar-link{color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .navbar.is-success .navbar-start>a.navbar-item:focus,html.theme--catppuccin-frappe .navbar.is-success .navbar-start>a.navbar-item:hover,html.theme--catppuccin-frappe .navbar.is-success .navbar-start>a.navbar-item.is-active,html.theme--catppuccin-frappe .navbar.is-success .navbar-start .navbar-link:focus,html.theme--catppuccin-frappe .navbar.is-success .navbar-start .navbar-link:hover,html.theme--catppuccin-frappe .navbar.is-success .navbar-start .navbar-link.is-active,html.theme--catppuccin-frappe .navbar.is-success .navbar-end>a.navbar-item:focus,html.theme--catppuccin-frappe .navbar.is-success .navbar-end>a.navbar-item:hover,html.theme--catppuccin-frappe .navbar.is-success .navbar-end>a.navbar-item.is-active,html.theme--catppuccin-frappe .navbar.is-success .navbar-end .navbar-link:focus,html.theme--catppuccin-frappe .navbar.is-success .navbar-end .navbar-link:hover,html.theme--catppuccin-frappe .navbar.is-success .navbar-end .navbar-link.is-active{background-color:#98ca77;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .navbar.is-success .navbar-start .navbar-link::after,html.theme--catppuccin-frappe .navbar.is-success .navbar-end .navbar-link::after{border-color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .navbar.is-success .navbar-item.has-dropdown:focus .navbar-link,html.theme--catppuccin-frappe .navbar.is-success .navbar-item.has-dropdown:hover .navbar-link,html.theme--catppuccin-frappe .navbar.is-success .navbar-item.has-dropdown.is-active .navbar-link{background-color:#98ca77;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .navbar.is-success .navbar-dropdown a.navbar-item.is-active{background-color:#a6d189;color:rgba(0,0,0,0.7)}}html.theme--catppuccin-frappe .navbar.is-warning{background-color:#e5c890;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .navbar.is-warning .navbar-brand>.navbar-item,html.theme--catppuccin-frappe .navbar.is-warning .navbar-brand .navbar-link{color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .navbar.is-warning .navbar-brand>a.navbar-item:focus,html.theme--catppuccin-frappe .navbar.is-warning .navbar-brand>a.navbar-item:hover,html.theme--catppuccin-frappe .navbar.is-warning .navbar-brand>a.navbar-item.is-active,html.theme--catppuccin-frappe .navbar.is-warning .navbar-brand .navbar-link:focus,html.theme--catppuccin-frappe .navbar.is-warning .navbar-brand .navbar-link:hover,html.theme--catppuccin-frappe .navbar.is-warning .navbar-brand .navbar-link.is-active{background-color:#e0be7b;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .navbar.is-warning .navbar-brand .navbar-link::after{border-color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .navbar.is-warning .navbar-burger{color:rgba(0,0,0,0.7)}@media screen and (min-width: 1056px){html.theme--catppuccin-frappe .navbar.is-warning .navbar-start>.navbar-item,html.theme--catppuccin-frappe .navbar.is-warning .navbar-start .navbar-link,html.theme--catppuccin-frappe .navbar.is-warning .navbar-end>.navbar-item,html.theme--catppuccin-frappe .navbar.is-warning .navbar-end .navbar-link{color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .navbar.is-warning .navbar-start>a.navbar-item:focus,html.theme--catppuccin-frappe .navbar.is-warning .navbar-start>a.navbar-item:hover,html.theme--catppuccin-frappe .navbar.is-warning .navbar-start>a.navbar-item.is-active,html.theme--catppuccin-frappe .navbar.is-warning .navbar-start .navbar-link:focus,html.theme--catppuccin-frappe .navbar.is-warning .navbar-start .navbar-link:hover,html.theme--catppuccin-frappe .navbar.is-warning .navbar-start .navbar-link.is-active,html.theme--catppuccin-frappe .navbar.is-warning .navbar-end>a.navbar-item:focus,html.theme--catppuccin-frappe .navbar.is-warning .navbar-end>a.navbar-item:hover,html.theme--catppuccin-frappe .navbar.is-warning .navbar-end>a.navbar-item.is-active,html.theme--catppuccin-frappe .navbar.is-warning .navbar-end .navbar-link:focus,html.theme--catppuccin-frappe .navbar.is-warning .navbar-end .navbar-link:hover,html.theme--catppuccin-frappe .navbar.is-warning .navbar-end .navbar-link.is-active{background-color:#e0be7b;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .navbar.is-warning .navbar-start .navbar-link::after,html.theme--catppuccin-frappe .navbar.is-warning .navbar-end .navbar-link::after{border-color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .navbar.is-warning .navbar-item.has-dropdown:focus .navbar-link,html.theme--catppuccin-frappe .navbar.is-warning .navbar-item.has-dropdown:hover .navbar-link,html.theme--catppuccin-frappe .navbar.is-warning .navbar-item.has-dropdown.is-active .navbar-link{background-color:#e0be7b;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .navbar.is-warning .navbar-dropdown a.navbar-item.is-active{background-color:#e5c890;color:rgba(0,0,0,0.7)}}html.theme--catppuccin-frappe .navbar.is-danger{background-color:#e78284;color:#fff}html.theme--catppuccin-frappe .navbar.is-danger .navbar-brand>.navbar-item,html.theme--catppuccin-frappe .navbar.is-danger .navbar-brand .navbar-link{color:#fff}html.theme--catppuccin-frappe .navbar.is-danger .navbar-brand>a.navbar-item:focus,html.theme--catppuccin-frappe .navbar.is-danger .navbar-brand>a.navbar-item:hover,html.theme--catppuccin-frappe .navbar.is-danger .navbar-brand>a.navbar-item.is-active,html.theme--catppuccin-frappe .navbar.is-danger .navbar-brand .navbar-link:focus,html.theme--catppuccin-frappe .navbar.is-danger .navbar-brand .navbar-link:hover,html.theme--catppuccin-frappe .navbar.is-danger .navbar-brand .navbar-link.is-active{background-color:#e36d6f;color:#fff}html.theme--catppuccin-frappe .navbar.is-danger .navbar-brand .navbar-link::after{border-color:#fff}html.theme--catppuccin-frappe .navbar.is-danger .navbar-burger{color:#fff}@media screen and (min-width: 1056px){html.theme--catppuccin-frappe .navbar.is-danger .navbar-start>.navbar-item,html.theme--catppuccin-frappe .navbar.is-danger .navbar-start .navbar-link,html.theme--catppuccin-frappe .navbar.is-danger .navbar-end>.navbar-item,html.theme--catppuccin-frappe .navbar.is-danger .navbar-end .navbar-link{color:#fff}html.theme--catppuccin-frappe .navbar.is-danger .navbar-start>a.navbar-item:focus,html.theme--catppuccin-frappe .navbar.is-danger .navbar-start>a.navbar-item:hover,html.theme--catppuccin-frappe .navbar.is-danger .navbar-start>a.navbar-item.is-active,html.theme--catppuccin-frappe .navbar.is-danger .navbar-start .navbar-link:focus,html.theme--catppuccin-frappe .navbar.is-danger .navbar-start .navbar-link:hover,html.theme--catppuccin-frappe .navbar.is-danger .navbar-start .navbar-link.is-active,html.theme--catppuccin-frappe .navbar.is-danger .navbar-end>a.navbar-item:focus,html.theme--catppuccin-frappe .navbar.is-danger .navbar-end>a.navbar-item:hover,html.theme--catppuccin-frappe .navbar.is-danger .navbar-end>a.navbar-item.is-active,html.theme--catppuccin-frappe .navbar.is-danger .navbar-end .navbar-link:focus,html.theme--catppuccin-frappe .navbar.is-danger .navbar-end .navbar-link:hover,html.theme--catppuccin-frappe .navbar.is-danger .navbar-end .navbar-link.is-active{background-color:#e36d6f;color:#fff}html.theme--catppuccin-frappe .navbar.is-danger .navbar-start .navbar-link::after,html.theme--catppuccin-frappe .navbar.is-danger .navbar-end .navbar-link::after{border-color:#fff}html.theme--catppuccin-frappe .navbar.is-danger .navbar-item.has-dropdown:focus .navbar-link,html.theme--catppuccin-frappe .navbar.is-danger .navbar-item.has-dropdown:hover .navbar-link,html.theme--catppuccin-frappe .navbar.is-danger .navbar-item.has-dropdown.is-active .navbar-link{background-color:#e36d6f;color:#fff}html.theme--catppuccin-frappe .navbar.is-danger .navbar-dropdown a.navbar-item.is-active{background-color:#e78284;color:#fff}}html.theme--catppuccin-frappe .navbar>.container{align-items:stretch;display:flex;min-height:4rem;width:100%}html.theme--catppuccin-frappe .navbar.has-shadow{box-shadow:0 2px 0 0 #292c3c}html.theme--catppuccin-frappe .navbar.is-fixed-bottom,html.theme--catppuccin-frappe .navbar.is-fixed-top{left:0;position:fixed;right:0;z-index:30}html.theme--catppuccin-frappe .navbar.is-fixed-bottom{bottom:0}html.theme--catppuccin-frappe .navbar.is-fixed-bottom.has-shadow{box-shadow:0 -2px 0 0 #292c3c}html.theme--catppuccin-frappe .navbar.is-fixed-top{top:0}html.theme--catppuccin-frappe html.has-navbar-fixed-top,html.theme--catppuccin-frappe body.has-navbar-fixed-top{padding-top:4rem}html.theme--catppuccin-frappe html.has-navbar-fixed-bottom,html.theme--catppuccin-frappe body.has-navbar-fixed-bottom{padding-bottom:4rem}html.theme--catppuccin-frappe .navbar-brand,html.theme--catppuccin-frappe .navbar-tabs{align-items:stretch;display:flex;flex-shrink:0;min-height:4rem}html.theme--catppuccin-frappe .navbar-brand a.navbar-item:focus,html.theme--catppuccin-frappe .navbar-brand a.navbar-item:hover{background-color:transparent}html.theme--catppuccin-frappe .navbar-tabs{-webkit-overflow-scrolling:touch;max-width:100vw;overflow-x:auto;overflow-y:hidden}html.theme--catppuccin-frappe .navbar-burger{color:#c6d0f5;-moz-appearance:none;-webkit-appearance:none;appearance:none;background:none;border:none;cursor:pointer;display:block;height:4rem;position:relative;width:4rem;margin-left:auto}html.theme--catppuccin-frappe .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--catppuccin-frappe .navbar-burger span:nth-child(1){top:calc(50% - 6px)}html.theme--catppuccin-frappe .navbar-burger span:nth-child(2){top:calc(50% - 1px)}html.theme--catppuccin-frappe .navbar-burger span:nth-child(3){top:calc(50% + 4px)}html.theme--catppuccin-frappe .navbar-burger:hover{background-color:rgba(0,0,0,0.05)}html.theme--catppuccin-frappe .navbar-burger.is-active span:nth-child(1){transform:translateY(5px) rotate(45deg)}html.theme--catppuccin-frappe .navbar-burger.is-active span:nth-child(2){opacity:0}html.theme--catppuccin-frappe .navbar-burger.is-active span:nth-child(3){transform:translateY(-5px) rotate(-45deg)}html.theme--catppuccin-frappe .navbar-menu{display:none}html.theme--catppuccin-frappe .navbar-item,html.theme--catppuccin-frappe .navbar-link{color:#c6d0f5;display:block;line-height:1.5;padding:0.5rem 0.75rem;position:relative}html.theme--catppuccin-frappe .navbar-item .icon:only-child,html.theme--catppuccin-frappe .navbar-link .icon:only-child{margin-left:-0.25rem;margin-right:-0.25rem}html.theme--catppuccin-frappe a.navbar-item,html.theme--catppuccin-frappe .navbar-link{cursor:pointer}html.theme--catppuccin-frappe a.navbar-item:focus,html.theme--catppuccin-frappe a.navbar-item:focus-within,html.theme--catppuccin-frappe a.navbar-item:hover,html.theme--catppuccin-frappe a.navbar-item.is-active,html.theme--catppuccin-frappe .navbar-link:focus,html.theme--catppuccin-frappe .navbar-link:focus-within,html.theme--catppuccin-frappe .navbar-link:hover,html.theme--catppuccin-frappe .navbar-link.is-active{background-color:rgba(0,0,0,0);color:#8caaee}html.theme--catppuccin-frappe .navbar-item{flex-grow:0;flex-shrink:0}html.theme--catppuccin-frappe .navbar-item img{max-height:1.75rem}html.theme--catppuccin-frappe .navbar-item.has-dropdown{padding:0}html.theme--catppuccin-frappe .navbar-item.is-expanded{flex-grow:1;flex-shrink:1}html.theme--catppuccin-frappe .navbar-item.is-tab{border-bottom:1px solid transparent;min-height:4rem;padding-bottom:calc(0.5rem - 1px)}html.theme--catppuccin-frappe .navbar-item.is-tab:focus,html.theme--catppuccin-frappe .navbar-item.is-tab:hover{background-color:rgba(0,0,0,0);border-bottom-color:#8caaee}html.theme--catppuccin-frappe .navbar-item.is-tab.is-active{background-color:rgba(0,0,0,0);border-bottom-color:#8caaee;border-bottom-style:solid;border-bottom-width:3px;color:#8caaee;padding-bottom:calc(0.5rem - 3px)}html.theme--catppuccin-frappe .navbar-content{flex-grow:1;flex-shrink:1}html.theme--catppuccin-frappe .navbar-link:not(.is-arrowless){padding-right:2.5em}html.theme--catppuccin-frappe .navbar-link:not(.is-arrowless)::after{border-color:#fff;margin-top:-0.375em;right:1.125em}html.theme--catppuccin-frappe .navbar-dropdown{font-size:0.875rem;padding-bottom:0.5rem;padding-top:0.5rem}html.theme--catppuccin-frappe .navbar-dropdown .navbar-item{padding-left:1.5rem;padding-right:1.5rem}html.theme--catppuccin-frappe .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--catppuccin-frappe .navbar>.container{display:block}html.theme--catppuccin-frappe .navbar-brand .navbar-item,html.theme--catppuccin-frappe .navbar-tabs .navbar-item{align-items:center;display:flex}html.theme--catppuccin-frappe .navbar-link::after{display:none}html.theme--catppuccin-frappe .navbar-menu{background-color:#8caaee;box-shadow:0 8px 16px rgba(10,10,10,0.1);padding:0.5rem 0}html.theme--catppuccin-frappe .navbar-menu.is-active{display:block}html.theme--catppuccin-frappe .navbar.is-fixed-bottom-touch,html.theme--catppuccin-frappe .navbar.is-fixed-top-touch{left:0;position:fixed;right:0;z-index:30}html.theme--catppuccin-frappe .navbar.is-fixed-bottom-touch{bottom:0}html.theme--catppuccin-frappe .navbar.is-fixed-bottom-touch.has-shadow{box-shadow:0 -2px 3px rgba(10,10,10,0.1)}html.theme--catppuccin-frappe .navbar.is-fixed-top-touch{top:0}html.theme--catppuccin-frappe .navbar.is-fixed-top .navbar-menu,html.theme--catppuccin-frappe .navbar.is-fixed-top-touch .navbar-menu{-webkit-overflow-scrolling:touch;max-height:calc(100vh - 4rem);overflow:auto}html.theme--catppuccin-frappe html.has-navbar-fixed-top-touch,html.theme--catppuccin-frappe body.has-navbar-fixed-top-touch{padding-top:4rem}html.theme--catppuccin-frappe html.has-navbar-fixed-bottom-touch,html.theme--catppuccin-frappe body.has-navbar-fixed-bottom-touch{padding-bottom:4rem}}@media screen and (min-width: 1056px){html.theme--catppuccin-frappe .navbar,html.theme--catppuccin-frappe .navbar-menu,html.theme--catppuccin-frappe .navbar-start,html.theme--catppuccin-frappe .navbar-end{align-items:stretch;display:flex}html.theme--catppuccin-frappe .navbar{min-height:4rem}html.theme--catppuccin-frappe .navbar.is-spaced{padding:1rem 2rem}html.theme--catppuccin-frappe .navbar.is-spaced .navbar-start,html.theme--catppuccin-frappe .navbar.is-spaced .navbar-end{align-items:center}html.theme--catppuccin-frappe .navbar.is-spaced a.navbar-item,html.theme--catppuccin-frappe .navbar.is-spaced .navbar-link{border-radius:.4em}html.theme--catppuccin-frappe .navbar.is-transparent a.navbar-item:focus,html.theme--catppuccin-frappe .navbar.is-transparent a.navbar-item:hover,html.theme--catppuccin-frappe .navbar.is-transparent a.navbar-item.is-active,html.theme--catppuccin-frappe .navbar.is-transparent .navbar-link:focus,html.theme--catppuccin-frappe .navbar.is-transparent .navbar-link:hover,html.theme--catppuccin-frappe .navbar.is-transparent .navbar-link.is-active{background-color:transparent !important}html.theme--catppuccin-frappe .navbar.is-transparent .navbar-item.has-dropdown.is-active .navbar-link,html.theme--catppuccin-frappe .navbar.is-transparent .navbar-item.has-dropdown.is-hoverable:focus .navbar-link,html.theme--catppuccin-frappe .navbar.is-transparent .navbar-item.has-dropdown.is-hoverable:focus-within .navbar-link,html.theme--catppuccin-frappe .navbar.is-transparent .navbar-item.has-dropdown.is-hoverable:hover .navbar-link{background-color:transparent !important}html.theme--catppuccin-frappe .navbar.is-transparent .navbar-dropdown a.navbar-item:focus,html.theme--catppuccin-frappe .navbar.is-transparent .navbar-dropdown a.navbar-item:hover{background-color:rgba(0,0,0,0);color:#838ba7}html.theme--catppuccin-frappe .navbar.is-transparent .navbar-dropdown a.navbar-item.is-active{background-color:rgba(0,0,0,0);color:#8caaee}html.theme--catppuccin-frappe .navbar-burger{display:none}html.theme--catppuccin-frappe .navbar-item,html.theme--catppuccin-frappe .navbar-link{align-items:center;display:flex}html.theme--catppuccin-frappe .navbar-item.has-dropdown{align-items:stretch}html.theme--catppuccin-frappe .navbar-item.has-dropdown-up .navbar-link::after{transform:rotate(135deg) translate(0.25em, -0.25em)}html.theme--catppuccin-frappe .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--catppuccin-frappe .navbar-item.is-active .navbar-dropdown,html.theme--catppuccin-frappe .navbar-item.is-hoverable:focus .navbar-dropdown,html.theme--catppuccin-frappe .navbar-item.is-hoverable:focus-within .navbar-dropdown,html.theme--catppuccin-frappe .navbar-item.is-hoverable:hover .navbar-dropdown{display:block}.navbar.is-spaced html.theme--catppuccin-frappe .navbar-item.is-active .navbar-dropdown,html.theme--catppuccin-frappe .navbar-item.is-active .navbar-dropdown.is-boxed,.navbar.is-spaced html.theme--catppuccin-frappe .navbar-item.is-hoverable:focus .navbar-dropdown,html.theme--catppuccin-frappe .navbar-item.is-hoverable:focus .navbar-dropdown.is-boxed,.navbar.is-spaced html.theme--catppuccin-frappe .navbar-item.is-hoverable:focus-within .navbar-dropdown,html.theme--catppuccin-frappe .navbar-item.is-hoverable:focus-within .navbar-dropdown.is-boxed,.navbar.is-spaced html.theme--catppuccin-frappe .navbar-item.is-hoverable:hover .navbar-dropdown,html.theme--catppuccin-frappe .navbar-item.is-hoverable:hover .navbar-dropdown.is-boxed{opacity:1;pointer-events:auto;transform:translateY(0)}html.theme--catppuccin-frappe .navbar-menu{flex-grow:1;flex-shrink:0}html.theme--catppuccin-frappe .navbar-start{justify-content:flex-start;margin-right:auto}html.theme--catppuccin-frappe .navbar-end{justify-content:flex-end;margin-left:auto}html.theme--catppuccin-frappe .navbar-dropdown{background-color:#8caaee;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--catppuccin-frappe .navbar-dropdown .navbar-item{padding:0.375rem 1rem;white-space:nowrap}html.theme--catppuccin-frappe .navbar-dropdown a.navbar-item{padding-right:3rem}html.theme--catppuccin-frappe .navbar-dropdown a.navbar-item:focus,html.theme--catppuccin-frappe .navbar-dropdown a.navbar-item:hover{background-color:rgba(0,0,0,0);color:#838ba7}html.theme--catppuccin-frappe .navbar-dropdown a.navbar-item.is-active{background-color:rgba(0,0,0,0);color:#8caaee}.navbar.is-spaced html.theme--catppuccin-frappe .navbar-dropdown,html.theme--catppuccin-frappe .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--catppuccin-frappe .navbar-dropdown.is-right{left:auto;right:0}html.theme--catppuccin-frappe .navbar-divider{display:block}html.theme--catppuccin-frappe .navbar>.container .navbar-brand,html.theme--catppuccin-frappe .container>.navbar .navbar-brand{margin-left:-.75rem}html.theme--catppuccin-frappe .navbar>.container .navbar-menu,html.theme--catppuccin-frappe .container>.navbar .navbar-menu{margin-right:-.75rem}html.theme--catppuccin-frappe .navbar.is-fixed-bottom-desktop,html.theme--catppuccin-frappe .navbar.is-fixed-top-desktop{left:0;position:fixed;right:0;z-index:30}html.theme--catppuccin-frappe .navbar.is-fixed-bottom-desktop{bottom:0}html.theme--catppuccin-frappe .navbar.is-fixed-bottom-desktop.has-shadow{box-shadow:0 -2px 3px rgba(10,10,10,0.1)}html.theme--catppuccin-frappe .navbar.is-fixed-top-desktop{top:0}html.theme--catppuccin-frappe html.has-navbar-fixed-top-desktop,html.theme--catppuccin-frappe body.has-navbar-fixed-top-desktop{padding-top:4rem}html.theme--catppuccin-frappe html.has-navbar-fixed-bottom-desktop,html.theme--catppuccin-frappe body.has-navbar-fixed-bottom-desktop{padding-bottom:4rem}html.theme--catppuccin-frappe html.has-spaced-navbar-fixed-top,html.theme--catppuccin-frappe body.has-spaced-navbar-fixed-top{padding-top:6rem}html.theme--catppuccin-frappe html.has-spaced-navbar-fixed-bottom,html.theme--catppuccin-frappe body.has-spaced-navbar-fixed-bottom{padding-bottom:6rem}html.theme--catppuccin-frappe a.navbar-item.is-active,html.theme--catppuccin-frappe .navbar-link.is-active{color:#8caaee}html.theme--catppuccin-frappe a.navbar-item.is-active:not(:focus):not(:hover),html.theme--catppuccin-frappe .navbar-link.is-active:not(:focus):not(:hover){background-color:rgba(0,0,0,0)}html.theme--catppuccin-frappe .navbar-item.has-dropdown:focus .navbar-link,html.theme--catppuccin-frappe .navbar-item.has-dropdown:hover .navbar-link,html.theme--catppuccin-frappe .navbar-item.has-dropdown.is-active .navbar-link{background-color:rgba(0,0,0,0)}}html.theme--catppuccin-frappe .hero.is-fullheight-with-navbar{min-height:calc(100vh - 4rem)}html.theme--catppuccin-frappe .pagination{font-size:1rem;margin:-.25rem}html.theme--catppuccin-frappe .pagination.is-small,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.pagination{font-size:.75rem}html.theme--catppuccin-frappe .pagination.is-medium{font-size:1.25rem}html.theme--catppuccin-frappe .pagination.is-large{font-size:1.5rem}html.theme--catppuccin-frappe .pagination.is-rounded .pagination-previous,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.pagination .pagination-previous,html.theme--catppuccin-frappe .pagination.is-rounded .pagination-next,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.pagination .pagination-next{padding-left:1em;padding-right:1em;border-radius:9999px}html.theme--catppuccin-frappe .pagination.is-rounded .pagination-link,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.pagination .pagination-link{border-radius:9999px}html.theme--catppuccin-frappe .pagination,html.theme--catppuccin-frappe .pagination-list{align-items:center;display:flex;justify-content:center;text-align:center}html.theme--catppuccin-frappe .pagination-previous,html.theme--catppuccin-frappe .pagination-next,html.theme--catppuccin-frappe .pagination-link,html.theme--catppuccin-frappe .pagination-ellipsis{font-size:1em;justify-content:center;margin:.25rem;padding-left:.5em;padding-right:.5em;text-align:center}html.theme--catppuccin-frappe .pagination-previous,html.theme--catppuccin-frappe .pagination-next,html.theme--catppuccin-frappe .pagination-link{border-color:#626880;color:#8caaee;min-width:2.5em}html.theme--catppuccin-frappe .pagination-previous:hover,html.theme--catppuccin-frappe .pagination-next:hover,html.theme--catppuccin-frappe .pagination-link:hover{border-color:#737994;color:#99d1db}html.theme--catppuccin-frappe .pagination-previous:focus,html.theme--catppuccin-frappe .pagination-next:focus,html.theme--catppuccin-frappe .pagination-link:focus{border-color:#737994}html.theme--catppuccin-frappe .pagination-previous:active,html.theme--catppuccin-frappe .pagination-next:active,html.theme--catppuccin-frappe .pagination-link:active{box-shadow:inset 0 1px 2px rgba(10,10,10,0.2)}html.theme--catppuccin-frappe .pagination-previous[disabled],html.theme--catppuccin-frappe .pagination-previous.is-disabled,html.theme--catppuccin-frappe .pagination-next[disabled],html.theme--catppuccin-frappe .pagination-next.is-disabled,html.theme--catppuccin-frappe .pagination-link[disabled],html.theme--catppuccin-frappe .pagination-link.is-disabled{background-color:#626880;border-color:#626880;box-shadow:none;color:#f1f4fd;opacity:0.5}html.theme--catppuccin-frappe .pagination-previous,html.theme--catppuccin-frappe .pagination-next{padding-left:.75em;padding-right:.75em;white-space:nowrap}html.theme--catppuccin-frappe .pagination-link.is-current{background-color:#8caaee;border-color:#8caaee;color:#fff}html.theme--catppuccin-frappe .pagination-ellipsis{color:#737994;pointer-events:none}html.theme--catppuccin-frappe .pagination-list{flex-wrap:wrap}html.theme--catppuccin-frappe .pagination-list li{list-style:none}@media screen and (max-width: 768px){html.theme--catppuccin-frappe .pagination{flex-wrap:wrap}html.theme--catppuccin-frappe .pagination-previous,html.theme--catppuccin-frappe .pagination-next{flex-grow:1;flex-shrink:1}html.theme--catppuccin-frappe .pagination-list li{flex-grow:1;flex-shrink:1}}@media screen and (min-width: 769px),print{html.theme--catppuccin-frappe .pagination-list{flex-grow:1;flex-shrink:1;justify-content:flex-start;order:1}html.theme--catppuccin-frappe .pagination-previous,html.theme--catppuccin-frappe .pagination-next,html.theme--catppuccin-frappe .pagination-link,html.theme--catppuccin-frappe .pagination-ellipsis{margin-bottom:0;margin-top:0}html.theme--catppuccin-frappe .pagination-previous{order:2}html.theme--catppuccin-frappe .pagination-next{order:3}html.theme--catppuccin-frappe .pagination{justify-content:space-between;margin-bottom:0;margin-top:0}html.theme--catppuccin-frappe .pagination.is-centered .pagination-previous{order:1}html.theme--catppuccin-frappe .pagination.is-centered .pagination-list{justify-content:center;order:2}html.theme--catppuccin-frappe .pagination.is-centered .pagination-next{order:3}html.theme--catppuccin-frappe .pagination.is-right .pagination-previous{order:1}html.theme--catppuccin-frappe .pagination.is-right .pagination-next{order:2}html.theme--catppuccin-frappe .pagination.is-right .pagination-list{justify-content:flex-end;order:3}}html.theme--catppuccin-frappe .panel{border-radius:8px;box-shadow:#171717;font-size:1rem}html.theme--catppuccin-frappe .panel:not(:last-child){margin-bottom:1.5rem}html.theme--catppuccin-frappe .panel.is-white .panel-heading{background-color:#fff;color:#0a0a0a}html.theme--catppuccin-frappe .panel.is-white .panel-tabs a.is-active{border-bottom-color:#fff}html.theme--catppuccin-frappe .panel.is-white .panel-block.is-active .panel-icon{color:#fff}html.theme--catppuccin-frappe .panel.is-black .panel-heading{background-color:#0a0a0a;color:#fff}html.theme--catppuccin-frappe .panel.is-black .panel-tabs a.is-active{border-bottom-color:#0a0a0a}html.theme--catppuccin-frappe .panel.is-black .panel-block.is-active .panel-icon{color:#0a0a0a}html.theme--catppuccin-frappe .panel.is-light .panel-heading{background-color:#f5f5f5;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .panel.is-light .panel-tabs a.is-active{border-bottom-color:#f5f5f5}html.theme--catppuccin-frappe .panel.is-light .panel-block.is-active .panel-icon{color:#f5f5f5}html.theme--catppuccin-frappe .panel.is-dark .panel-heading,html.theme--catppuccin-frappe .content kbd.panel .panel-heading{background-color:#414559;color:#fff}html.theme--catppuccin-frappe .panel.is-dark .panel-tabs a.is-active,html.theme--catppuccin-frappe .content kbd.panel .panel-tabs a.is-active{border-bottom-color:#414559}html.theme--catppuccin-frappe .panel.is-dark .panel-block.is-active .panel-icon,html.theme--catppuccin-frappe .content kbd.panel .panel-block.is-active .panel-icon{color:#414559}html.theme--catppuccin-frappe .panel.is-primary .panel-heading,html.theme--catppuccin-frappe .docstring>section>a.panel.docs-sourcelink .panel-heading{background-color:#8caaee;color:#fff}html.theme--catppuccin-frappe .panel.is-primary .panel-tabs a.is-active,html.theme--catppuccin-frappe .docstring>section>a.panel.docs-sourcelink .panel-tabs a.is-active{border-bottom-color:#8caaee}html.theme--catppuccin-frappe .panel.is-primary .panel-block.is-active .panel-icon,html.theme--catppuccin-frappe .docstring>section>a.panel.docs-sourcelink .panel-block.is-active .panel-icon{color:#8caaee}html.theme--catppuccin-frappe .panel.is-link .panel-heading{background-color:#8caaee;color:#fff}html.theme--catppuccin-frappe .panel.is-link .panel-tabs a.is-active{border-bottom-color:#8caaee}html.theme--catppuccin-frappe .panel.is-link .panel-block.is-active .panel-icon{color:#8caaee}html.theme--catppuccin-frappe .panel.is-info .panel-heading{background-color:#81c8be;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .panel.is-info .panel-tabs a.is-active{border-bottom-color:#81c8be}html.theme--catppuccin-frappe .panel.is-info .panel-block.is-active .panel-icon{color:#81c8be}html.theme--catppuccin-frappe .panel.is-success .panel-heading{background-color:#a6d189;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .panel.is-success .panel-tabs a.is-active{border-bottom-color:#a6d189}html.theme--catppuccin-frappe .panel.is-success .panel-block.is-active .panel-icon{color:#a6d189}html.theme--catppuccin-frappe .panel.is-warning .panel-heading{background-color:#e5c890;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .panel.is-warning .panel-tabs a.is-active{border-bottom-color:#e5c890}html.theme--catppuccin-frappe .panel.is-warning .panel-block.is-active .panel-icon{color:#e5c890}html.theme--catppuccin-frappe .panel.is-danger .panel-heading{background-color:#e78284;color:#fff}html.theme--catppuccin-frappe .panel.is-danger .panel-tabs a.is-active{border-bottom-color:#e78284}html.theme--catppuccin-frappe .panel.is-danger .panel-block.is-active .panel-icon{color:#e78284}html.theme--catppuccin-frappe .panel-tabs:not(:last-child),html.theme--catppuccin-frappe .panel-block:not(:last-child){border-bottom:1px solid #ededed}html.theme--catppuccin-frappe .panel-heading{background-color:#51576d;border-radius:8px 8px 0 0;color:#b0bef1;font-size:1.25em;font-weight:700;line-height:1.25;padding:0.75em 1em}html.theme--catppuccin-frappe .panel-tabs{align-items:flex-end;display:flex;font-size:.875em;justify-content:center}html.theme--catppuccin-frappe .panel-tabs a{border-bottom:1px solid #626880;margin-bottom:-1px;padding:0.5em}html.theme--catppuccin-frappe .panel-tabs a.is-active{border-bottom-color:#51576d;color:#769aeb}html.theme--catppuccin-frappe .panel-list a{color:#c6d0f5}html.theme--catppuccin-frappe .panel-list a:hover{color:#8caaee}html.theme--catppuccin-frappe .panel-block{align-items:center;color:#b0bef1;display:flex;justify-content:flex-start;padding:0.5em 0.75em}html.theme--catppuccin-frappe .panel-block input[type="checkbox"]{margin-right:.75em}html.theme--catppuccin-frappe .panel-block>.control{flex-grow:1;flex-shrink:1;width:100%}html.theme--catppuccin-frappe .panel-block.is-wrapped{flex-wrap:wrap}html.theme--catppuccin-frappe .panel-block.is-active{border-left-color:#8caaee;color:#769aeb}html.theme--catppuccin-frappe .panel-block.is-active .panel-icon{color:#8caaee}html.theme--catppuccin-frappe .panel-block:last-child{border-bottom-left-radius:8px;border-bottom-right-radius:8px}html.theme--catppuccin-frappe a.panel-block,html.theme--catppuccin-frappe label.panel-block{cursor:pointer}html.theme--catppuccin-frappe a.panel-block:hover,html.theme--catppuccin-frappe label.panel-block:hover{background-color:#292c3c}html.theme--catppuccin-frappe .panel-icon{display:inline-block;font-size:14px;height:1em;line-height:1em;text-align:center;vertical-align:top;width:1em;color:#f1f4fd;margin-right:.75em}html.theme--catppuccin-frappe .panel-icon .fa{font-size:inherit;line-height:inherit}html.theme--catppuccin-frappe .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}html.theme--catppuccin-frappe .tabs a{align-items:center;border-bottom-color:#626880;border-bottom-style:solid;border-bottom-width:1px;color:#c6d0f5;display:flex;justify-content:center;margin-bottom:-1px;padding:0.5em 1em;vertical-align:top}html.theme--catppuccin-frappe .tabs a:hover{border-bottom-color:#b0bef1;color:#b0bef1}html.theme--catppuccin-frappe .tabs li{display:block}html.theme--catppuccin-frappe .tabs li.is-active a{border-bottom-color:#8caaee;color:#8caaee}html.theme--catppuccin-frappe .tabs ul{align-items:center;border-bottom-color:#626880;border-bottom-style:solid;border-bottom-width:1px;display:flex;flex-grow:1;flex-shrink:0;justify-content:flex-start}html.theme--catppuccin-frappe .tabs ul.is-left{padding-right:0.75em}html.theme--catppuccin-frappe .tabs ul.is-center{flex:none;justify-content:center;padding-left:0.75em;padding-right:0.75em}html.theme--catppuccin-frappe .tabs ul.is-right{justify-content:flex-end;padding-left:0.75em}html.theme--catppuccin-frappe .tabs .icon:first-child{margin-right:.5em}html.theme--catppuccin-frappe .tabs .icon:last-child{margin-left:.5em}html.theme--catppuccin-frappe .tabs.is-centered ul{justify-content:center}html.theme--catppuccin-frappe .tabs.is-right ul{justify-content:flex-end}html.theme--catppuccin-frappe .tabs.is-boxed a{border:1px solid transparent;border-radius:.4em .4em 0 0}html.theme--catppuccin-frappe .tabs.is-boxed a:hover{background-color:#292c3c;border-bottom-color:#626880}html.theme--catppuccin-frappe .tabs.is-boxed li.is-active a{background-color:#fff;border-color:#626880;border-bottom-color:rgba(0,0,0,0) !important}html.theme--catppuccin-frappe .tabs.is-fullwidth li{flex-grow:1;flex-shrink:0}html.theme--catppuccin-frappe .tabs.is-toggle a{border-color:#626880;border-style:solid;border-width:1px;margin-bottom:0;position:relative}html.theme--catppuccin-frappe .tabs.is-toggle a:hover{background-color:#292c3c;border-color:#737994;z-index:2}html.theme--catppuccin-frappe .tabs.is-toggle li+li{margin-left:-1px}html.theme--catppuccin-frappe .tabs.is-toggle li:first-child a{border-top-left-radius:.4em;border-bottom-left-radius:.4em}html.theme--catppuccin-frappe .tabs.is-toggle li:last-child a{border-top-right-radius:.4em;border-bottom-right-radius:.4em}html.theme--catppuccin-frappe .tabs.is-toggle li.is-active a{background-color:#8caaee;border-color:#8caaee;color:#fff;z-index:1}html.theme--catppuccin-frappe .tabs.is-toggle ul{border-bottom:none}html.theme--catppuccin-frappe .tabs.is-toggle.is-toggle-rounded li:first-child a{border-bottom-left-radius:9999px;border-top-left-radius:9999px;padding-left:1.25em}html.theme--catppuccin-frappe .tabs.is-toggle.is-toggle-rounded li:last-child a{border-bottom-right-radius:9999px;border-top-right-radius:9999px;padding-right:1.25em}html.theme--catppuccin-frappe .tabs.is-small,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.tabs{font-size:.75rem}html.theme--catppuccin-frappe .tabs.is-medium{font-size:1.25rem}html.theme--catppuccin-frappe .tabs.is-large{font-size:1.5rem}html.theme--catppuccin-frappe .column{display:block;flex-basis:0;flex-grow:1;flex-shrink:1;padding:.75rem}.columns.is-mobile>html.theme--catppuccin-frappe .column.is-narrow{flex:none;width:unset}.columns.is-mobile>html.theme--catppuccin-frappe .column.is-full{flex:none;width:100%}.columns.is-mobile>html.theme--catppuccin-frappe .column.is-three-quarters{flex:none;width:75%}.columns.is-mobile>html.theme--catppuccin-frappe .column.is-two-thirds{flex:none;width:66.6666%}.columns.is-mobile>html.theme--catppuccin-frappe .column.is-half{flex:none;width:50%}.columns.is-mobile>html.theme--catppuccin-frappe .column.is-one-third{flex:none;width:33.3333%}.columns.is-mobile>html.theme--catppuccin-frappe .column.is-one-quarter{flex:none;width:25%}.columns.is-mobile>html.theme--catppuccin-frappe .column.is-one-fifth{flex:none;width:20%}.columns.is-mobile>html.theme--catppuccin-frappe .column.is-two-fifths{flex:none;width:40%}.columns.is-mobile>html.theme--catppuccin-frappe .column.is-three-fifths{flex:none;width:60%}.columns.is-mobile>html.theme--catppuccin-frappe .column.is-four-fifths{flex:none;width:80%}.columns.is-mobile>html.theme--catppuccin-frappe .column.is-offset-three-quarters{margin-left:75%}.columns.is-mobile>html.theme--catppuccin-frappe .column.is-offset-two-thirds{margin-left:66.6666%}.columns.is-mobile>html.theme--catppuccin-frappe .column.is-offset-half{margin-left:50%}.columns.is-mobile>html.theme--catppuccin-frappe .column.is-offset-one-third{margin-left:33.3333%}.columns.is-mobile>html.theme--catppuccin-frappe .column.is-offset-one-quarter{margin-left:25%}.columns.is-mobile>html.theme--catppuccin-frappe .column.is-offset-one-fifth{margin-left:20%}.columns.is-mobile>html.theme--catppuccin-frappe .column.is-offset-two-fifths{margin-left:40%}.columns.is-mobile>html.theme--catppuccin-frappe .column.is-offset-three-fifths{margin-left:60%}.columns.is-mobile>html.theme--catppuccin-frappe .column.is-offset-four-fifths{margin-left:80%}.columns.is-mobile>html.theme--catppuccin-frappe .column.is-0{flex:none;width:0%}.columns.is-mobile>html.theme--catppuccin-frappe .column.is-offset-0{margin-left:0%}.columns.is-mobile>html.theme--catppuccin-frappe .column.is-1{flex:none;width:8.33333337%}.columns.is-mobile>html.theme--catppuccin-frappe .column.is-offset-1{margin-left:8.33333337%}.columns.is-mobile>html.theme--catppuccin-frappe .column.is-2{flex:none;width:16.66666674%}.columns.is-mobile>html.theme--catppuccin-frappe .column.is-offset-2{margin-left:16.66666674%}.columns.is-mobile>html.theme--catppuccin-frappe .column.is-3{flex:none;width:25%}.columns.is-mobile>html.theme--catppuccin-frappe .column.is-offset-3{margin-left:25%}.columns.is-mobile>html.theme--catppuccin-frappe .column.is-4{flex:none;width:33.33333337%}.columns.is-mobile>html.theme--catppuccin-frappe .column.is-offset-4{margin-left:33.33333337%}.columns.is-mobile>html.theme--catppuccin-frappe .column.is-5{flex:none;width:41.66666674%}.columns.is-mobile>html.theme--catppuccin-frappe .column.is-offset-5{margin-left:41.66666674%}.columns.is-mobile>html.theme--catppuccin-frappe .column.is-6{flex:none;width:50%}.columns.is-mobile>html.theme--catppuccin-frappe .column.is-offset-6{margin-left:50%}.columns.is-mobile>html.theme--catppuccin-frappe .column.is-7{flex:none;width:58.33333337%}.columns.is-mobile>html.theme--catppuccin-frappe .column.is-offset-7{margin-left:58.33333337%}.columns.is-mobile>html.theme--catppuccin-frappe .column.is-8{flex:none;width:66.66666674%}.columns.is-mobile>html.theme--catppuccin-frappe .column.is-offset-8{margin-left:66.66666674%}.columns.is-mobile>html.theme--catppuccin-frappe .column.is-9{flex:none;width:75%}.columns.is-mobile>html.theme--catppuccin-frappe .column.is-offset-9{margin-left:75%}.columns.is-mobile>html.theme--catppuccin-frappe .column.is-10{flex:none;width:83.33333337%}.columns.is-mobile>html.theme--catppuccin-frappe .column.is-offset-10{margin-left:83.33333337%}.columns.is-mobile>html.theme--catppuccin-frappe .column.is-11{flex:none;width:91.66666674%}.columns.is-mobile>html.theme--catppuccin-frappe .column.is-offset-11{margin-left:91.66666674%}.columns.is-mobile>html.theme--catppuccin-frappe .column.is-12{flex:none;width:100%}.columns.is-mobile>html.theme--catppuccin-frappe .column.is-offset-12{margin-left:100%}@media screen and (max-width: 768px){html.theme--catppuccin-frappe .column.is-narrow-mobile{flex:none;width:unset}html.theme--catppuccin-frappe .column.is-full-mobile{flex:none;width:100%}html.theme--catppuccin-frappe .column.is-three-quarters-mobile{flex:none;width:75%}html.theme--catppuccin-frappe .column.is-two-thirds-mobile{flex:none;width:66.6666%}html.theme--catppuccin-frappe .column.is-half-mobile{flex:none;width:50%}html.theme--catppuccin-frappe .column.is-one-third-mobile{flex:none;width:33.3333%}html.theme--catppuccin-frappe .column.is-one-quarter-mobile{flex:none;width:25%}html.theme--catppuccin-frappe .column.is-one-fifth-mobile{flex:none;width:20%}html.theme--catppuccin-frappe .column.is-two-fifths-mobile{flex:none;width:40%}html.theme--catppuccin-frappe .column.is-three-fifths-mobile{flex:none;width:60%}html.theme--catppuccin-frappe .column.is-four-fifths-mobile{flex:none;width:80%}html.theme--catppuccin-frappe .column.is-offset-three-quarters-mobile{margin-left:75%}html.theme--catppuccin-frappe .column.is-offset-two-thirds-mobile{margin-left:66.6666%}html.theme--catppuccin-frappe .column.is-offset-half-mobile{margin-left:50%}html.theme--catppuccin-frappe .column.is-offset-one-third-mobile{margin-left:33.3333%}html.theme--catppuccin-frappe .column.is-offset-one-quarter-mobile{margin-left:25%}html.theme--catppuccin-frappe .column.is-offset-one-fifth-mobile{margin-left:20%}html.theme--catppuccin-frappe .column.is-offset-two-fifths-mobile{margin-left:40%}html.theme--catppuccin-frappe .column.is-offset-three-fifths-mobile{margin-left:60%}html.theme--catppuccin-frappe .column.is-offset-four-fifths-mobile{margin-left:80%}html.theme--catppuccin-frappe .column.is-0-mobile{flex:none;width:0%}html.theme--catppuccin-frappe .column.is-offset-0-mobile{margin-left:0%}html.theme--catppuccin-frappe .column.is-1-mobile{flex:none;width:8.33333337%}html.theme--catppuccin-frappe .column.is-offset-1-mobile{margin-left:8.33333337%}html.theme--catppuccin-frappe .column.is-2-mobile{flex:none;width:16.66666674%}html.theme--catppuccin-frappe .column.is-offset-2-mobile{margin-left:16.66666674%}html.theme--catppuccin-frappe .column.is-3-mobile{flex:none;width:25%}html.theme--catppuccin-frappe .column.is-offset-3-mobile{margin-left:25%}html.theme--catppuccin-frappe .column.is-4-mobile{flex:none;width:33.33333337%}html.theme--catppuccin-frappe .column.is-offset-4-mobile{margin-left:33.33333337%}html.theme--catppuccin-frappe .column.is-5-mobile{flex:none;width:41.66666674%}html.theme--catppuccin-frappe .column.is-offset-5-mobile{margin-left:41.66666674%}html.theme--catppuccin-frappe .column.is-6-mobile{flex:none;width:50%}html.theme--catppuccin-frappe .column.is-offset-6-mobile{margin-left:50%}html.theme--catppuccin-frappe .column.is-7-mobile{flex:none;width:58.33333337%}html.theme--catppuccin-frappe .column.is-offset-7-mobile{margin-left:58.33333337%}html.theme--catppuccin-frappe .column.is-8-mobile{flex:none;width:66.66666674%}html.theme--catppuccin-frappe .column.is-offset-8-mobile{margin-left:66.66666674%}html.theme--catppuccin-frappe .column.is-9-mobile{flex:none;width:75%}html.theme--catppuccin-frappe .column.is-offset-9-mobile{margin-left:75%}html.theme--catppuccin-frappe .column.is-10-mobile{flex:none;width:83.33333337%}html.theme--catppuccin-frappe .column.is-offset-10-mobile{margin-left:83.33333337%}html.theme--catppuccin-frappe .column.is-11-mobile{flex:none;width:91.66666674%}html.theme--catppuccin-frappe .column.is-offset-11-mobile{margin-left:91.66666674%}html.theme--catppuccin-frappe .column.is-12-mobile{flex:none;width:100%}html.theme--catppuccin-frappe .column.is-offset-12-mobile{margin-left:100%}}@media screen and (min-width: 769px),print{html.theme--catppuccin-frappe .column.is-narrow,html.theme--catppuccin-frappe .column.is-narrow-tablet{flex:none;width:unset}html.theme--catppuccin-frappe .column.is-full,html.theme--catppuccin-frappe .column.is-full-tablet{flex:none;width:100%}html.theme--catppuccin-frappe .column.is-three-quarters,html.theme--catppuccin-frappe .column.is-three-quarters-tablet{flex:none;width:75%}html.theme--catppuccin-frappe .column.is-two-thirds,html.theme--catppuccin-frappe .column.is-two-thirds-tablet{flex:none;width:66.6666%}html.theme--catppuccin-frappe .column.is-half,html.theme--catppuccin-frappe .column.is-half-tablet{flex:none;width:50%}html.theme--catppuccin-frappe .column.is-one-third,html.theme--catppuccin-frappe .column.is-one-third-tablet{flex:none;width:33.3333%}html.theme--catppuccin-frappe .column.is-one-quarter,html.theme--catppuccin-frappe .column.is-one-quarter-tablet{flex:none;width:25%}html.theme--catppuccin-frappe .column.is-one-fifth,html.theme--catppuccin-frappe .column.is-one-fifth-tablet{flex:none;width:20%}html.theme--catppuccin-frappe .column.is-two-fifths,html.theme--catppuccin-frappe .column.is-two-fifths-tablet{flex:none;width:40%}html.theme--catppuccin-frappe .column.is-three-fifths,html.theme--catppuccin-frappe .column.is-three-fifths-tablet{flex:none;width:60%}html.theme--catppuccin-frappe .column.is-four-fifths,html.theme--catppuccin-frappe .column.is-four-fifths-tablet{flex:none;width:80%}html.theme--catppuccin-frappe .column.is-offset-three-quarters,html.theme--catppuccin-frappe .column.is-offset-three-quarters-tablet{margin-left:75%}html.theme--catppuccin-frappe .column.is-offset-two-thirds,html.theme--catppuccin-frappe .column.is-offset-two-thirds-tablet{margin-left:66.6666%}html.theme--catppuccin-frappe .column.is-offset-half,html.theme--catppuccin-frappe .column.is-offset-half-tablet{margin-left:50%}html.theme--catppuccin-frappe .column.is-offset-one-third,html.theme--catppuccin-frappe .column.is-offset-one-third-tablet{margin-left:33.3333%}html.theme--catppuccin-frappe .column.is-offset-one-quarter,html.theme--catppuccin-frappe .column.is-offset-one-quarter-tablet{margin-left:25%}html.theme--catppuccin-frappe .column.is-offset-one-fifth,html.theme--catppuccin-frappe .column.is-offset-one-fifth-tablet{margin-left:20%}html.theme--catppuccin-frappe .column.is-offset-two-fifths,html.theme--catppuccin-frappe .column.is-offset-two-fifths-tablet{margin-left:40%}html.theme--catppuccin-frappe .column.is-offset-three-fifths,html.theme--catppuccin-frappe .column.is-offset-three-fifths-tablet{margin-left:60%}html.theme--catppuccin-frappe .column.is-offset-four-fifths,html.theme--catppuccin-frappe .column.is-offset-four-fifths-tablet{margin-left:80%}html.theme--catppuccin-frappe .column.is-0,html.theme--catppuccin-frappe .column.is-0-tablet{flex:none;width:0%}html.theme--catppuccin-frappe .column.is-offset-0,html.theme--catppuccin-frappe .column.is-offset-0-tablet{margin-left:0%}html.theme--catppuccin-frappe .column.is-1,html.theme--catppuccin-frappe .column.is-1-tablet{flex:none;width:8.33333337%}html.theme--catppuccin-frappe .column.is-offset-1,html.theme--catppuccin-frappe .column.is-offset-1-tablet{margin-left:8.33333337%}html.theme--catppuccin-frappe .column.is-2,html.theme--catppuccin-frappe .column.is-2-tablet{flex:none;width:16.66666674%}html.theme--catppuccin-frappe .column.is-offset-2,html.theme--catppuccin-frappe .column.is-offset-2-tablet{margin-left:16.66666674%}html.theme--catppuccin-frappe .column.is-3,html.theme--catppuccin-frappe .column.is-3-tablet{flex:none;width:25%}html.theme--catppuccin-frappe .column.is-offset-3,html.theme--catppuccin-frappe .column.is-offset-3-tablet{margin-left:25%}html.theme--catppuccin-frappe .column.is-4,html.theme--catppuccin-frappe .column.is-4-tablet{flex:none;width:33.33333337%}html.theme--catppuccin-frappe .column.is-offset-4,html.theme--catppuccin-frappe .column.is-offset-4-tablet{margin-left:33.33333337%}html.theme--catppuccin-frappe .column.is-5,html.theme--catppuccin-frappe .column.is-5-tablet{flex:none;width:41.66666674%}html.theme--catppuccin-frappe .column.is-offset-5,html.theme--catppuccin-frappe .column.is-offset-5-tablet{margin-left:41.66666674%}html.theme--catppuccin-frappe .column.is-6,html.theme--catppuccin-frappe .column.is-6-tablet{flex:none;width:50%}html.theme--catppuccin-frappe .column.is-offset-6,html.theme--catppuccin-frappe .column.is-offset-6-tablet{margin-left:50%}html.theme--catppuccin-frappe .column.is-7,html.theme--catppuccin-frappe .column.is-7-tablet{flex:none;width:58.33333337%}html.theme--catppuccin-frappe .column.is-offset-7,html.theme--catppuccin-frappe .column.is-offset-7-tablet{margin-left:58.33333337%}html.theme--catppuccin-frappe .column.is-8,html.theme--catppuccin-frappe .column.is-8-tablet{flex:none;width:66.66666674%}html.theme--catppuccin-frappe .column.is-offset-8,html.theme--catppuccin-frappe .column.is-offset-8-tablet{margin-left:66.66666674%}html.theme--catppuccin-frappe .column.is-9,html.theme--catppuccin-frappe .column.is-9-tablet{flex:none;width:75%}html.theme--catppuccin-frappe .column.is-offset-9,html.theme--catppuccin-frappe .column.is-offset-9-tablet{margin-left:75%}html.theme--catppuccin-frappe .column.is-10,html.theme--catppuccin-frappe .column.is-10-tablet{flex:none;width:83.33333337%}html.theme--catppuccin-frappe .column.is-offset-10,html.theme--catppuccin-frappe .column.is-offset-10-tablet{margin-left:83.33333337%}html.theme--catppuccin-frappe .column.is-11,html.theme--catppuccin-frappe .column.is-11-tablet{flex:none;width:91.66666674%}html.theme--catppuccin-frappe .column.is-offset-11,html.theme--catppuccin-frappe .column.is-offset-11-tablet{margin-left:91.66666674%}html.theme--catppuccin-frappe .column.is-12,html.theme--catppuccin-frappe .column.is-12-tablet{flex:none;width:100%}html.theme--catppuccin-frappe .column.is-offset-12,html.theme--catppuccin-frappe .column.is-offset-12-tablet{margin-left:100%}}@media screen and (max-width: 1055px){html.theme--catppuccin-frappe .column.is-narrow-touch{flex:none;width:unset}html.theme--catppuccin-frappe .column.is-full-touch{flex:none;width:100%}html.theme--catppuccin-frappe .column.is-three-quarters-touch{flex:none;width:75%}html.theme--catppuccin-frappe .column.is-two-thirds-touch{flex:none;width:66.6666%}html.theme--catppuccin-frappe .column.is-half-touch{flex:none;width:50%}html.theme--catppuccin-frappe .column.is-one-third-touch{flex:none;width:33.3333%}html.theme--catppuccin-frappe .column.is-one-quarter-touch{flex:none;width:25%}html.theme--catppuccin-frappe .column.is-one-fifth-touch{flex:none;width:20%}html.theme--catppuccin-frappe .column.is-two-fifths-touch{flex:none;width:40%}html.theme--catppuccin-frappe .column.is-three-fifths-touch{flex:none;width:60%}html.theme--catppuccin-frappe .column.is-four-fifths-touch{flex:none;width:80%}html.theme--catppuccin-frappe .column.is-offset-three-quarters-touch{margin-left:75%}html.theme--catppuccin-frappe .column.is-offset-two-thirds-touch{margin-left:66.6666%}html.theme--catppuccin-frappe .column.is-offset-half-touch{margin-left:50%}html.theme--catppuccin-frappe .column.is-offset-one-third-touch{margin-left:33.3333%}html.theme--catppuccin-frappe .column.is-offset-one-quarter-touch{margin-left:25%}html.theme--catppuccin-frappe .column.is-offset-one-fifth-touch{margin-left:20%}html.theme--catppuccin-frappe .column.is-offset-two-fifths-touch{margin-left:40%}html.theme--catppuccin-frappe .column.is-offset-three-fifths-touch{margin-left:60%}html.theme--catppuccin-frappe .column.is-offset-four-fifths-touch{margin-left:80%}html.theme--catppuccin-frappe .column.is-0-touch{flex:none;width:0%}html.theme--catppuccin-frappe .column.is-offset-0-touch{margin-left:0%}html.theme--catppuccin-frappe .column.is-1-touch{flex:none;width:8.33333337%}html.theme--catppuccin-frappe .column.is-offset-1-touch{margin-left:8.33333337%}html.theme--catppuccin-frappe .column.is-2-touch{flex:none;width:16.66666674%}html.theme--catppuccin-frappe .column.is-offset-2-touch{margin-left:16.66666674%}html.theme--catppuccin-frappe .column.is-3-touch{flex:none;width:25%}html.theme--catppuccin-frappe .column.is-offset-3-touch{margin-left:25%}html.theme--catppuccin-frappe .column.is-4-touch{flex:none;width:33.33333337%}html.theme--catppuccin-frappe .column.is-offset-4-touch{margin-left:33.33333337%}html.theme--catppuccin-frappe .column.is-5-touch{flex:none;width:41.66666674%}html.theme--catppuccin-frappe .column.is-offset-5-touch{margin-left:41.66666674%}html.theme--catppuccin-frappe .column.is-6-touch{flex:none;width:50%}html.theme--catppuccin-frappe .column.is-offset-6-touch{margin-left:50%}html.theme--catppuccin-frappe .column.is-7-touch{flex:none;width:58.33333337%}html.theme--catppuccin-frappe .column.is-offset-7-touch{margin-left:58.33333337%}html.theme--catppuccin-frappe .column.is-8-touch{flex:none;width:66.66666674%}html.theme--catppuccin-frappe .column.is-offset-8-touch{margin-left:66.66666674%}html.theme--catppuccin-frappe .column.is-9-touch{flex:none;width:75%}html.theme--catppuccin-frappe .column.is-offset-9-touch{margin-left:75%}html.theme--catppuccin-frappe .column.is-10-touch{flex:none;width:83.33333337%}html.theme--catppuccin-frappe .column.is-offset-10-touch{margin-left:83.33333337%}html.theme--catppuccin-frappe .column.is-11-touch{flex:none;width:91.66666674%}html.theme--catppuccin-frappe .column.is-offset-11-touch{margin-left:91.66666674%}html.theme--catppuccin-frappe .column.is-12-touch{flex:none;width:100%}html.theme--catppuccin-frappe .column.is-offset-12-touch{margin-left:100%}}@media screen and (min-width: 1056px){html.theme--catppuccin-frappe .column.is-narrow-desktop{flex:none;width:unset}html.theme--catppuccin-frappe .column.is-full-desktop{flex:none;width:100%}html.theme--catppuccin-frappe .column.is-three-quarters-desktop{flex:none;width:75%}html.theme--catppuccin-frappe .column.is-two-thirds-desktop{flex:none;width:66.6666%}html.theme--catppuccin-frappe .column.is-half-desktop{flex:none;width:50%}html.theme--catppuccin-frappe .column.is-one-third-desktop{flex:none;width:33.3333%}html.theme--catppuccin-frappe .column.is-one-quarter-desktop{flex:none;width:25%}html.theme--catppuccin-frappe .column.is-one-fifth-desktop{flex:none;width:20%}html.theme--catppuccin-frappe .column.is-two-fifths-desktop{flex:none;width:40%}html.theme--catppuccin-frappe .column.is-three-fifths-desktop{flex:none;width:60%}html.theme--catppuccin-frappe .column.is-four-fifths-desktop{flex:none;width:80%}html.theme--catppuccin-frappe .column.is-offset-three-quarters-desktop{margin-left:75%}html.theme--catppuccin-frappe .column.is-offset-two-thirds-desktop{margin-left:66.6666%}html.theme--catppuccin-frappe .column.is-offset-half-desktop{margin-left:50%}html.theme--catppuccin-frappe .column.is-offset-one-third-desktop{margin-left:33.3333%}html.theme--catppuccin-frappe .column.is-offset-one-quarter-desktop{margin-left:25%}html.theme--catppuccin-frappe .column.is-offset-one-fifth-desktop{margin-left:20%}html.theme--catppuccin-frappe .column.is-offset-two-fifths-desktop{margin-left:40%}html.theme--catppuccin-frappe .column.is-offset-three-fifths-desktop{margin-left:60%}html.theme--catppuccin-frappe .column.is-offset-four-fifths-desktop{margin-left:80%}html.theme--catppuccin-frappe .column.is-0-desktop{flex:none;width:0%}html.theme--catppuccin-frappe .column.is-offset-0-desktop{margin-left:0%}html.theme--catppuccin-frappe .column.is-1-desktop{flex:none;width:8.33333337%}html.theme--catppuccin-frappe .column.is-offset-1-desktop{margin-left:8.33333337%}html.theme--catppuccin-frappe .column.is-2-desktop{flex:none;width:16.66666674%}html.theme--catppuccin-frappe .column.is-offset-2-desktop{margin-left:16.66666674%}html.theme--catppuccin-frappe .column.is-3-desktop{flex:none;width:25%}html.theme--catppuccin-frappe .column.is-offset-3-desktop{margin-left:25%}html.theme--catppuccin-frappe .column.is-4-desktop{flex:none;width:33.33333337%}html.theme--catppuccin-frappe .column.is-offset-4-desktop{margin-left:33.33333337%}html.theme--catppuccin-frappe .column.is-5-desktop{flex:none;width:41.66666674%}html.theme--catppuccin-frappe .column.is-offset-5-desktop{margin-left:41.66666674%}html.theme--catppuccin-frappe .column.is-6-desktop{flex:none;width:50%}html.theme--catppuccin-frappe .column.is-offset-6-desktop{margin-left:50%}html.theme--catppuccin-frappe .column.is-7-desktop{flex:none;width:58.33333337%}html.theme--catppuccin-frappe .column.is-offset-7-desktop{margin-left:58.33333337%}html.theme--catppuccin-frappe .column.is-8-desktop{flex:none;width:66.66666674%}html.theme--catppuccin-frappe .column.is-offset-8-desktop{margin-left:66.66666674%}html.theme--catppuccin-frappe .column.is-9-desktop{flex:none;width:75%}html.theme--catppuccin-frappe .column.is-offset-9-desktop{margin-left:75%}html.theme--catppuccin-frappe .column.is-10-desktop{flex:none;width:83.33333337%}html.theme--catppuccin-frappe .column.is-offset-10-desktop{margin-left:83.33333337%}html.theme--catppuccin-frappe .column.is-11-desktop{flex:none;width:91.66666674%}html.theme--catppuccin-frappe .column.is-offset-11-desktop{margin-left:91.66666674%}html.theme--catppuccin-frappe .column.is-12-desktop{flex:none;width:100%}html.theme--catppuccin-frappe .column.is-offset-12-desktop{margin-left:100%}}@media screen and (min-width: 1216px){html.theme--catppuccin-frappe .column.is-narrow-widescreen{flex:none;width:unset}html.theme--catppuccin-frappe .column.is-full-widescreen{flex:none;width:100%}html.theme--catppuccin-frappe .column.is-three-quarters-widescreen{flex:none;width:75%}html.theme--catppuccin-frappe .column.is-two-thirds-widescreen{flex:none;width:66.6666%}html.theme--catppuccin-frappe .column.is-half-widescreen{flex:none;width:50%}html.theme--catppuccin-frappe .column.is-one-third-widescreen{flex:none;width:33.3333%}html.theme--catppuccin-frappe .column.is-one-quarter-widescreen{flex:none;width:25%}html.theme--catppuccin-frappe .column.is-one-fifth-widescreen{flex:none;width:20%}html.theme--catppuccin-frappe .column.is-two-fifths-widescreen{flex:none;width:40%}html.theme--catppuccin-frappe .column.is-three-fifths-widescreen{flex:none;width:60%}html.theme--catppuccin-frappe .column.is-four-fifths-widescreen{flex:none;width:80%}html.theme--catppuccin-frappe .column.is-offset-three-quarters-widescreen{margin-left:75%}html.theme--catppuccin-frappe .column.is-offset-two-thirds-widescreen{margin-left:66.6666%}html.theme--catppuccin-frappe .column.is-offset-half-widescreen{margin-left:50%}html.theme--catppuccin-frappe .column.is-offset-one-third-widescreen{margin-left:33.3333%}html.theme--catppuccin-frappe .column.is-offset-one-quarter-widescreen{margin-left:25%}html.theme--catppuccin-frappe .column.is-offset-one-fifth-widescreen{margin-left:20%}html.theme--catppuccin-frappe .column.is-offset-two-fifths-widescreen{margin-left:40%}html.theme--catppuccin-frappe .column.is-offset-three-fifths-widescreen{margin-left:60%}html.theme--catppuccin-frappe .column.is-offset-four-fifths-widescreen{margin-left:80%}html.theme--catppuccin-frappe .column.is-0-widescreen{flex:none;width:0%}html.theme--catppuccin-frappe .column.is-offset-0-widescreen{margin-left:0%}html.theme--catppuccin-frappe .column.is-1-widescreen{flex:none;width:8.33333337%}html.theme--catppuccin-frappe .column.is-offset-1-widescreen{margin-left:8.33333337%}html.theme--catppuccin-frappe .column.is-2-widescreen{flex:none;width:16.66666674%}html.theme--catppuccin-frappe .column.is-offset-2-widescreen{margin-left:16.66666674%}html.theme--catppuccin-frappe .column.is-3-widescreen{flex:none;width:25%}html.theme--catppuccin-frappe .column.is-offset-3-widescreen{margin-left:25%}html.theme--catppuccin-frappe .column.is-4-widescreen{flex:none;width:33.33333337%}html.theme--catppuccin-frappe .column.is-offset-4-widescreen{margin-left:33.33333337%}html.theme--catppuccin-frappe .column.is-5-widescreen{flex:none;width:41.66666674%}html.theme--catppuccin-frappe .column.is-offset-5-widescreen{margin-left:41.66666674%}html.theme--catppuccin-frappe .column.is-6-widescreen{flex:none;width:50%}html.theme--catppuccin-frappe .column.is-offset-6-widescreen{margin-left:50%}html.theme--catppuccin-frappe .column.is-7-widescreen{flex:none;width:58.33333337%}html.theme--catppuccin-frappe .column.is-offset-7-widescreen{margin-left:58.33333337%}html.theme--catppuccin-frappe .column.is-8-widescreen{flex:none;width:66.66666674%}html.theme--catppuccin-frappe .column.is-offset-8-widescreen{margin-left:66.66666674%}html.theme--catppuccin-frappe .column.is-9-widescreen{flex:none;width:75%}html.theme--catppuccin-frappe .column.is-offset-9-widescreen{margin-left:75%}html.theme--catppuccin-frappe .column.is-10-widescreen{flex:none;width:83.33333337%}html.theme--catppuccin-frappe .column.is-offset-10-widescreen{margin-left:83.33333337%}html.theme--catppuccin-frappe .column.is-11-widescreen{flex:none;width:91.66666674%}html.theme--catppuccin-frappe .column.is-offset-11-widescreen{margin-left:91.66666674%}html.theme--catppuccin-frappe .column.is-12-widescreen{flex:none;width:100%}html.theme--catppuccin-frappe .column.is-offset-12-widescreen{margin-left:100%}}@media screen and (min-width: 1408px){html.theme--catppuccin-frappe .column.is-narrow-fullhd{flex:none;width:unset}html.theme--catppuccin-frappe .column.is-full-fullhd{flex:none;width:100%}html.theme--catppuccin-frappe .column.is-three-quarters-fullhd{flex:none;width:75%}html.theme--catppuccin-frappe .column.is-two-thirds-fullhd{flex:none;width:66.6666%}html.theme--catppuccin-frappe .column.is-half-fullhd{flex:none;width:50%}html.theme--catppuccin-frappe .column.is-one-third-fullhd{flex:none;width:33.3333%}html.theme--catppuccin-frappe .column.is-one-quarter-fullhd{flex:none;width:25%}html.theme--catppuccin-frappe .column.is-one-fifth-fullhd{flex:none;width:20%}html.theme--catppuccin-frappe .column.is-two-fifths-fullhd{flex:none;width:40%}html.theme--catppuccin-frappe .column.is-three-fifths-fullhd{flex:none;width:60%}html.theme--catppuccin-frappe .column.is-four-fifths-fullhd{flex:none;width:80%}html.theme--catppuccin-frappe .column.is-offset-three-quarters-fullhd{margin-left:75%}html.theme--catppuccin-frappe .column.is-offset-two-thirds-fullhd{margin-left:66.6666%}html.theme--catppuccin-frappe .column.is-offset-half-fullhd{margin-left:50%}html.theme--catppuccin-frappe .column.is-offset-one-third-fullhd{margin-left:33.3333%}html.theme--catppuccin-frappe .column.is-offset-one-quarter-fullhd{margin-left:25%}html.theme--catppuccin-frappe .column.is-offset-one-fifth-fullhd{margin-left:20%}html.theme--catppuccin-frappe .column.is-offset-two-fifths-fullhd{margin-left:40%}html.theme--catppuccin-frappe .column.is-offset-three-fifths-fullhd{margin-left:60%}html.theme--catppuccin-frappe .column.is-offset-four-fifths-fullhd{margin-left:80%}html.theme--catppuccin-frappe .column.is-0-fullhd{flex:none;width:0%}html.theme--catppuccin-frappe .column.is-offset-0-fullhd{margin-left:0%}html.theme--catppuccin-frappe .column.is-1-fullhd{flex:none;width:8.33333337%}html.theme--catppuccin-frappe .column.is-offset-1-fullhd{margin-left:8.33333337%}html.theme--catppuccin-frappe .column.is-2-fullhd{flex:none;width:16.66666674%}html.theme--catppuccin-frappe .column.is-offset-2-fullhd{margin-left:16.66666674%}html.theme--catppuccin-frappe .column.is-3-fullhd{flex:none;width:25%}html.theme--catppuccin-frappe .column.is-offset-3-fullhd{margin-left:25%}html.theme--catppuccin-frappe .column.is-4-fullhd{flex:none;width:33.33333337%}html.theme--catppuccin-frappe .column.is-offset-4-fullhd{margin-left:33.33333337%}html.theme--catppuccin-frappe .column.is-5-fullhd{flex:none;width:41.66666674%}html.theme--catppuccin-frappe .column.is-offset-5-fullhd{margin-left:41.66666674%}html.theme--catppuccin-frappe .column.is-6-fullhd{flex:none;width:50%}html.theme--catppuccin-frappe .column.is-offset-6-fullhd{margin-left:50%}html.theme--catppuccin-frappe .column.is-7-fullhd{flex:none;width:58.33333337%}html.theme--catppuccin-frappe .column.is-offset-7-fullhd{margin-left:58.33333337%}html.theme--catppuccin-frappe .column.is-8-fullhd{flex:none;width:66.66666674%}html.theme--catppuccin-frappe .column.is-offset-8-fullhd{margin-left:66.66666674%}html.theme--catppuccin-frappe .column.is-9-fullhd{flex:none;width:75%}html.theme--catppuccin-frappe .column.is-offset-9-fullhd{margin-left:75%}html.theme--catppuccin-frappe .column.is-10-fullhd{flex:none;width:83.33333337%}html.theme--catppuccin-frappe .column.is-offset-10-fullhd{margin-left:83.33333337%}html.theme--catppuccin-frappe .column.is-11-fullhd{flex:none;width:91.66666674%}html.theme--catppuccin-frappe .column.is-offset-11-fullhd{margin-left:91.66666674%}html.theme--catppuccin-frappe .column.is-12-fullhd{flex:none;width:100%}html.theme--catppuccin-frappe .column.is-offset-12-fullhd{margin-left:100%}}html.theme--catppuccin-frappe .columns{margin-left:-.75rem;margin-right:-.75rem;margin-top:-.75rem}html.theme--catppuccin-frappe .columns:last-child{margin-bottom:-.75rem}html.theme--catppuccin-frappe .columns:not(:last-child){margin-bottom:calc(1.5rem - .75rem)}html.theme--catppuccin-frappe .columns.is-centered{justify-content:center}html.theme--catppuccin-frappe .columns.is-gapless{margin-left:0;margin-right:0;margin-top:0}html.theme--catppuccin-frappe .columns.is-gapless>.column{margin:0;padding:0 !important}html.theme--catppuccin-frappe .columns.is-gapless:not(:last-child){margin-bottom:1.5rem}html.theme--catppuccin-frappe .columns.is-gapless:last-child{margin-bottom:0}html.theme--catppuccin-frappe .columns.is-mobile{display:flex}html.theme--catppuccin-frappe .columns.is-multiline{flex-wrap:wrap}html.theme--catppuccin-frappe .columns.is-vcentered{align-items:center}@media screen and (min-width: 769px),print{html.theme--catppuccin-frappe .columns:not(.is-desktop){display:flex}}@media screen and (min-width: 1056px){html.theme--catppuccin-frappe .columns.is-desktop{display:flex}}html.theme--catppuccin-frappe .columns.is-variable{--columnGap: 0.75rem;margin-left:calc(-1 * var(--columnGap));margin-right:calc(-1 * var(--columnGap))}html.theme--catppuccin-frappe .columns.is-variable>.column{padding-left:var(--columnGap);padding-right:var(--columnGap)}html.theme--catppuccin-frappe .columns.is-variable.is-0{--columnGap: 0rem}@media screen and (max-width: 768px){html.theme--catppuccin-frappe .columns.is-variable.is-0-mobile{--columnGap: 0rem}}@media screen and (min-width: 769px),print{html.theme--catppuccin-frappe .columns.is-variable.is-0-tablet{--columnGap: 0rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--catppuccin-frappe .columns.is-variable.is-0-tablet-only{--columnGap: 0rem}}@media screen and (max-width: 1055px){html.theme--catppuccin-frappe .columns.is-variable.is-0-touch{--columnGap: 0rem}}@media screen and (min-width: 1056px){html.theme--catppuccin-frappe .columns.is-variable.is-0-desktop{--columnGap: 0rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){html.theme--catppuccin-frappe .columns.is-variable.is-0-desktop-only{--columnGap: 0rem}}@media screen and (min-width: 1216px){html.theme--catppuccin-frappe .columns.is-variable.is-0-widescreen{--columnGap: 0rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){html.theme--catppuccin-frappe .columns.is-variable.is-0-widescreen-only{--columnGap: 0rem}}@media screen and (min-width: 1408px){html.theme--catppuccin-frappe .columns.is-variable.is-0-fullhd{--columnGap: 0rem}}html.theme--catppuccin-frappe .columns.is-variable.is-1{--columnGap: .25rem}@media screen and (max-width: 768px){html.theme--catppuccin-frappe .columns.is-variable.is-1-mobile{--columnGap: .25rem}}@media screen and (min-width: 769px),print{html.theme--catppuccin-frappe .columns.is-variable.is-1-tablet{--columnGap: .25rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--catppuccin-frappe .columns.is-variable.is-1-tablet-only{--columnGap: .25rem}}@media screen and (max-width: 1055px){html.theme--catppuccin-frappe .columns.is-variable.is-1-touch{--columnGap: .25rem}}@media screen and (min-width: 1056px){html.theme--catppuccin-frappe .columns.is-variable.is-1-desktop{--columnGap: .25rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){html.theme--catppuccin-frappe .columns.is-variable.is-1-desktop-only{--columnGap: .25rem}}@media screen and (min-width: 1216px){html.theme--catppuccin-frappe .columns.is-variable.is-1-widescreen{--columnGap: .25rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){html.theme--catppuccin-frappe .columns.is-variable.is-1-widescreen-only{--columnGap: .25rem}}@media screen and (min-width: 1408px){html.theme--catppuccin-frappe .columns.is-variable.is-1-fullhd{--columnGap: .25rem}}html.theme--catppuccin-frappe .columns.is-variable.is-2{--columnGap: .5rem}@media screen and (max-width: 768px){html.theme--catppuccin-frappe .columns.is-variable.is-2-mobile{--columnGap: .5rem}}@media screen and (min-width: 769px),print{html.theme--catppuccin-frappe .columns.is-variable.is-2-tablet{--columnGap: .5rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--catppuccin-frappe .columns.is-variable.is-2-tablet-only{--columnGap: .5rem}}@media screen and (max-width: 1055px){html.theme--catppuccin-frappe .columns.is-variable.is-2-touch{--columnGap: .5rem}}@media screen and (min-width: 1056px){html.theme--catppuccin-frappe .columns.is-variable.is-2-desktop{--columnGap: .5rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){html.theme--catppuccin-frappe .columns.is-variable.is-2-desktop-only{--columnGap: .5rem}}@media screen and (min-width: 1216px){html.theme--catppuccin-frappe .columns.is-variable.is-2-widescreen{--columnGap: .5rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){html.theme--catppuccin-frappe .columns.is-variable.is-2-widescreen-only{--columnGap: .5rem}}@media screen and (min-width: 1408px){html.theme--catppuccin-frappe .columns.is-variable.is-2-fullhd{--columnGap: .5rem}}html.theme--catppuccin-frappe .columns.is-variable.is-3{--columnGap: .75rem}@media screen and (max-width: 768px){html.theme--catppuccin-frappe .columns.is-variable.is-3-mobile{--columnGap: .75rem}}@media screen and (min-width: 769px),print{html.theme--catppuccin-frappe .columns.is-variable.is-3-tablet{--columnGap: .75rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--catppuccin-frappe .columns.is-variable.is-3-tablet-only{--columnGap: .75rem}}@media screen and (max-width: 1055px){html.theme--catppuccin-frappe .columns.is-variable.is-3-touch{--columnGap: .75rem}}@media screen and (min-width: 1056px){html.theme--catppuccin-frappe .columns.is-variable.is-3-desktop{--columnGap: .75rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){html.theme--catppuccin-frappe .columns.is-variable.is-3-desktop-only{--columnGap: .75rem}}@media screen and (min-width: 1216px){html.theme--catppuccin-frappe .columns.is-variable.is-3-widescreen{--columnGap: .75rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){html.theme--catppuccin-frappe .columns.is-variable.is-3-widescreen-only{--columnGap: .75rem}}@media screen and (min-width: 1408px){html.theme--catppuccin-frappe .columns.is-variable.is-3-fullhd{--columnGap: .75rem}}html.theme--catppuccin-frappe .columns.is-variable.is-4{--columnGap: 1rem}@media screen and (max-width: 768px){html.theme--catppuccin-frappe .columns.is-variable.is-4-mobile{--columnGap: 1rem}}@media screen and (min-width: 769px),print{html.theme--catppuccin-frappe .columns.is-variable.is-4-tablet{--columnGap: 1rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--catppuccin-frappe .columns.is-variable.is-4-tablet-only{--columnGap: 1rem}}@media screen and (max-width: 1055px){html.theme--catppuccin-frappe .columns.is-variable.is-4-touch{--columnGap: 1rem}}@media screen and (min-width: 1056px){html.theme--catppuccin-frappe .columns.is-variable.is-4-desktop{--columnGap: 1rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){html.theme--catppuccin-frappe .columns.is-variable.is-4-desktop-only{--columnGap: 1rem}}@media screen and (min-width: 1216px){html.theme--catppuccin-frappe .columns.is-variable.is-4-widescreen{--columnGap: 1rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){html.theme--catppuccin-frappe .columns.is-variable.is-4-widescreen-only{--columnGap: 1rem}}@media screen and (min-width: 1408px){html.theme--catppuccin-frappe .columns.is-variable.is-4-fullhd{--columnGap: 1rem}}html.theme--catppuccin-frappe .columns.is-variable.is-5{--columnGap: 1.25rem}@media screen and (max-width: 768px){html.theme--catppuccin-frappe .columns.is-variable.is-5-mobile{--columnGap: 1.25rem}}@media screen and (min-width: 769px),print{html.theme--catppuccin-frappe .columns.is-variable.is-5-tablet{--columnGap: 1.25rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--catppuccin-frappe .columns.is-variable.is-5-tablet-only{--columnGap: 1.25rem}}@media screen and (max-width: 1055px){html.theme--catppuccin-frappe .columns.is-variable.is-5-touch{--columnGap: 1.25rem}}@media screen and (min-width: 1056px){html.theme--catppuccin-frappe .columns.is-variable.is-5-desktop{--columnGap: 1.25rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){html.theme--catppuccin-frappe .columns.is-variable.is-5-desktop-only{--columnGap: 1.25rem}}@media screen and (min-width: 1216px){html.theme--catppuccin-frappe .columns.is-variable.is-5-widescreen{--columnGap: 1.25rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){html.theme--catppuccin-frappe .columns.is-variable.is-5-widescreen-only{--columnGap: 1.25rem}}@media screen and (min-width: 1408px){html.theme--catppuccin-frappe .columns.is-variable.is-5-fullhd{--columnGap: 1.25rem}}html.theme--catppuccin-frappe .columns.is-variable.is-6{--columnGap: 1.5rem}@media screen and (max-width: 768px){html.theme--catppuccin-frappe .columns.is-variable.is-6-mobile{--columnGap: 1.5rem}}@media screen and (min-width: 769px),print{html.theme--catppuccin-frappe .columns.is-variable.is-6-tablet{--columnGap: 1.5rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--catppuccin-frappe .columns.is-variable.is-6-tablet-only{--columnGap: 1.5rem}}@media screen and (max-width: 1055px){html.theme--catppuccin-frappe .columns.is-variable.is-6-touch{--columnGap: 1.5rem}}@media screen and (min-width: 1056px){html.theme--catppuccin-frappe .columns.is-variable.is-6-desktop{--columnGap: 1.5rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){html.theme--catppuccin-frappe .columns.is-variable.is-6-desktop-only{--columnGap: 1.5rem}}@media screen and (min-width: 1216px){html.theme--catppuccin-frappe .columns.is-variable.is-6-widescreen{--columnGap: 1.5rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){html.theme--catppuccin-frappe .columns.is-variable.is-6-widescreen-only{--columnGap: 1.5rem}}@media screen and (min-width: 1408px){html.theme--catppuccin-frappe .columns.is-variable.is-6-fullhd{--columnGap: 1.5rem}}html.theme--catppuccin-frappe .columns.is-variable.is-7{--columnGap: 1.75rem}@media screen and (max-width: 768px){html.theme--catppuccin-frappe .columns.is-variable.is-7-mobile{--columnGap: 1.75rem}}@media screen and (min-width: 769px),print{html.theme--catppuccin-frappe .columns.is-variable.is-7-tablet{--columnGap: 1.75rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--catppuccin-frappe .columns.is-variable.is-7-tablet-only{--columnGap: 1.75rem}}@media screen and (max-width: 1055px){html.theme--catppuccin-frappe .columns.is-variable.is-7-touch{--columnGap: 1.75rem}}@media screen and (min-width: 1056px){html.theme--catppuccin-frappe .columns.is-variable.is-7-desktop{--columnGap: 1.75rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){html.theme--catppuccin-frappe .columns.is-variable.is-7-desktop-only{--columnGap: 1.75rem}}@media screen and (min-width: 1216px){html.theme--catppuccin-frappe .columns.is-variable.is-7-widescreen{--columnGap: 1.75rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){html.theme--catppuccin-frappe .columns.is-variable.is-7-widescreen-only{--columnGap: 1.75rem}}@media screen and (min-width: 1408px){html.theme--catppuccin-frappe .columns.is-variable.is-7-fullhd{--columnGap: 1.75rem}}html.theme--catppuccin-frappe .columns.is-variable.is-8{--columnGap: 2rem}@media screen and (max-width: 768px){html.theme--catppuccin-frappe .columns.is-variable.is-8-mobile{--columnGap: 2rem}}@media screen and (min-width: 769px),print{html.theme--catppuccin-frappe .columns.is-variable.is-8-tablet{--columnGap: 2rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--catppuccin-frappe .columns.is-variable.is-8-tablet-only{--columnGap: 2rem}}@media screen and (max-width: 1055px){html.theme--catppuccin-frappe .columns.is-variable.is-8-touch{--columnGap: 2rem}}@media screen and (min-width: 1056px){html.theme--catppuccin-frappe .columns.is-variable.is-8-desktop{--columnGap: 2rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){html.theme--catppuccin-frappe .columns.is-variable.is-8-desktop-only{--columnGap: 2rem}}@media screen and (min-width: 1216px){html.theme--catppuccin-frappe .columns.is-variable.is-8-widescreen{--columnGap: 2rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){html.theme--catppuccin-frappe .columns.is-variable.is-8-widescreen-only{--columnGap: 2rem}}@media screen and (min-width: 1408px){html.theme--catppuccin-frappe .columns.is-variable.is-8-fullhd{--columnGap: 2rem}}html.theme--catppuccin-frappe .tile{align-items:stretch;display:block;flex-basis:0;flex-grow:1;flex-shrink:1;min-height:min-content}html.theme--catppuccin-frappe .tile.is-ancestor{margin-left:-.75rem;margin-right:-.75rem;margin-top:-.75rem}html.theme--catppuccin-frappe .tile.is-ancestor:last-child{margin-bottom:-.75rem}html.theme--catppuccin-frappe .tile.is-ancestor:not(:last-child){margin-bottom:.75rem}html.theme--catppuccin-frappe .tile.is-child{margin:0 !important}html.theme--catppuccin-frappe .tile.is-parent{padding:.75rem}html.theme--catppuccin-frappe .tile.is-vertical{flex-direction:column}html.theme--catppuccin-frappe .tile.is-vertical>.tile.is-child:not(:last-child){margin-bottom:1.5rem !important}@media screen and (min-width: 769px),print{html.theme--catppuccin-frappe .tile:not(.is-child){display:flex}html.theme--catppuccin-frappe .tile.is-1{flex:none;width:8.33333337%}html.theme--catppuccin-frappe .tile.is-2{flex:none;width:16.66666674%}html.theme--catppuccin-frappe .tile.is-3{flex:none;width:25%}html.theme--catppuccin-frappe .tile.is-4{flex:none;width:33.33333337%}html.theme--catppuccin-frappe .tile.is-5{flex:none;width:41.66666674%}html.theme--catppuccin-frappe .tile.is-6{flex:none;width:50%}html.theme--catppuccin-frappe .tile.is-7{flex:none;width:58.33333337%}html.theme--catppuccin-frappe .tile.is-8{flex:none;width:66.66666674%}html.theme--catppuccin-frappe .tile.is-9{flex:none;width:75%}html.theme--catppuccin-frappe .tile.is-10{flex:none;width:83.33333337%}html.theme--catppuccin-frappe .tile.is-11{flex:none;width:91.66666674%}html.theme--catppuccin-frappe .tile.is-12{flex:none;width:100%}}html.theme--catppuccin-frappe .hero{align-items:stretch;display:flex;flex-direction:column;justify-content:space-between}html.theme--catppuccin-frappe .hero .navbar{background:none}html.theme--catppuccin-frappe .hero .tabs ul{border-bottom:none}html.theme--catppuccin-frappe .hero.is-white{background-color:#fff;color:#0a0a0a}html.theme--catppuccin-frappe .hero.is-white a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--catppuccin-frappe .hero.is-white strong{color:inherit}html.theme--catppuccin-frappe .hero.is-white .title{color:#0a0a0a}html.theme--catppuccin-frappe .hero.is-white .subtitle{color:rgba(10,10,10,0.9)}html.theme--catppuccin-frappe .hero.is-white .subtitle a:not(.button),html.theme--catppuccin-frappe .hero.is-white .subtitle strong{color:#0a0a0a}@media screen and (max-width: 1055px){html.theme--catppuccin-frappe .hero.is-white .navbar-menu{background-color:#fff}}html.theme--catppuccin-frappe .hero.is-white .navbar-item,html.theme--catppuccin-frappe .hero.is-white .navbar-link{color:rgba(10,10,10,0.7)}html.theme--catppuccin-frappe .hero.is-white a.navbar-item:hover,html.theme--catppuccin-frappe .hero.is-white a.navbar-item.is-active,html.theme--catppuccin-frappe .hero.is-white .navbar-link:hover,html.theme--catppuccin-frappe .hero.is-white .navbar-link.is-active{background-color:#f2f2f2;color:#0a0a0a}html.theme--catppuccin-frappe .hero.is-white .tabs a{color:#0a0a0a;opacity:0.9}html.theme--catppuccin-frappe .hero.is-white .tabs a:hover{opacity:1}html.theme--catppuccin-frappe .hero.is-white .tabs li.is-active a{color:#fff !important;opacity:1}html.theme--catppuccin-frappe .hero.is-white .tabs.is-boxed a,html.theme--catppuccin-frappe .hero.is-white .tabs.is-toggle a{color:#0a0a0a}html.theme--catppuccin-frappe .hero.is-white .tabs.is-boxed a:hover,html.theme--catppuccin-frappe .hero.is-white .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--catppuccin-frappe .hero.is-white .tabs.is-boxed li.is-active a,html.theme--catppuccin-frappe .hero.is-white .tabs.is-boxed li.is-active a:hover,html.theme--catppuccin-frappe .hero.is-white .tabs.is-toggle li.is-active a,html.theme--catppuccin-frappe .hero.is-white .tabs.is-toggle li.is-active a:hover{background-color:#0a0a0a;border-color:#0a0a0a;color:#fff}html.theme--catppuccin-frappe .hero.is-white.is-bold{background-image:linear-gradient(141deg, #e8e3e4 0%, #fff 71%, #fff 100%)}@media screen and (max-width: 768px){html.theme--catppuccin-frappe .hero.is-white.is-bold .navbar-menu{background-image:linear-gradient(141deg, #e8e3e4 0%, #fff 71%, #fff 100%)}}html.theme--catppuccin-frappe .hero.is-black{background-color:#0a0a0a;color:#fff}html.theme--catppuccin-frappe .hero.is-black a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--catppuccin-frappe .hero.is-black strong{color:inherit}html.theme--catppuccin-frappe .hero.is-black .title{color:#fff}html.theme--catppuccin-frappe .hero.is-black .subtitle{color:rgba(255,255,255,0.9)}html.theme--catppuccin-frappe .hero.is-black .subtitle a:not(.button),html.theme--catppuccin-frappe .hero.is-black .subtitle strong{color:#fff}@media screen and (max-width: 1055px){html.theme--catppuccin-frappe .hero.is-black .navbar-menu{background-color:#0a0a0a}}html.theme--catppuccin-frappe .hero.is-black .navbar-item,html.theme--catppuccin-frappe .hero.is-black .navbar-link{color:rgba(255,255,255,0.7)}html.theme--catppuccin-frappe .hero.is-black a.navbar-item:hover,html.theme--catppuccin-frappe .hero.is-black a.navbar-item.is-active,html.theme--catppuccin-frappe .hero.is-black .navbar-link:hover,html.theme--catppuccin-frappe .hero.is-black .navbar-link.is-active{background-color:#000;color:#fff}html.theme--catppuccin-frappe .hero.is-black .tabs a{color:#fff;opacity:0.9}html.theme--catppuccin-frappe .hero.is-black .tabs a:hover{opacity:1}html.theme--catppuccin-frappe .hero.is-black .tabs li.is-active a{color:#0a0a0a !important;opacity:1}html.theme--catppuccin-frappe .hero.is-black .tabs.is-boxed a,html.theme--catppuccin-frappe .hero.is-black .tabs.is-toggle a{color:#fff}html.theme--catppuccin-frappe .hero.is-black .tabs.is-boxed a:hover,html.theme--catppuccin-frappe .hero.is-black .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--catppuccin-frappe .hero.is-black .tabs.is-boxed li.is-active a,html.theme--catppuccin-frappe .hero.is-black .tabs.is-boxed li.is-active a:hover,html.theme--catppuccin-frappe .hero.is-black .tabs.is-toggle li.is-active a,html.theme--catppuccin-frappe .hero.is-black .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#0a0a0a}html.theme--catppuccin-frappe .hero.is-black.is-bold{background-image:linear-gradient(141deg, #000 0%, #0a0a0a 71%, #181616 100%)}@media screen and (max-width: 768px){html.theme--catppuccin-frappe .hero.is-black.is-bold .navbar-menu{background-image:linear-gradient(141deg, #000 0%, #0a0a0a 71%, #181616 100%)}}html.theme--catppuccin-frappe .hero.is-light{background-color:#f5f5f5;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .hero.is-light a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--catppuccin-frappe .hero.is-light strong{color:inherit}html.theme--catppuccin-frappe .hero.is-light .title{color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .hero.is-light .subtitle{color:rgba(0,0,0,0.9)}html.theme--catppuccin-frappe .hero.is-light .subtitle a:not(.button),html.theme--catppuccin-frappe .hero.is-light .subtitle strong{color:rgba(0,0,0,0.7)}@media screen and (max-width: 1055px){html.theme--catppuccin-frappe .hero.is-light .navbar-menu{background-color:#f5f5f5}}html.theme--catppuccin-frappe .hero.is-light .navbar-item,html.theme--catppuccin-frappe .hero.is-light .navbar-link{color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .hero.is-light a.navbar-item:hover,html.theme--catppuccin-frappe .hero.is-light a.navbar-item.is-active,html.theme--catppuccin-frappe .hero.is-light .navbar-link:hover,html.theme--catppuccin-frappe .hero.is-light .navbar-link.is-active{background-color:#e8e8e8;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .hero.is-light .tabs a{color:rgba(0,0,0,0.7);opacity:0.9}html.theme--catppuccin-frappe .hero.is-light .tabs a:hover{opacity:1}html.theme--catppuccin-frappe .hero.is-light .tabs li.is-active a{color:#f5f5f5 !important;opacity:1}html.theme--catppuccin-frappe .hero.is-light .tabs.is-boxed a,html.theme--catppuccin-frappe .hero.is-light .tabs.is-toggle a{color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .hero.is-light .tabs.is-boxed a:hover,html.theme--catppuccin-frappe .hero.is-light .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--catppuccin-frappe .hero.is-light .tabs.is-boxed li.is-active a,html.theme--catppuccin-frappe .hero.is-light .tabs.is-boxed li.is-active a:hover,html.theme--catppuccin-frappe .hero.is-light .tabs.is-toggle li.is-active a,html.theme--catppuccin-frappe .hero.is-light .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:#f5f5f5}html.theme--catppuccin-frappe .hero.is-light.is-bold{background-image:linear-gradient(141deg, #dfd8d9 0%, #f5f5f5 71%, #fff 100%)}@media screen and (max-width: 768px){html.theme--catppuccin-frappe .hero.is-light.is-bold .navbar-menu{background-image:linear-gradient(141deg, #dfd8d9 0%, #f5f5f5 71%, #fff 100%)}}html.theme--catppuccin-frappe .hero.is-dark,html.theme--catppuccin-frappe .content kbd.hero{background-color:#414559;color:#fff}html.theme--catppuccin-frappe .hero.is-dark a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--catppuccin-frappe .content kbd.hero a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--catppuccin-frappe .hero.is-dark strong,html.theme--catppuccin-frappe .content kbd.hero strong{color:inherit}html.theme--catppuccin-frappe .hero.is-dark .title,html.theme--catppuccin-frappe .content kbd.hero .title{color:#fff}html.theme--catppuccin-frappe .hero.is-dark .subtitle,html.theme--catppuccin-frappe .content kbd.hero .subtitle{color:rgba(255,255,255,0.9)}html.theme--catppuccin-frappe .hero.is-dark .subtitle a:not(.button),html.theme--catppuccin-frappe .content kbd.hero .subtitle a:not(.button),html.theme--catppuccin-frappe .hero.is-dark .subtitle strong,html.theme--catppuccin-frappe .content kbd.hero .subtitle strong{color:#fff}@media screen and (max-width: 1055px){html.theme--catppuccin-frappe .hero.is-dark .navbar-menu,html.theme--catppuccin-frappe .content kbd.hero .navbar-menu{background-color:#414559}}html.theme--catppuccin-frappe .hero.is-dark .navbar-item,html.theme--catppuccin-frappe .content kbd.hero .navbar-item,html.theme--catppuccin-frappe .hero.is-dark .navbar-link,html.theme--catppuccin-frappe .content kbd.hero .navbar-link{color:rgba(255,255,255,0.7)}html.theme--catppuccin-frappe .hero.is-dark a.navbar-item:hover,html.theme--catppuccin-frappe .content kbd.hero a.navbar-item:hover,html.theme--catppuccin-frappe .hero.is-dark a.navbar-item.is-active,html.theme--catppuccin-frappe .content kbd.hero a.navbar-item.is-active,html.theme--catppuccin-frappe .hero.is-dark .navbar-link:hover,html.theme--catppuccin-frappe .content kbd.hero .navbar-link:hover,html.theme--catppuccin-frappe .hero.is-dark .navbar-link.is-active,html.theme--catppuccin-frappe .content kbd.hero .navbar-link.is-active{background-color:#363a4a;color:#fff}html.theme--catppuccin-frappe .hero.is-dark .tabs a,html.theme--catppuccin-frappe .content kbd.hero .tabs a{color:#fff;opacity:0.9}html.theme--catppuccin-frappe .hero.is-dark .tabs a:hover,html.theme--catppuccin-frappe .content kbd.hero .tabs a:hover{opacity:1}html.theme--catppuccin-frappe .hero.is-dark .tabs li.is-active a,html.theme--catppuccin-frappe .content kbd.hero .tabs li.is-active a{color:#414559 !important;opacity:1}html.theme--catppuccin-frappe .hero.is-dark .tabs.is-boxed a,html.theme--catppuccin-frappe .content kbd.hero .tabs.is-boxed a,html.theme--catppuccin-frappe .hero.is-dark .tabs.is-toggle a,html.theme--catppuccin-frappe .content kbd.hero .tabs.is-toggle a{color:#fff}html.theme--catppuccin-frappe .hero.is-dark .tabs.is-boxed a:hover,html.theme--catppuccin-frappe .content kbd.hero .tabs.is-boxed a:hover,html.theme--catppuccin-frappe .hero.is-dark .tabs.is-toggle a:hover,html.theme--catppuccin-frappe .content kbd.hero .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--catppuccin-frappe .hero.is-dark .tabs.is-boxed li.is-active a,html.theme--catppuccin-frappe .content kbd.hero .tabs.is-boxed li.is-active a,html.theme--catppuccin-frappe .hero.is-dark .tabs.is-boxed li.is-active a:hover,html.theme--catppuccin-frappe .hero.is-dark .tabs.is-toggle li.is-active a,html.theme--catppuccin-frappe .content kbd.hero .tabs.is-toggle li.is-active a,html.theme--catppuccin-frappe .hero.is-dark .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#414559}html.theme--catppuccin-frappe .hero.is-dark.is-bold,html.theme--catppuccin-frappe .content kbd.hero.is-bold{background-image:linear-gradient(141deg, #262f41 0%, #414559 71%, #47476c 100%)}@media screen and (max-width: 768px){html.theme--catppuccin-frappe .hero.is-dark.is-bold .navbar-menu,html.theme--catppuccin-frappe .content kbd.hero.is-bold .navbar-menu{background-image:linear-gradient(141deg, #262f41 0%, #414559 71%, #47476c 100%)}}html.theme--catppuccin-frappe .hero.is-primary,html.theme--catppuccin-frappe .docstring>section>a.hero.docs-sourcelink{background-color:#8caaee;color:#fff}html.theme--catppuccin-frappe .hero.is-primary a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--catppuccin-frappe .docstring>section>a.hero.docs-sourcelink a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--catppuccin-frappe .hero.is-primary strong,html.theme--catppuccin-frappe .docstring>section>a.hero.docs-sourcelink strong{color:inherit}html.theme--catppuccin-frappe .hero.is-primary .title,html.theme--catppuccin-frappe .docstring>section>a.hero.docs-sourcelink .title{color:#fff}html.theme--catppuccin-frappe .hero.is-primary .subtitle,html.theme--catppuccin-frappe .docstring>section>a.hero.docs-sourcelink .subtitle{color:rgba(255,255,255,0.9)}html.theme--catppuccin-frappe .hero.is-primary .subtitle a:not(.button),html.theme--catppuccin-frappe .docstring>section>a.hero.docs-sourcelink .subtitle a:not(.button),html.theme--catppuccin-frappe .hero.is-primary .subtitle strong,html.theme--catppuccin-frappe .docstring>section>a.hero.docs-sourcelink .subtitle strong{color:#fff}@media screen and (max-width: 1055px){html.theme--catppuccin-frappe .hero.is-primary .navbar-menu,html.theme--catppuccin-frappe .docstring>section>a.hero.docs-sourcelink .navbar-menu{background-color:#8caaee}}html.theme--catppuccin-frappe .hero.is-primary .navbar-item,html.theme--catppuccin-frappe .docstring>section>a.hero.docs-sourcelink .navbar-item,html.theme--catppuccin-frappe .hero.is-primary .navbar-link,html.theme--catppuccin-frappe .docstring>section>a.hero.docs-sourcelink .navbar-link{color:rgba(255,255,255,0.7)}html.theme--catppuccin-frappe .hero.is-primary a.navbar-item:hover,html.theme--catppuccin-frappe .docstring>section>a.hero.docs-sourcelink a.navbar-item:hover,html.theme--catppuccin-frappe .hero.is-primary a.navbar-item.is-active,html.theme--catppuccin-frappe .docstring>section>a.hero.docs-sourcelink a.navbar-item.is-active,html.theme--catppuccin-frappe .hero.is-primary .navbar-link:hover,html.theme--catppuccin-frappe .docstring>section>a.hero.docs-sourcelink .navbar-link:hover,html.theme--catppuccin-frappe .hero.is-primary .navbar-link.is-active,html.theme--catppuccin-frappe .docstring>section>a.hero.docs-sourcelink .navbar-link.is-active{background-color:#769aeb;color:#fff}html.theme--catppuccin-frappe .hero.is-primary .tabs a,html.theme--catppuccin-frappe .docstring>section>a.hero.docs-sourcelink .tabs a{color:#fff;opacity:0.9}html.theme--catppuccin-frappe .hero.is-primary .tabs a:hover,html.theme--catppuccin-frappe .docstring>section>a.hero.docs-sourcelink .tabs a:hover{opacity:1}html.theme--catppuccin-frappe .hero.is-primary .tabs li.is-active a,html.theme--catppuccin-frappe .docstring>section>a.hero.docs-sourcelink .tabs li.is-active a{color:#8caaee !important;opacity:1}html.theme--catppuccin-frappe .hero.is-primary .tabs.is-boxed a,html.theme--catppuccin-frappe .docstring>section>a.hero.docs-sourcelink .tabs.is-boxed a,html.theme--catppuccin-frappe .hero.is-primary .tabs.is-toggle a,html.theme--catppuccin-frappe .docstring>section>a.hero.docs-sourcelink .tabs.is-toggle a{color:#fff}html.theme--catppuccin-frappe .hero.is-primary .tabs.is-boxed a:hover,html.theme--catppuccin-frappe .docstring>section>a.hero.docs-sourcelink .tabs.is-boxed a:hover,html.theme--catppuccin-frappe .hero.is-primary .tabs.is-toggle a:hover,html.theme--catppuccin-frappe .docstring>section>a.hero.docs-sourcelink .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--catppuccin-frappe .hero.is-primary .tabs.is-boxed li.is-active a,html.theme--catppuccin-frappe .docstring>section>a.hero.docs-sourcelink .tabs.is-boxed li.is-active a,html.theme--catppuccin-frappe .hero.is-primary .tabs.is-boxed li.is-active a:hover,html.theme--catppuccin-frappe .hero.is-primary .tabs.is-toggle li.is-active a,html.theme--catppuccin-frappe .docstring>section>a.hero.docs-sourcelink .tabs.is-toggle li.is-active a,html.theme--catppuccin-frappe .hero.is-primary .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#8caaee}html.theme--catppuccin-frappe .hero.is-primary.is-bold,html.theme--catppuccin-frappe .docstring>section>a.hero.is-bold.docs-sourcelink{background-image:linear-gradient(141deg, #569ff1 0%, #8caaee 71%, #a0abf4 100%)}@media screen and (max-width: 768px){html.theme--catppuccin-frappe .hero.is-primary.is-bold .navbar-menu,html.theme--catppuccin-frappe .docstring>section>a.hero.is-bold.docs-sourcelink .navbar-menu{background-image:linear-gradient(141deg, #569ff1 0%, #8caaee 71%, #a0abf4 100%)}}html.theme--catppuccin-frappe .hero.is-link{background-color:#8caaee;color:#fff}html.theme--catppuccin-frappe .hero.is-link a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--catppuccin-frappe .hero.is-link strong{color:inherit}html.theme--catppuccin-frappe .hero.is-link .title{color:#fff}html.theme--catppuccin-frappe .hero.is-link .subtitle{color:rgba(255,255,255,0.9)}html.theme--catppuccin-frappe .hero.is-link .subtitle a:not(.button),html.theme--catppuccin-frappe .hero.is-link .subtitle strong{color:#fff}@media screen and (max-width: 1055px){html.theme--catppuccin-frappe .hero.is-link .navbar-menu{background-color:#8caaee}}html.theme--catppuccin-frappe .hero.is-link .navbar-item,html.theme--catppuccin-frappe .hero.is-link .navbar-link{color:rgba(255,255,255,0.7)}html.theme--catppuccin-frappe .hero.is-link a.navbar-item:hover,html.theme--catppuccin-frappe .hero.is-link a.navbar-item.is-active,html.theme--catppuccin-frappe .hero.is-link .navbar-link:hover,html.theme--catppuccin-frappe .hero.is-link .navbar-link.is-active{background-color:#769aeb;color:#fff}html.theme--catppuccin-frappe .hero.is-link .tabs a{color:#fff;opacity:0.9}html.theme--catppuccin-frappe .hero.is-link .tabs a:hover{opacity:1}html.theme--catppuccin-frappe .hero.is-link .tabs li.is-active a{color:#8caaee !important;opacity:1}html.theme--catppuccin-frappe .hero.is-link .tabs.is-boxed a,html.theme--catppuccin-frappe .hero.is-link .tabs.is-toggle a{color:#fff}html.theme--catppuccin-frappe .hero.is-link .tabs.is-boxed a:hover,html.theme--catppuccin-frappe .hero.is-link .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--catppuccin-frappe .hero.is-link .tabs.is-boxed li.is-active a,html.theme--catppuccin-frappe .hero.is-link .tabs.is-boxed li.is-active a:hover,html.theme--catppuccin-frappe .hero.is-link .tabs.is-toggle li.is-active a,html.theme--catppuccin-frappe .hero.is-link .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#8caaee}html.theme--catppuccin-frappe .hero.is-link.is-bold{background-image:linear-gradient(141deg, #569ff1 0%, #8caaee 71%, #a0abf4 100%)}@media screen and (max-width: 768px){html.theme--catppuccin-frappe .hero.is-link.is-bold .navbar-menu{background-image:linear-gradient(141deg, #569ff1 0%, #8caaee 71%, #a0abf4 100%)}}html.theme--catppuccin-frappe .hero.is-info{background-color:#81c8be;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .hero.is-info a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--catppuccin-frappe .hero.is-info strong{color:inherit}html.theme--catppuccin-frappe .hero.is-info .title{color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .hero.is-info .subtitle{color:rgba(0,0,0,0.9)}html.theme--catppuccin-frappe .hero.is-info .subtitle a:not(.button),html.theme--catppuccin-frappe .hero.is-info .subtitle strong{color:rgba(0,0,0,0.7)}@media screen and (max-width: 1055px){html.theme--catppuccin-frappe .hero.is-info .navbar-menu{background-color:#81c8be}}html.theme--catppuccin-frappe .hero.is-info .navbar-item,html.theme--catppuccin-frappe .hero.is-info .navbar-link{color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .hero.is-info a.navbar-item:hover,html.theme--catppuccin-frappe .hero.is-info a.navbar-item.is-active,html.theme--catppuccin-frappe .hero.is-info .navbar-link:hover,html.theme--catppuccin-frappe .hero.is-info .navbar-link.is-active{background-color:#6fc0b5;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .hero.is-info .tabs a{color:rgba(0,0,0,0.7);opacity:0.9}html.theme--catppuccin-frappe .hero.is-info .tabs a:hover{opacity:1}html.theme--catppuccin-frappe .hero.is-info .tabs li.is-active a{color:#81c8be !important;opacity:1}html.theme--catppuccin-frappe .hero.is-info .tabs.is-boxed a,html.theme--catppuccin-frappe .hero.is-info .tabs.is-toggle a{color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .hero.is-info .tabs.is-boxed a:hover,html.theme--catppuccin-frappe .hero.is-info .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--catppuccin-frappe .hero.is-info .tabs.is-boxed li.is-active a,html.theme--catppuccin-frappe .hero.is-info .tabs.is-boxed li.is-active a:hover,html.theme--catppuccin-frappe .hero.is-info .tabs.is-toggle li.is-active a,html.theme--catppuccin-frappe .hero.is-info .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:#81c8be}html.theme--catppuccin-frappe .hero.is-info.is-bold{background-image:linear-gradient(141deg, #52c4a1 0%, #81c8be 71%, #8fd2d4 100%)}@media screen and (max-width: 768px){html.theme--catppuccin-frappe .hero.is-info.is-bold .navbar-menu{background-image:linear-gradient(141deg, #52c4a1 0%, #81c8be 71%, #8fd2d4 100%)}}html.theme--catppuccin-frappe .hero.is-success{background-color:#a6d189;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .hero.is-success a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--catppuccin-frappe .hero.is-success strong{color:inherit}html.theme--catppuccin-frappe .hero.is-success .title{color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .hero.is-success .subtitle{color:rgba(0,0,0,0.9)}html.theme--catppuccin-frappe .hero.is-success .subtitle a:not(.button),html.theme--catppuccin-frappe .hero.is-success .subtitle strong{color:rgba(0,0,0,0.7)}@media screen and (max-width: 1055px){html.theme--catppuccin-frappe .hero.is-success .navbar-menu{background-color:#a6d189}}html.theme--catppuccin-frappe .hero.is-success .navbar-item,html.theme--catppuccin-frappe .hero.is-success .navbar-link{color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .hero.is-success a.navbar-item:hover,html.theme--catppuccin-frappe .hero.is-success a.navbar-item.is-active,html.theme--catppuccin-frappe .hero.is-success .navbar-link:hover,html.theme--catppuccin-frappe .hero.is-success .navbar-link.is-active{background-color:#98ca77;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .hero.is-success .tabs a{color:rgba(0,0,0,0.7);opacity:0.9}html.theme--catppuccin-frappe .hero.is-success .tabs a:hover{opacity:1}html.theme--catppuccin-frappe .hero.is-success .tabs li.is-active a{color:#a6d189 !important;opacity:1}html.theme--catppuccin-frappe .hero.is-success .tabs.is-boxed a,html.theme--catppuccin-frappe .hero.is-success .tabs.is-toggle a{color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .hero.is-success .tabs.is-boxed a:hover,html.theme--catppuccin-frappe .hero.is-success .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--catppuccin-frappe .hero.is-success .tabs.is-boxed li.is-active a,html.theme--catppuccin-frappe .hero.is-success .tabs.is-boxed li.is-active a:hover,html.theme--catppuccin-frappe .hero.is-success .tabs.is-toggle li.is-active a,html.theme--catppuccin-frappe .hero.is-success .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:#a6d189}html.theme--catppuccin-frappe .hero.is-success.is-bold{background-image:linear-gradient(141deg, #9ccd5a 0%, #a6d189 71%, #a8dc98 100%)}@media screen and (max-width: 768px){html.theme--catppuccin-frappe .hero.is-success.is-bold .navbar-menu{background-image:linear-gradient(141deg, #9ccd5a 0%, #a6d189 71%, #a8dc98 100%)}}html.theme--catppuccin-frappe .hero.is-warning{background-color:#e5c890;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .hero.is-warning a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--catppuccin-frappe .hero.is-warning strong{color:inherit}html.theme--catppuccin-frappe .hero.is-warning .title{color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .hero.is-warning .subtitle{color:rgba(0,0,0,0.9)}html.theme--catppuccin-frappe .hero.is-warning .subtitle a:not(.button),html.theme--catppuccin-frappe .hero.is-warning .subtitle strong{color:rgba(0,0,0,0.7)}@media screen and (max-width: 1055px){html.theme--catppuccin-frappe .hero.is-warning .navbar-menu{background-color:#e5c890}}html.theme--catppuccin-frappe .hero.is-warning .navbar-item,html.theme--catppuccin-frappe .hero.is-warning .navbar-link{color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .hero.is-warning a.navbar-item:hover,html.theme--catppuccin-frappe .hero.is-warning a.navbar-item.is-active,html.theme--catppuccin-frappe .hero.is-warning .navbar-link:hover,html.theme--catppuccin-frappe .hero.is-warning .navbar-link.is-active{background-color:#e0be7b;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .hero.is-warning .tabs a{color:rgba(0,0,0,0.7);opacity:0.9}html.theme--catppuccin-frappe .hero.is-warning .tabs a:hover{opacity:1}html.theme--catppuccin-frappe .hero.is-warning .tabs li.is-active a{color:#e5c890 !important;opacity:1}html.theme--catppuccin-frappe .hero.is-warning .tabs.is-boxed a,html.theme--catppuccin-frappe .hero.is-warning .tabs.is-toggle a{color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .hero.is-warning .tabs.is-boxed a:hover,html.theme--catppuccin-frappe .hero.is-warning .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--catppuccin-frappe .hero.is-warning .tabs.is-boxed li.is-active a,html.theme--catppuccin-frappe .hero.is-warning .tabs.is-boxed li.is-active a:hover,html.theme--catppuccin-frappe .hero.is-warning .tabs.is-toggle li.is-active a,html.theme--catppuccin-frappe .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:#e5c890}html.theme--catppuccin-frappe .hero.is-warning.is-bold{background-image:linear-gradient(141deg, #e5a05d 0%, #e5c890 71%, #ede0a2 100%)}@media screen and (max-width: 768px){html.theme--catppuccin-frappe .hero.is-warning.is-bold .navbar-menu{background-image:linear-gradient(141deg, #e5a05d 0%, #e5c890 71%, #ede0a2 100%)}}html.theme--catppuccin-frappe .hero.is-danger{background-color:#e78284;color:#fff}html.theme--catppuccin-frappe .hero.is-danger a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--catppuccin-frappe .hero.is-danger strong{color:inherit}html.theme--catppuccin-frappe .hero.is-danger .title{color:#fff}html.theme--catppuccin-frappe .hero.is-danger .subtitle{color:rgba(255,255,255,0.9)}html.theme--catppuccin-frappe .hero.is-danger .subtitle a:not(.button),html.theme--catppuccin-frappe .hero.is-danger .subtitle strong{color:#fff}@media screen and (max-width: 1055px){html.theme--catppuccin-frappe .hero.is-danger .navbar-menu{background-color:#e78284}}html.theme--catppuccin-frappe .hero.is-danger .navbar-item,html.theme--catppuccin-frappe .hero.is-danger .navbar-link{color:rgba(255,255,255,0.7)}html.theme--catppuccin-frappe .hero.is-danger a.navbar-item:hover,html.theme--catppuccin-frappe .hero.is-danger a.navbar-item.is-active,html.theme--catppuccin-frappe .hero.is-danger .navbar-link:hover,html.theme--catppuccin-frappe .hero.is-danger .navbar-link.is-active{background-color:#e36d6f;color:#fff}html.theme--catppuccin-frappe .hero.is-danger .tabs a{color:#fff;opacity:0.9}html.theme--catppuccin-frappe .hero.is-danger .tabs a:hover{opacity:1}html.theme--catppuccin-frappe .hero.is-danger .tabs li.is-active a{color:#e78284 !important;opacity:1}html.theme--catppuccin-frappe .hero.is-danger .tabs.is-boxed a,html.theme--catppuccin-frappe .hero.is-danger .tabs.is-toggle a{color:#fff}html.theme--catppuccin-frappe .hero.is-danger .tabs.is-boxed a:hover,html.theme--catppuccin-frappe .hero.is-danger .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--catppuccin-frappe .hero.is-danger .tabs.is-boxed li.is-active a,html.theme--catppuccin-frappe .hero.is-danger .tabs.is-boxed li.is-active a:hover,html.theme--catppuccin-frappe .hero.is-danger .tabs.is-toggle li.is-active a,html.theme--catppuccin-frappe .hero.is-danger .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#e78284}html.theme--catppuccin-frappe .hero.is-danger.is-bold{background-image:linear-gradient(141deg, #e94d6a 0%, #e78284 71%, #eea294 100%)}@media screen and (max-width: 768px){html.theme--catppuccin-frappe .hero.is-danger.is-bold .navbar-menu{background-image:linear-gradient(141deg, #e94d6a 0%, #e78284 71%, #eea294 100%)}}html.theme--catppuccin-frappe .hero.is-small .hero-body,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.hero .hero-body{padding:1.5rem}@media screen and (min-width: 769px),print{html.theme--catppuccin-frappe .hero.is-medium .hero-body{padding:9rem 4.5rem}}@media screen and (min-width: 769px),print{html.theme--catppuccin-frappe .hero.is-large .hero-body{padding:18rem 6rem}}html.theme--catppuccin-frappe .hero.is-halfheight .hero-body,html.theme--catppuccin-frappe .hero.is-fullheight .hero-body,html.theme--catppuccin-frappe .hero.is-fullheight-with-navbar .hero-body{align-items:center;display:flex}html.theme--catppuccin-frappe .hero.is-halfheight .hero-body>.container,html.theme--catppuccin-frappe .hero.is-fullheight .hero-body>.container,html.theme--catppuccin-frappe .hero.is-fullheight-with-navbar .hero-body>.container{flex-grow:1;flex-shrink:1}html.theme--catppuccin-frappe .hero.is-halfheight{min-height:50vh}html.theme--catppuccin-frappe .hero.is-fullheight{min-height:100vh}html.theme--catppuccin-frappe .hero-video{overflow:hidden}html.theme--catppuccin-frappe .hero-video video{left:50%;min-height:100%;min-width:100%;position:absolute;top:50%;transform:translate3d(-50%, -50%, 0)}html.theme--catppuccin-frappe .hero-video.is-transparent{opacity:0.3}@media screen and (max-width: 768px){html.theme--catppuccin-frappe .hero-video{display:none}}html.theme--catppuccin-frappe .hero-buttons{margin-top:1.5rem}@media screen and (max-width: 768px){html.theme--catppuccin-frappe .hero-buttons .button{display:flex}html.theme--catppuccin-frappe .hero-buttons .button:not(:last-child){margin-bottom:0.75rem}}@media screen and (min-width: 769px),print{html.theme--catppuccin-frappe .hero-buttons{display:flex;justify-content:center}html.theme--catppuccin-frappe .hero-buttons .button:not(:last-child){margin-right:1.5rem}}html.theme--catppuccin-frappe .hero-head,html.theme--catppuccin-frappe .hero-foot{flex-grow:0;flex-shrink:0}html.theme--catppuccin-frappe .hero-body{flex-grow:1;flex-shrink:0;padding:3rem 1.5rem}@media screen and (min-width: 769px),print{html.theme--catppuccin-frappe .hero-body{padding:3rem 3rem}}html.theme--catppuccin-frappe .section{padding:3rem 1.5rem}@media screen and (min-width: 1056px){html.theme--catppuccin-frappe .section{padding:3rem 3rem}html.theme--catppuccin-frappe .section.is-medium{padding:9rem 4.5rem}html.theme--catppuccin-frappe .section.is-large{padding:18rem 6rem}}html.theme--catppuccin-frappe .footer{background-color:#292c3c;padding:3rem 1.5rem 6rem}html.theme--catppuccin-frappe h1 .docs-heading-anchor,html.theme--catppuccin-frappe h1 .docs-heading-anchor:hover,html.theme--catppuccin-frappe h1 .docs-heading-anchor:visited,html.theme--catppuccin-frappe h2 .docs-heading-anchor,html.theme--catppuccin-frappe h2 .docs-heading-anchor:hover,html.theme--catppuccin-frappe h2 .docs-heading-anchor:visited,html.theme--catppuccin-frappe h3 .docs-heading-anchor,html.theme--catppuccin-frappe h3 .docs-heading-anchor:hover,html.theme--catppuccin-frappe h3 .docs-heading-anchor:visited,html.theme--catppuccin-frappe h4 .docs-heading-anchor,html.theme--catppuccin-frappe h4 .docs-heading-anchor:hover,html.theme--catppuccin-frappe h4 .docs-heading-anchor:visited,html.theme--catppuccin-frappe h5 .docs-heading-anchor,html.theme--catppuccin-frappe h5 .docs-heading-anchor:hover,html.theme--catppuccin-frappe h5 .docs-heading-anchor:visited,html.theme--catppuccin-frappe h6 .docs-heading-anchor,html.theme--catppuccin-frappe h6 .docs-heading-anchor:hover,html.theme--catppuccin-frappe h6 .docs-heading-anchor:visited{color:#c6d0f5}html.theme--catppuccin-frappe h1 .docs-heading-anchor-permalink,html.theme--catppuccin-frappe h2 .docs-heading-anchor-permalink,html.theme--catppuccin-frappe h3 .docs-heading-anchor-permalink,html.theme--catppuccin-frappe h4 .docs-heading-anchor-permalink,html.theme--catppuccin-frappe h5 .docs-heading-anchor-permalink,html.theme--catppuccin-frappe h6 .docs-heading-anchor-permalink{visibility:hidden;vertical-align:middle;margin-left:0.5em;font-size:0.7rem}html.theme--catppuccin-frappe h1 .docs-heading-anchor-permalink::before,html.theme--catppuccin-frappe h2 .docs-heading-anchor-permalink::before,html.theme--catppuccin-frappe h3 .docs-heading-anchor-permalink::before,html.theme--catppuccin-frappe h4 .docs-heading-anchor-permalink::before,html.theme--catppuccin-frappe h5 .docs-heading-anchor-permalink::before,html.theme--catppuccin-frappe h6 .docs-heading-anchor-permalink::before{font-family:"Font Awesome 6 Free";font-weight:900;content:"\f0c1"}html.theme--catppuccin-frappe h1:hover .docs-heading-anchor-permalink,html.theme--catppuccin-frappe h2:hover .docs-heading-anchor-permalink,html.theme--catppuccin-frappe h3:hover .docs-heading-anchor-permalink,html.theme--catppuccin-frappe h4:hover .docs-heading-anchor-permalink,html.theme--catppuccin-frappe h5:hover .docs-heading-anchor-permalink,html.theme--catppuccin-frappe h6:hover .docs-heading-anchor-permalink{visibility:visible}html.theme--catppuccin-frappe .docs-light-only{display:none !important}html.theme--catppuccin-frappe pre{position:relative;overflow:hidden}html.theme--catppuccin-frappe pre code,html.theme--catppuccin-frappe pre code.hljs{padding:0 .75rem !important;overflow:auto;display:block}html.theme--catppuccin-frappe pre code:first-of-type,html.theme--catppuccin-frappe pre code.hljs:first-of-type{padding-top:0.5rem !important}html.theme--catppuccin-frappe pre code:last-of-type,html.theme--catppuccin-frappe pre code.hljs:last-of-type{padding-bottom:0.5rem !important}html.theme--catppuccin-frappe 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 6 Free";color:#c6d0f5;cursor:pointer;text-align:center}html.theme--catppuccin-frappe pre .copy-button:focus,html.theme--catppuccin-frappe pre .copy-button:hover{opacity:1;background:rgba(198,208,245,0.1);color:#8caaee}html.theme--catppuccin-frappe pre .copy-button.success{color:#a6d189;opacity:1}html.theme--catppuccin-frappe pre .copy-button.error{color:#e78284;opacity:1}html.theme--catppuccin-frappe pre:hover .copy-button{opacity:1}html.theme--catppuccin-frappe .admonition{background-color:#292c3c;border-style:solid;border-width:2px;border-color:#b5bfe2;border-radius:4px;font-size:1rem}html.theme--catppuccin-frappe .admonition strong{color:currentColor}html.theme--catppuccin-frappe .admonition.is-small,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.admonition{font-size:.75rem}html.theme--catppuccin-frappe .admonition.is-medium{font-size:1.25rem}html.theme--catppuccin-frappe .admonition.is-large{font-size:1.5rem}html.theme--catppuccin-frappe .admonition.is-default{background-color:#292c3c;border-color:#b5bfe2}html.theme--catppuccin-frappe .admonition.is-default>.admonition-header{background-color:rgba(0,0,0,0);color:#b5bfe2}html.theme--catppuccin-frappe .admonition.is-default>.admonition-body{color:#c6d0f5}html.theme--catppuccin-frappe .admonition.is-info{background-color:#292c3c;border-color:#81c8be}html.theme--catppuccin-frappe .admonition.is-info>.admonition-header{background-color:rgba(0,0,0,0);color:#81c8be}html.theme--catppuccin-frappe .admonition.is-info>.admonition-body{color:#c6d0f5}html.theme--catppuccin-frappe .admonition.is-success{background-color:#292c3c;border-color:#a6d189}html.theme--catppuccin-frappe .admonition.is-success>.admonition-header{background-color:rgba(0,0,0,0);color:#a6d189}html.theme--catppuccin-frappe .admonition.is-success>.admonition-body{color:#c6d0f5}html.theme--catppuccin-frappe .admonition.is-warning{background-color:#292c3c;border-color:#e5c890}html.theme--catppuccin-frappe .admonition.is-warning>.admonition-header{background-color:rgba(0,0,0,0);color:#e5c890}html.theme--catppuccin-frappe .admonition.is-warning>.admonition-body{color:#c6d0f5}html.theme--catppuccin-frappe .admonition.is-danger{background-color:#292c3c;border-color:#e78284}html.theme--catppuccin-frappe .admonition.is-danger>.admonition-header{background-color:rgba(0,0,0,0);color:#e78284}html.theme--catppuccin-frappe .admonition.is-danger>.admonition-body{color:#c6d0f5}html.theme--catppuccin-frappe .admonition.is-compat{background-color:#292c3c;border-color:#99d1db}html.theme--catppuccin-frappe .admonition.is-compat>.admonition-header{background-color:rgba(0,0,0,0);color:#99d1db}html.theme--catppuccin-frappe .admonition.is-compat>.admonition-body{color:#c6d0f5}html.theme--catppuccin-frappe .admonition.is-todo{background-color:#292c3c;border-color:#ca9ee6}html.theme--catppuccin-frappe .admonition.is-todo>.admonition-header{background-color:rgba(0,0,0,0);color:#ca9ee6}html.theme--catppuccin-frappe .admonition.is-todo>.admonition-body{color:#c6d0f5}html.theme--catppuccin-frappe .admonition-header{color:#b5bfe2;background-color:rgba(0,0,0,0);align-items:center;font-weight:700;justify-content:space-between;line-height:1.25;padding:0.5rem .75rem;position:relative}html.theme--catppuccin-frappe .admonition-header:before{font-family:"Font Awesome 6 Free";font-weight:900;margin-right:.75rem;content:"\f06a"}html.theme--catppuccin-frappe details.admonition.is-details>.admonition-header{list-style:none}html.theme--catppuccin-frappe details.admonition.is-details>.admonition-header:before{font-family:"Font Awesome 6 Free";font-weight:900;content:"\f055"}html.theme--catppuccin-frappe details.admonition.is-details[open]>.admonition-header:before{font-family:"Font Awesome 6 Free";font-weight:900;content:"\f056"}html.theme--catppuccin-frappe .admonition-body{color:#c6d0f5;padding:0.5rem .75rem}html.theme--catppuccin-frappe .admonition-body pre{background-color:#292c3c}html.theme--catppuccin-frappe .admonition-body code{background-color:#292c3c}html.theme--catppuccin-frappe .docstring{margin-bottom:1em;background-color:rgba(0,0,0,0);border:2px solid #626880;border-radius:4px;box-shadow:none;max-width:100%}html.theme--catppuccin-frappe .docstring>header{cursor:pointer;display:flex;flex-grow:1;align-items:stretch;padding:0.5rem .75rem;background-color:#292c3c;box-shadow:0 0.125em 0.25em rgba(10,10,10,0.1);box-shadow:none;border-bottom:1px solid #626880;overflow:auto}html.theme--catppuccin-frappe .docstring>header code{background-color:transparent}html.theme--catppuccin-frappe .docstring>header .docstring-article-toggle-button{min-width:1.1rem;padding:0.2rem 0.2rem 0.2rem 0}html.theme--catppuccin-frappe .docstring>header .docstring-binding{margin-right:0.3em}html.theme--catppuccin-frappe .docstring>header .docstring-category{margin-left:0.3em}html.theme--catppuccin-frappe .docstring>section{position:relative;padding:.75rem .75rem;border-bottom:1px solid #626880}html.theme--catppuccin-frappe .docstring>section:last-child{border-bottom:none}html.theme--catppuccin-frappe .docstring>section>a.docs-sourcelink{transition:opacity 0.3s;opacity:0;position:absolute;right:.375rem;bottom:.375rem}html.theme--catppuccin-frappe .docstring>section>a.docs-sourcelink:focus{opacity:1 !important}html.theme--catppuccin-frappe .docstring:hover>section>a.docs-sourcelink{opacity:0.2}html.theme--catppuccin-frappe .docstring:focus-within>section>a.docs-sourcelink{opacity:0.2}html.theme--catppuccin-frappe .docstring>section:hover a.docs-sourcelink{opacity:1}html.theme--catppuccin-frappe .documenter-example-output{background-color:#303446}html.theme--catppuccin-frappe .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:#292c3c;color:#c6d0f5;border-bottom:3px solid rgba(0,0,0,0);padding:10px 35px;text-align:center;font-size:15px}html.theme--catppuccin-frappe .outdated-warning-overlay .outdated-warning-closer{position:absolute;top:calc(50% - 10px);right:18px;cursor:pointer;width:12px}html.theme--catppuccin-frappe .outdated-warning-overlay a{color:#8caaee}html.theme--catppuccin-frappe .outdated-warning-overlay a:hover{color:#99d1db}html.theme--catppuccin-frappe .content pre{border:2px solid #626880;border-radius:4px}html.theme--catppuccin-frappe .content code{font-weight:inherit}html.theme--catppuccin-frappe .content a code{color:#8caaee}html.theme--catppuccin-frappe .content a:hover code{color:#99d1db}html.theme--catppuccin-frappe .content h1 code,html.theme--catppuccin-frappe .content h2 code,html.theme--catppuccin-frappe .content h3 code,html.theme--catppuccin-frappe .content h4 code,html.theme--catppuccin-frappe .content h5 code,html.theme--catppuccin-frappe .content h6 code{color:#c6d0f5}html.theme--catppuccin-frappe .content table{display:block;width:initial;max-width:100%;overflow-x:auto}html.theme--catppuccin-frappe .content blockquote>ul:first-child,html.theme--catppuccin-frappe .content blockquote>ol:first-child,html.theme--catppuccin-frappe .content .admonition-body>ul:first-child,html.theme--catppuccin-frappe .content .admonition-body>ol:first-child{margin-top:0}html.theme--catppuccin-frappe pre,html.theme--catppuccin-frappe code{font-variant-ligatures:no-contextual}html.theme--catppuccin-frappe .breadcrumb a.is-disabled{cursor:default;pointer-events:none}html.theme--catppuccin-frappe .breadcrumb a.is-disabled,html.theme--catppuccin-frappe .breadcrumb a.is-disabled:hover{color:#b0bef1}html.theme--catppuccin-frappe .hljs{background:initial !important}html.theme--catppuccin-frappe .katex .katex-mathml{top:0;right:0}html.theme--catppuccin-frappe .katex-display,html.theme--catppuccin-frappe mjx-container,html.theme--catppuccin-frappe .MathJax_Display{margin:0.5em 0 !important}html.theme--catppuccin-frappe html{-moz-osx-font-smoothing:auto;-webkit-font-smoothing:auto}html.theme--catppuccin-frappe li.no-marker{list-style:none}html.theme--catppuccin-frappe #documenter .docs-main>article{overflow-wrap:break-word}html.theme--catppuccin-frappe #documenter .docs-main>article .math-container{overflow-x:auto;overflow-y:hidden}@media screen and (min-width: 1056px){html.theme--catppuccin-frappe #documenter .docs-main{max-width:52rem;margin-left:20rem;padding-right:1rem}}@media screen and (max-width: 1055px){html.theme--catppuccin-frappe #documenter .docs-main{width:100%}html.theme--catppuccin-frappe #documenter .docs-main>article{max-width:52rem;margin-left:auto;margin-right:auto;margin-bottom:1rem;padding:0 1rem}html.theme--catppuccin-frappe #documenter .docs-main>header,html.theme--catppuccin-frappe #documenter .docs-main>nav{max-width:100%;width:100%;margin:0}}html.theme--catppuccin-frappe #documenter .docs-main header.docs-navbar{background-color:#303446;border-bottom:1px solid #626880;z-index:2;min-height:4rem;margin-bottom:1rem;display:flex}html.theme--catppuccin-frappe #documenter .docs-main header.docs-navbar .breadcrumb{flex-grow:1;overflow-x:hidden}html.theme--catppuccin-frappe #documenter .docs-main header.docs-navbar .docs-sidebar-button{display:block;font-size:1.5rem;padding-bottom:0.1rem;margin-right:1rem}html.theme--catppuccin-frappe #documenter .docs-main header.docs-navbar .docs-right{display:flex;white-space:nowrap;gap:1rem;align-items:center}html.theme--catppuccin-frappe #documenter .docs-main header.docs-navbar .docs-right .docs-icon,html.theme--catppuccin-frappe #documenter .docs-main header.docs-navbar .docs-right .docs-label{display:inline-block}html.theme--catppuccin-frappe #documenter .docs-main header.docs-navbar .docs-right .docs-label{padding:0;margin-left:0.3em}@media screen and (max-width: 1055px){html.theme--catppuccin-frappe #documenter .docs-main header.docs-navbar .docs-right .docs-navbar-link{margin-left:0.4rem;margin-right:0.4rem}}html.theme--catppuccin-frappe #documenter .docs-main header.docs-navbar>*{margin:auto 0}@media screen and (max-width: 1055px){html.theme--catppuccin-frappe #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--catppuccin-frappe #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--catppuccin-frappe #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--catppuccin-frappe #documenter .docs-main section.footnotes{border-top:1px solid #626880}html.theme--catppuccin-frappe #documenter .docs-main section.footnotes li .tag:first-child,html.theme--catppuccin-frappe #documenter .docs-main section.footnotes li .docstring>section>a.docs-sourcelink:first-child,html.theme--catppuccin-frappe #documenter .docs-main section.footnotes li .content kbd:first-child,html.theme--catppuccin-frappe .content #documenter .docs-main section.footnotes li kbd:first-child{margin-right:1em;margin-bottom:0.4em}html.theme--catppuccin-frappe #documenter .docs-main .docs-footer{display:flex;flex-wrap:wrap;margin-left:0;margin-right:0;border-top:1px solid #626880;padding-top:1rem;padding-bottom:1rem}@media screen and (max-width: 1055px){html.theme--catppuccin-frappe #documenter .docs-main .docs-footer{padding-left:1rem;padding-right:1rem}}html.theme--catppuccin-frappe #documenter .docs-main .docs-footer .docs-footer-nextpage,html.theme--catppuccin-frappe #documenter .docs-main .docs-footer .docs-footer-prevpage{flex-grow:1}html.theme--catppuccin-frappe #documenter .docs-main .docs-footer .docs-footer-nextpage{text-align:right}html.theme--catppuccin-frappe #documenter .docs-main .docs-footer .flexbox-break{flex-basis:100%;height:0}html.theme--catppuccin-frappe #documenter .docs-main .docs-footer .footer-message{font-size:0.8em;margin:0.5em auto 0 auto;text-align:center}html.theme--catppuccin-frappe #documenter .docs-sidebar{display:flex;flex-direction:column;color:#c6d0f5;background-color:#292c3c;border-right:1px solid #626880;padding:0;flex:0 0 18rem;z-index:5;font-size:1rem;position:fixed;left:-18rem;width:18rem;height:100%;transition:left 0.3s}html.theme--catppuccin-frappe #documenter .docs-sidebar.visible{left:0;box-shadow:.4rem 0rem .8rem #171717}@media screen and (min-width: 1056px){html.theme--catppuccin-frappe #documenter .docs-sidebar.visible{box-shadow:none}}@media screen and (min-width: 1056px){html.theme--catppuccin-frappe #documenter .docs-sidebar{left:0;top:0}}html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo{margin-top:1rem;padding:0 1rem}html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img{max-height:6rem;margin:auto}html.theme--catppuccin-frappe #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--catppuccin-frappe #documenter .docs-sidebar .docs-package-name .docs-autofit{max-width:16.2rem}html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-package-name a,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-package-name a:hover{color:#c6d0f5}html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-version-selector{border-top:1px solid #626880;display:none;padding:0.5rem}html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-version-selector.visible{display:flex}html.theme--catppuccin-frappe #documenter .docs-sidebar ul.docs-menu{flex-grow:1;user-select:none;border-top:1px solid #626880;padding-bottom:1.5rem}html.theme--catppuccin-frappe #documenter .docs-sidebar ul.docs-menu>li>.tocitem{font-weight:bold}html.theme--catppuccin-frappe #documenter .docs-sidebar ul.docs-menu>li li{font-size:.95rem;margin-left:1em;border-left:1px solid #626880}html.theme--catppuccin-frappe #documenter .docs-sidebar ul.docs-menu input.collapse-toggle{display:none}html.theme--catppuccin-frappe #documenter .docs-sidebar ul.docs-menu ul.collapsed{display:none}html.theme--catppuccin-frappe #documenter .docs-sidebar ul.docs-menu input:checked~ul.collapsed{display:block}html.theme--catppuccin-frappe #documenter .docs-sidebar ul.docs-menu label.tocitem{display:flex}html.theme--catppuccin-frappe #documenter .docs-sidebar ul.docs-menu label.tocitem .docs-label{flex-grow:2}html.theme--catppuccin-frappe #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}html.theme--catppuccin-frappe #documenter .docs-sidebar ul.docs-menu label.tocitem .docs-chevron::before{font-family:"Font Awesome 6 Free";font-weight:900;content:"\f054"}html.theme--catppuccin-frappe #documenter .docs-sidebar ul.docs-menu input:checked~label.tocitem .docs-chevron::before{content:"\f078"}html.theme--catppuccin-frappe #documenter .docs-sidebar ul.docs-menu .tocitem{display:block;padding:0.5rem 0.5rem}html.theme--catppuccin-frappe #documenter .docs-sidebar ul.docs-menu .tocitem,html.theme--catppuccin-frappe #documenter .docs-sidebar ul.docs-menu .tocitem:hover{color:#c6d0f5;background:#292c3c}html.theme--catppuccin-frappe #documenter .docs-sidebar ul.docs-menu a.tocitem:hover,html.theme--catppuccin-frappe #documenter .docs-sidebar ul.docs-menu label.tocitem:hover{color:#c6d0f5;background-color:#313548}html.theme--catppuccin-frappe #documenter .docs-sidebar ul.docs-menu li.is-active{border-top:1px solid #626880;border-bottom:1px solid #626880;background-color:#232634}html.theme--catppuccin-frappe #documenter .docs-sidebar ul.docs-menu li.is-active .tocitem,html.theme--catppuccin-frappe #documenter .docs-sidebar ul.docs-menu li.is-active .tocitem:hover{background-color:#232634;color:#c6d0f5}html.theme--catppuccin-frappe #documenter .docs-sidebar ul.docs-menu li.is-active ul.internal .tocitem:hover{background-color:#313548;color:#c6d0f5}html.theme--catppuccin-frappe #documenter .docs-sidebar ul.docs-menu>li.is-active:first-child{border-top:none}html.theme--catppuccin-frappe #documenter .docs-sidebar ul.docs-menu ul.internal{margin:0 0.5rem 0.5rem;border-top:1px solid #626880}html.theme--catppuccin-frappe #documenter .docs-sidebar ul.docs-menu ul.internal li{font-size:.85rem;border-left:none;margin-left:0;margin-top:0.5rem}html.theme--catppuccin-frappe #documenter .docs-sidebar ul.docs-menu ul.internal .tocitem{width:100%;padding:0}html.theme--catppuccin-frappe #documenter .docs-sidebar ul.docs-menu ul.internal .tocitem::before{content:"⚬";margin-right:0.4em}html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search{margin:auto;margin-top:0.5rem;margin-bottom:0.5rem}html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input{width:14.4rem}html.theme--catppuccin-frappe #documenter .docs-sidebar #documenter-search-query{color:#868c98;width:14.4rem;box-shadow:inset 0 1px 2px rgba(10,10,10,0.1)}@media screen and (min-width: 1056px){html.theme--catppuccin-frappe #documenter .docs-sidebar ul.docs-menu{overflow-y:auto;-webkit-overflow-scroll:touch}html.theme--catppuccin-frappe #documenter .docs-sidebar ul.docs-menu::-webkit-scrollbar{width:.3rem;background:none}html.theme--catppuccin-frappe #documenter .docs-sidebar ul.docs-menu::-webkit-scrollbar-thumb{border-radius:5px 0px 0px 5px;background:#3a3e54}html.theme--catppuccin-frappe #documenter .docs-sidebar ul.docs-menu::-webkit-scrollbar-thumb:hover{background:#4a506c}}@media screen and (max-width: 1055px){html.theme--catppuccin-frappe #documenter .docs-sidebar{overflow-y:auto;-webkit-overflow-scroll:touch}html.theme--catppuccin-frappe #documenter .docs-sidebar::-webkit-scrollbar{width:.3rem;background:none}html.theme--catppuccin-frappe #documenter .docs-sidebar::-webkit-scrollbar-thumb{border-radius:5px 0px 0px 5px;background:#3a3e54}html.theme--catppuccin-frappe #documenter .docs-sidebar::-webkit-scrollbar-thumb:hover{background:#4a506c}}html.theme--catppuccin-frappe kbd.search-modal-key-hints{border-radius:0.25rem;border:1px solid rgba(245,245,245,0.6);box-shadow:0 2px 0 1px rgba(245,245,245,0.6);cursor:default;font-size:0.9rem;line-height:1.5;min-width:0.75rem;text-align:center;padding:0.1rem 0.3rem;position:relative;top:-1px}html.theme--catppuccin-frappe .search-min-width-50{min-width:50%}html.theme--catppuccin-frappe .search-min-height-100{min-height:100%}html.theme--catppuccin-frappe .search-modal-card-body{max-height:calc(100vh - 15rem)}html.theme--catppuccin-frappe .search-result-link{border-radius:0.7em;transition:all 300ms}html.theme--catppuccin-frappe .search-result-link:hover,html.theme--catppuccin-frappe .search-result-link:focus{background-color:rgba(0,128,128,0.1)}html.theme--catppuccin-frappe .search-result-link .property-search-result-badge,html.theme--catppuccin-frappe .search-result-link .search-filter{transition:all 300ms}html.theme--catppuccin-frappe .property-search-result-badge,html.theme--catppuccin-frappe .search-filter{padding:0.15em 0.5em;font-size:0.8em;font-style:italic;text-transform:none !important;line-height:1.5;color:#f5f5f5;background-color:rgba(51,65,85,0.501961);border-radius:0.6rem}html.theme--catppuccin-frappe .search-result-link:hover .property-search-result-badge,html.theme--catppuccin-frappe .search-result-link:hover .search-filter,html.theme--catppuccin-frappe .search-result-link:focus .property-search-result-badge,html.theme--catppuccin-frappe .search-result-link:focus .search-filter{color:#333;background-color:#f1f5f9}html.theme--catppuccin-frappe .search-filter{color:#333;background-color:#f5f5f5;transition:all 300ms}html.theme--catppuccin-frappe .search-filter:hover,html.theme--catppuccin-frappe .search-filter:focus{color:#333}html.theme--catppuccin-frappe .search-filter-selected{color:#414559;background-color:#babbf1}html.theme--catppuccin-frappe .search-filter-selected:hover,html.theme--catppuccin-frappe .search-filter-selected:focus{color:#414559}html.theme--catppuccin-frappe .search-result-highlight{background-color:#ffdd57;color:black}html.theme--catppuccin-frappe .search-divider{border-bottom:1px solid #626880}html.theme--catppuccin-frappe .search-result-title{width:85%;color:#f5f5f5}html.theme--catppuccin-frappe .search-result-code-title{font-size:0.875rem;font-family:"JuliaMono","SFMono-Regular","Menlo","Consolas","Liberation Mono","DejaVu Sans Mono",monospace}html.theme--catppuccin-frappe #search-modal .modal-card-body::-webkit-scrollbar,html.theme--catppuccin-frappe #search-modal .filter-tabs::-webkit-scrollbar{height:10px;width:10px;background-color:transparent}html.theme--catppuccin-frappe #search-modal .modal-card-body::-webkit-scrollbar-thumb,html.theme--catppuccin-frappe #search-modal .filter-tabs::-webkit-scrollbar-thumb{background-color:gray;border-radius:1rem}html.theme--catppuccin-frappe #search-modal .modal-card-body::-webkit-scrollbar-track,html.theme--catppuccin-frappe #search-modal .filter-tabs::-webkit-scrollbar-track{-webkit-box-shadow:inset 0 0 6px rgba(0,0,0,0.6);background-color:transparent}html.theme--catppuccin-frappe .w-100{width:100%}html.theme--catppuccin-frappe .gap-2{gap:0.5rem}html.theme--catppuccin-frappe .gap-4{gap:1rem}html.theme--catppuccin-frappe .gap-8{gap:2rem}html.theme--catppuccin-frappe{background-color:#303446;font-size:16px;min-width:300px;overflow-x:auto;overflow-y:scroll;text-rendering:optimizeLegibility;text-size-adjust:100%}html.theme--catppuccin-frappe a{transition:all 200ms ease}html.theme--catppuccin-frappe .label{color:#c6d0f5}html.theme--catppuccin-frappe .button,html.theme--catppuccin-frappe .control.has-icons-left .icon,html.theme--catppuccin-frappe .control.has-icons-right .icon,html.theme--catppuccin-frappe .input,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input,html.theme--catppuccin-frappe .pagination-ellipsis,html.theme--catppuccin-frappe .pagination-link,html.theme--catppuccin-frappe .pagination-next,html.theme--catppuccin-frappe .pagination-previous,html.theme--catppuccin-frappe .select,html.theme--catppuccin-frappe .select select,html.theme--catppuccin-frappe .textarea{height:2.5em;color:#c6d0f5}html.theme--catppuccin-frappe .input,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input,html.theme--catppuccin-frappe .textarea{transition:all 200ms ease;box-shadow:none;border-width:1px;padding-left:1em;padding-right:1em;color:#c6d0f5}html.theme--catppuccin-frappe .select:after,html.theme--catppuccin-frappe .select select{border-width:1px}html.theme--catppuccin-frappe .menu-list a{transition:all 300ms ease}html.theme--catppuccin-frappe .modal-card-foot,html.theme--catppuccin-frappe .modal-card-head{border-color:#626880}html.theme--catppuccin-frappe .navbar{border-radius:.4em}html.theme--catppuccin-frappe .navbar.is-transparent{background:none}html.theme--catppuccin-frappe .navbar.is-primary .navbar-dropdown a.navbar-item.is-active,html.theme--catppuccin-frappe .docstring>section>a.navbar.docs-sourcelink .navbar-dropdown a.navbar-item.is-active{background-color:#8caaee}@media screen and (max-width: 1055px){html.theme--catppuccin-frappe .navbar .navbar-menu{background-color:#8caaee;border-radius:0 0 .4em .4em}}html.theme--catppuccin-frappe .docstring>section>a.docs-sourcelink:not(body){color:#414559}html.theme--catppuccin-frappe .tag.is-link:not(body),html.theme--catppuccin-frappe .docstring>section>a.is-link.docs-sourcelink:not(body),html.theme--catppuccin-frappe .content kbd.is-link:not(body){color:#414559}html.theme--catppuccin-frappe .ansi span.sgr1{font-weight:bolder}html.theme--catppuccin-frappe .ansi span.sgr2{font-weight:lighter}html.theme--catppuccin-frappe .ansi span.sgr3{font-style:italic}html.theme--catppuccin-frappe .ansi span.sgr4{text-decoration:underline}html.theme--catppuccin-frappe .ansi span.sgr7{color:#303446;background-color:#c6d0f5}html.theme--catppuccin-frappe .ansi span.sgr8{color:transparent}html.theme--catppuccin-frappe .ansi span.sgr8 span{color:transparent}html.theme--catppuccin-frappe .ansi span.sgr9{text-decoration:line-through}html.theme--catppuccin-frappe .ansi span.sgr30{color:#51576d}html.theme--catppuccin-frappe .ansi span.sgr31{color:#e78284}html.theme--catppuccin-frappe .ansi span.sgr32{color:#a6d189}html.theme--catppuccin-frappe .ansi span.sgr33{color:#e5c890}html.theme--catppuccin-frappe .ansi span.sgr34{color:#8caaee}html.theme--catppuccin-frappe .ansi span.sgr35{color:#f4b8e4}html.theme--catppuccin-frappe .ansi span.sgr36{color:#81c8be}html.theme--catppuccin-frappe .ansi span.sgr37{color:#b5bfe2}html.theme--catppuccin-frappe .ansi span.sgr40{background-color:#51576d}html.theme--catppuccin-frappe .ansi span.sgr41{background-color:#e78284}html.theme--catppuccin-frappe .ansi span.sgr42{background-color:#a6d189}html.theme--catppuccin-frappe .ansi span.sgr43{background-color:#e5c890}html.theme--catppuccin-frappe .ansi span.sgr44{background-color:#8caaee}html.theme--catppuccin-frappe .ansi span.sgr45{background-color:#f4b8e4}html.theme--catppuccin-frappe .ansi span.sgr46{background-color:#81c8be}html.theme--catppuccin-frappe .ansi span.sgr47{background-color:#b5bfe2}html.theme--catppuccin-frappe .ansi span.sgr90{color:#626880}html.theme--catppuccin-frappe .ansi span.sgr91{color:#e78284}html.theme--catppuccin-frappe .ansi span.sgr92{color:#a6d189}html.theme--catppuccin-frappe .ansi span.sgr93{color:#e5c890}html.theme--catppuccin-frappe .ansi span.sgr94{color:#8caaee}html.theme--catppuccin-frappe .ansi span.sgr95{color:#f4b8e4}html.theme--catppuccin-frappe .ansi span.sgr96{color:#81c8be}html.theme--catppuccin-frappe .ansi span.sgr97{color:#a5adce}html.theme--catppuccin-frappe .ansi span.sgr100{background-color:#626880}html.theme--catppuccin-frappe .ansi span.sgr101{background-color:#e78284}html.theme--catppuccin-frappe .ansi span.sgr102{background-color:#a6d189}html.theme--catppuccin-frappe .ansi span.sgr103{background-color:#e5c890}html.theme--catppuccin-frappe .ansi span.sgr104{background-color:#8caaee}html.theme--catppuccin-frappe .ansi span.sgr105{background-color:#f4b8e4}html.theme--catppuccin-frappe .ansi span.sgr106{background-color:#81c8be}html.theme--catppuccin-frappe .ansi span.sgr107{background-color:#a5adce}html.theme--catppuccin-frappe code.language-julia-repl>span.hljs-meta{color:#a6d189;font-weight:bolder}html.theme--catppuccin-frappe code .hljs{color:#c6d0f5;background:#303446}html.theme--catppuccin-frappe code .hljs-keyword{color:#ca9ee6}html.theme--catppuccin-frappe code .hljs-built_in{color:#e78284}html.theme--catppuccin-frappe code .hljs-type{color:#e5c890}html.theme--catppuccin-frappe code .hljs-literal{color:#ef9f76}html.theme--catppuccin-frappe code .hljs-number{color:#ef9f76}html.theme--catppuccin-frappe code .hljs-operator{color:#81c8be}html.theme--catppuccin-frappe code .hljs-punctuation{color:#b5bfe2}html.theme--catppuccin-frappe code .hljs-property{color:#81c8be}html.theme--catppuccin-frappe code .hljs-regexp{color:#f4b8e4}html.theme--catppuccin-frappe code .hljs-string{color:#a6d189}html.theme--catppuccin-frappe code .hljs-char.escape_{color:#a6d189}html.theme--catppuccin-frappe code .hljs-subst{color:#a5adce}html.theme--catppuccin-frappe code .hljs-symbol{color:#eebebe}html.theme--catppuccin-frappe code .hljs-variable{color:#ca9ee6}html.theme--catppuccin-frappe code .hljs-variable.language_{color:#ca9ee6}html.theme--catppuccin-frappe code .hljs-variable.constant_{color:#ef9f76}html.theme--catppuccin-frappe code .hljs-title{color:#8caaee}html.theme--catppuccin-frappe code .hljs-title.class_{color:#e5c890}html.theme--catppuccin-frappe code .hljs-title.function_{color:#8caaee}html.theme--catppuccin-frappe code .hljs-params{color:#c6d0f5}html.theme--catppuccin-frappe code .hljs-comment{color:#626880}html.theme--catppuccin-frappe code .hljs-doctag{color:#e78284}html.theme--catppuccin-frappe code .hljs-meta{color:#ef9f76}html.theme--catppuccin-frappe code .hljs-section{color:#8caaee}html.theme--catppuccin-frappe code .hljs-tag{color:#a5adce}html.theme--catppuccin-frappe code .hljs-name{color:#ca9ee6}html.theme--catppuccin-frappe code .hljs-attr{color:#8caaee}html.theme--catppuccin-frappe code .hljs-attribute{color:#a6d189}html.theme--catppuccin-frappe code .hljs-bullet{color:#81c8be}html.theme--catppuccin-frappe code .hljs-code{color:#a6d189}html.theme--catppuccin-frappe code .hljs-emphasis{color:#e78284;font-style:italic}html.theme--catppuccin-frappe code .hljs-strong{color:#e78284;font-weight:bold}html.theme--catppuccin-frappe code .hljs-formula{color:#81c8be}html.theme--catppuccin-frappe code .hljs-link{color:#85c1dc;font-style:italic}html.theme--catppuccin-frappe code .hljs-quote{color:#a6d189;font-style:italic}html.theme--catppuccin-frappe code .hljs-selector-tag{color:#e5c890}html.theme--catppuccin-frappe code .hljs-selector-id{color:#8caaee}html.theme--catppuccin-frappe code .hljs-selector-class{color:#81c8be}html.theme--catppuccin-frappe code .hljs-selector-attr{color:#ca9ee6}html.theme--catppuccin-frappe code .hljs-selector-pseudo{color:#81c8be}html.theme--catppuccin-frappe code .hljs-template-tag{color:#eebebe}html.theme--catppuccin-frappe code .hljs-template-variable{color:#eebebe}html.theme--catppuccin-frappe code .hljs-addition{color:#a6d189;background:rgba(166,227,161,0.15)}html.theme--catppuccin-frappe code .hljs-deletion{color:#e78284;background:rgba(243,139,168,0.15)}html.theme--catppuccin-frappe .search-result-link{border-radius:0.7em;transition:all 300ms}html.theme--catppuccin-frappe .search-result-link:hover,html.theme--catppuccin-frappe .search-result-link:focus{background-color:#414559}html.theme--catppuccin-frappe .search-result-link .property-search-result-badge,html.theme--catppuccin-frappe .search-result-link .search-filter{transition:all 300ms}html.theme--catppuccin-frappe .search-result-link:hover .property-search-result-badge,html.theme--catppuccin-frappe .search-result-link:hover .search-filter,html.theme--catppuccin-frappe .search-result-link:focus .property-search-result-badge,html.theme--catppuccin-frappe .search-result-link:focus .search-filter{color:#414559 !important;background-color:#babbf1 !important}html.theme--catppuccin-frappe .search-result-title{color:#c6d0f5}html.theme--catppuccin-frappe .search-result-highlight{background-color:#e78284;color:#292c3c}html.theme--catppuccin-frappe .search-divider{border-bottom:1px solid #5e6d6f50}html.theme--catppuccin-frappe .w-100{width:100%}html.theme--catppuccin-frappe .gap-2{gap:0.5rem}html.theme--catppuccin-frappe .gap-4{gap:1rem} diff --git a/previews/PR4245/assets/themes/catppuccin-latte.css b/previews/PR4245/assets/themes/catppuccin-latte.css deleted file mode 100644 index 63160d3449f7..000000000000 --- a/previews/PR4245/assets/themes/catppuccin-latte.css +++ /dev/null @@ -1 +0,0 @@ -html.theme--catppuccin-latte .pagination-previous,html.theme--catppuccin-latte .pagination-next,html.theme--catppuccin-latte .pagination-link,html.theme--catppuccin-latte .pagination-ellipsis,html.theme--catppuccin-latte .file-cta,html.theme--catppuccin-latte .file-name,html.theme--catppuccin-latte .select select,html.theme--catppuccin-latte .textarea,html.theme--catppuccin-latte .input,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input,html.theme--catppuccin-latte .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:1rem;height:2.5em;justify-content:flex-start;line-height:1.5;padding-bottom:calc(0.5em - 1px);padding-left:calc(0.75em - 1px);padding-right:calc(0.75em - 1px);padding-top:calc(0.5em - 1px);position:relative;vertical-align:top}html.theme--catppuccin-latte .pagination-previous:focus,html.theme--catppuccin-latte .pagination-next:focus,html.theme--catppuccin-latte .pagination-link:focus,html.theme--catppuccin-latte .pagination-ellipsis:focus,html.theme--catppuccin-latte .file-cta:focus,html.theme--catppuccin-latte .file-name:focus,html.theme--catppuccin-latte .select select:focus,html.theme--catppuccin-latte .textarea:focus,html.theme--catppuccin-latte .input:focus,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input:focus,html.theme--catppuccin-latte .button:focus,html.theme--catppuccin-latte .is-focused.pagination-previous,html.theme--catppuccin-latte .is-focused.pagination-next,html.theme--catppuccin-latte .is-focused.pagination-link,html.theme--catppuccin-latte .is-focused.pagination-ellipsis,html.theme--catppuccin-latte .is-focused.file-cta,html.theme--catppuccin-latte .is-focused.file-name,html.theme--catppuccin-latte .select select.is-focused,html.theme--catppuccin-latte .is-focused.textarea,html.theme--catppuccin-latte .is-focused.input,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--catppuccin-latte .is-focused.button,html.theme--catppuccin-latte .pagination-previous:active,html.theme--catppuccin-latte .pagination-next:active,html.theme--catppuccin-latte .pagination-link:active,html.theme--catppuccin-latte .pagination-ellipsis:active,html.theme--catppuccin-latte .file-cta:active,html.theme--catppuccin-latte .file-name:active,html.theme--catppuccin-latte .select select:active,html.theme--catppuccin-latte .textarea:active,html.theme--catppuccin-latte .input:active,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input:active,html.theme--catppuccin-latte .button:active,html.theme--catppuccin-latte .is-active.pagination-previous,html.theme--catppuccin-latte .is-active.pagination-next,html.theme--catppuccin-latte .is-active.pagination-link,html.theme--catppuccin-latte .is-active.pagination-ellipsis,html.theme--catppuccin-latte .is-active.file-cta,html.theme--catppuccin-latte .is-active.file-name,html.theme--catppuccin-latte .select select.is-active,html.theme--catppuccin-latte .is-active.textarea,html.theme--catppuccin-latte .is-active.input,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-active,html.theme--catppuccin-latte .is-active.button{outline:none}html.theme--catppuccin-latte .pagination-previous[disabled],html.theme--catppuccin-latte .pagination-next[disabled],html.theme--catppuccin-latte .pagination-link[disabled],html.theme--catppuccin-latte .pagination-ellipsis[disabled],html.theme--catppuccin-latte .file-cta[disabled],html.theme--catppuccin-latte .file-name[disabled],html.theme--catppuccin-latte .select select[disabled],html.theme--catppuccin-latte .textarea[disabled],html.theme--catppuccin-latte .input[disabled],html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input[disabled],html.theme--catppuccin-latte .button[disabled],fieldset[disabled] html.theme--catppuccin-latte .pagination-previous,html.theme--catppuccin-latte fieldset[disabled] .pagination-previous,fieldset[disabled] html.theme--catppuccin-latte .pagination-next,html.theme--catppuccin-latte fieldset[disabled] .pagination-next,fieldset[disabled] html.theme--catppuccin-latte .pagination-link,html.theme--catppuccin-latte fieldset[disabled] .pagination-link,fieldset[disabled] html.theme--catppuccin-latte .pagination-ellipsis,html.theme--catppuccin-latte fieldset[disabled] .pagination-ellipsis,fieldset[disabled] html.theme--catppuccin-latte .file-cta,html.theme--catppuccin-latte fieldset[disabled] .file-cta,fieldset[disabled] html.theme--catppuccin-latte .file-name,html.theme--catppuccin-latte fieldset[disabled] .file-name,fieldset[disabled] html.theme--catppuccin-latte .select select,fieldset[disabled] html.theme--catppuccin-latte .textarea,fieldset[disabled] html.theme--catppuccin-latte .input,fieldset[disabled] html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input,html.theme--catppuccin-latte fieldset[disabled] .select select,html.theme--catppuccin-latte .select fieldset[disabled] select,html.theme--catppuccin-latte fieldset[disabled] .textarea,html.theme--catppuccin-latte fieldset[disabled] .input,html.theme--catppuccin-latte fieldset[disabled] #documenter .docs-sidebar form.docs-search>input,html.theme--catppuccin-latte #documenter .docs-sidebar fieldset[disabled] form.docs-search>input,fieldset[disabled] html.theme--catppuccin-latte .button,html.theme--catppuccin-latte fieldset[disabled] .button{cursor:not-allowed}html.theme--catppuccin-latte .tabs,html.theme--catppuccin-latte .pagination-previous,html.theme--catppuccin-latte .pagination-next,html.theme--catppuccin-latte .pagination-link,html.theme--catppuccin-latte .pagination-ellipsis,html.theme--catppuccin-latte .breadcrumb,html.theme--catppuccin-latte .file,html.theme--catppuccin-latte .button,.is-unselectable{-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}html.theme--catppuccin-latte .navbar-link:not(.is-arrowless)::after,html.theme--catppuccin-latte .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--catppuccin-latte .admonition:not(:last-child),html.theme--catppuccin-latte .tabs:not(:last-child),html.theme--catppuccin-latte .pagination:not(:last-child),html.theme--catppuccin-latte .message:not(:last-child),html.theme--catppuccin-latte .level:not(:last-child),html.theme--catppuccin-latte .breadcrumb:not(:last-child),html.theme--catppuccin-latte .block:not(:last-child),html.theme--catppuccin-latte .title:not(:last-child),html.theme--catppuccin-latte .subtitle:not(:last-child),html.theme--catppuccin-latte .table-container:not(:last-child),html.theme--catppuccin-latte .table:not(:last-child),html.theme--catppuccin-latte .progress:not(:last-child),html.theme--catppuccin-latte .notification:not(:last-child),html.theme--catppuccin-latte .content:not(:last-child),html.theme--catppuccin-latte .box:not(:last-child){margin-bottom:1.5rem}html.theme--catppuccin-latte .modal-close,html.theme--catppuccin-latte .delete{-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-moz-appearance:none;-webkit-appearance:none;background-color:rgba(10,10,10,0.2);border:none;border-radius:9999px;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--catppuccin-latte .modal-close::before,html.theme--catppuccin-latte .delete::before,html.theme--catppuccin-latte .modal-close::after,html.theme--catppuccin-latte .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--catppuccin-latte .modal-close::before,html.theme--catppuccin-latte .delete::before{height:2px;width:50%}html.theme--catppuccin-latte .modal-close::after,html.theme--catppuccin-latte .delete::after{height:50%;width:2px}html.theme--catppuccin-latte .modal-close:hover,html.theme--catppuccin-latte .delete:hover,html.theme--catppuccin-latte .modal-close:focus,html.theme--catppuccin-latte .delete:focus{background-color:rgba(10,10,10,0.3)}html.theme--catppuccin-latte .modal-close:active,html.theme--catppuccin-latte .delete:active{background-color:rgba(10,10,10,0.4)}html.theme--catppuccin-latte .is-small.modal-close,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.modal-close,html.theme--catppuccin-latte .is-small.delete,html.theme--catppuccin-latte #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--catppuccin-latte .is-medium.modal-close,html.theme--catppuccin-latte .is-medium.delete{height:24px;max-height:24px;max-width:24px;min-height:24px;min-width:24px;width:24px}html.theme--catppuccin-latte .is-large.modal-close,html.theme--catppuccin-latte .is-large.delete{height:32px;max-height:32px;max-width:32px;min-height:32px;min-width:32px;width:32px}html.theme--catppuccin-latte .control.is-loading::after,html.theme--catppuccin-latte .select.is-loading::after,html.theme--catppuccin-latte .loader,html.theme--catppuccin-latte .button.is-loading::after{animation:spinAround 500ms infinite linear;border:2px solid #8c8fa1;border-radius:9999px;border-right-color:transparent;border-top-color:transparent;content:"";display:block;height:1em;position:relative;width:1em}html.theme--catppuccin-latte .hero-video,html.theme--catppuccin-latte .modal-background,html.theme--catppuccin-latte .modal,html.theme--catppuccin-latte .image.is-square img,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-square img,html.theme--catppuccin-latte .image.is-square .has-ratio,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-square .has-ratio,html.theme--catppuccin-latte .image.is-1by1 img,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-1by1 img,html.theme--catppuccin-latte .image.is-1by1 .has-ratio,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-1by1 .has-ratio,html.theme--catppuccin-latte .image.is-5by4 img,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-5by4 img,html.theme--catppuccin-latte .image.is-5by4 .has-ratio,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-5by4 .has-ratio,html.theme--catppuccin-latte .image.is-4by3 img,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-4by3 img,html.theme--catppuccin-latte .image.is-4by3 .has-ratio,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-4by3 .has-ratio,html.theme--catppuccin-latte .image.is-3by2 img,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-3by2 img,html.theme--catppuccin-latte .image.is-3by2 .has-ratio,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-3by2 .has-ratio,html.theme--catppuccin-latte .image.is-5by3 img,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-5by3 img,html.theme--catppuccin-latte .image.is-5by3 .has-ratio,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-5by3 .has-ratio,html.theme--catppuccin-latte .image.is-16by9 img,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-16by9 img,html.theme--catppuccin-latte .image.is-16by9 .has-ratio,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-16by9 .has-ratio,html.theme--catppuccin-latte .image.is-2by1 img,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-2by1 img,html.theme--catppuccin-latte .image.is-2by1 .has-ratio,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-2by1 .has-ratio,html.theme--catppuccin-latte .image.is-3by1 img,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-3by1 img,html.theme--catppuccin-latte .image.is-3by1 .has-ratio,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-3by1 .has-ratio,html.theme--catppuccin-latte .image.is-4by5 img,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-4by5 img,html.theme--catppuccin-latte .image.is-4by5 .has-ratio,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-4by5 .has-ratio,html.theme--catppuccin-latte .image.is-3by4 img,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-3by4 img,html.theme--catppuccin-latte .image.is-3by4 .has-ratio,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-3by4 .has-ratio,html.theme--catppuccin-latte .image.is-2by3 img,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-2by3 img,html.theme--catppuccin-latte .image.is-2by3 .has-ratio,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-2by3 .has-ratio,html.theme--catppuccin-latte .image.is-3by5 img,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-3by5 img,html.theme--catppuccin-latte .image.is-3by5 .has-ratio,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-3by5 .has-ratio,html.theme--catppuccin-latte .image.is-9by16 img,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-9by16 img,html.theme--catppuccin-latte .image.is-9by16 .has-ratio,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-9by16 .has-ratio,html.theme--catppuccin-latte .image.is-1by2 img,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-1by2 img,html.theme--catppuccin-latte .image.is-1by2 .has-ratio,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-1by2 .has-ratio,html.theme--catppuccin-latte .image.is-1by3 img,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-1by3 img,html.theme--catppuccin-latte .image.is-1by3 .has-ratio,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-1by3 .has-ratio,.is-overlay{bottom:0;left:0;position:absolute;right:0;top:0}html.theme--catppuccin-latte .navbar-burger{-moz-appearance:none;-webkit-appearance:none;appearance:none;background:none;border:none;color:currentColor;font-family:inherit;font-size:1em;margin:0;padding:0}/*! minireset.css v0.0.6 | 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,video{height:auto;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:inherit}.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:#ccd0da !important}a.has-text-dark:hover,a.has-text-dark:focus{color:#aeb5c5 !important}.has-background-dark{background-color:#ccd0da !important}.has-text-primary{color:#1e66f5 !important}a.has-text-primary:hover,a.has-text-primary:focus{color:#0a4ed6 !important}.has-background-primary{background-color:#1e66f5 !important}.has-text-primary-light{color:#ebf2fe !important}a.has-text-primary-light:hover,a.has-text-primary-light:focus{color:#bbd1fc !important}.has-background-primary-light{background-color:#ebf2fe !important}.has-text-primary-dark{color:#0a52e1 !important}a.has-text-primary-dark:hover,a.has-text-primary-dark:focus{color:#286df5 !important}.has-background-primary-dark{background-color:#0a52e1 !important}.has-text-link{color:#1e66f5 !important}a.has-text-link:hover,a.has-text-link:focus{color:#0a4ed6 !important}.has-background-link{background-color:#1e66f5 !important}.has-text-link-light{color:#ebf2fe !important}a.has-text-link-light:hover,a.has-text-link-light:focus{color:#bbd1fc !important}.has-background-link-light{background-color:#ebf2fe !important}.has-text-link-dark{color:#0a52e1 !important}a.has-text-link-dark:hover,a.has-text-link-dark:focus{color:#286df5 !important}.has-background-link-dark{background-color:#0a52e1 !important}.has-text-info{color:#179299 !important}a.has-text-info:hover,a.has-text-info:focus{color:#10686d !important}.has-background-info{background-color:#179299 !important}.has-text-info-light{color:#edfcfc !important}a.has-text-info-light:hover,a.has-text-info-light:focus{color:#c1f3f6 !important}.has-background-info-light{background-color:#edfcfc !important}.has-text-info-dark{color:#1cb2ba !important}a.has-text-info-dark:hover,a.has-text-info-dark:focus{color:#2ad5df !important}.has-background-info-dark{background-color:#1cb2ba !important}.has-text-success{color:#40a02b !important}a.has-text-success:hover,a.has-text-success:focus{color:#307820 !important}.has-background-success{background-color:#40a02b !important}.has-text-success-light{color:#f1fbef !important}a.has-text-success-light:hover,a.has-text-success-light:focus{color:#cef0c7 !important}.has-background-success-light{background-color:#f1fbef !important}.has-text-success-dark{color:#40a12b !important}a.has-text-success-dark:hover,a.has-text-success-dark:focus{color:#50c936 !important}.has-background-success-dark{background-color:#40a12b !important}.has-text-warning{color:#df8e1d !important}a.has-text-warning:hover,a.has-text-warning:focus{color:#b27117 !important}.has-background-warning{background-color:#df8e1d !important}.has-text-warning-light{color:#fdf6ed !important}a.has-text-warning-light:hover,a.has-text-warning-light:focus{color:#f7e0c0 !important}.has-background-warning-light{background-color:#fdf6ed !important}.has-text-warning-dark{color:#9e6515 !important}a.has-text-warning-dark:hover,a.has-text-warning-dark:focus{color:#cb811a !important}.has-background-warning-dark{background-color:#9e6515 !important}.has-text-danger{color:#d20f39 !important}a.has-text-danger:hover,a.has-text-danger:focus{color:#a20c2c !important}.has-background-danger{background-color:#d20f39 !important}.has-text-danger-light{color:#feecf0 !important}a.has-text-danger-light:hover,a.has-text-danger-light:focus{color:#fabcca !important}.has-background-danger-light{background-color:#feecf0 !important}.has-text-danger-dark{color:#e9113f !important}a.has-text-danger-dark:hover,a.has-text-danger-dark:focus{color:#f13c63 !important}.has-background-danger-dark{background-color:#e9113f !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:#ccd0da !important}.has-background-grey-darker{background-color:#ccd0da !important}.has-text-grey-dark{color:#bcc0cc !important}.has-background-grey-dark{background-color:#bcc0cc !important}.has-text-grey{color:#acb0be !important}.has-background-grey{background-color:#acb0be !important}.has-text-grey-light{color:#9ca0b0 !important}.has-background-grey-light{background-color:#9ca0b0 !important}.has-text-grey-lighter{color:#8c8fa1 !important}.has-background-grey-lighter{background-color:#8c8fa1 !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}.is-flex-direction-row{flex-direction:row !important}.is-flex-direction-row-reverse{flex-direction:row-reverse !important}.is-flex-direction-column{flex-direction:column !important}.is-flex-direction-column-reverse{flex-direction:column-reverse !important}.is-flex-wrap-nowrap{flex-wrap:nowrap !important}.is-flex-wrap-wrap{flex-wrap:wrap !important}.is-flex-wrap-wrap-reverse{flex-wrap:wrap-reverse !important}.is-justify-content-flex-start{justify-content:flex-start !important}.is-justify-content-flex-end{justify-content:flex-end !important}.is-justify-content-center{justify-content:center !important}.is-justify-content-space-between{justify-content:space-between !important}.is-justify-content-space-around{justify-content:space-around !important}.is-justify-content-space-evenly{justify-content:space-evenly !important}.is-justify-content-start{justify-content:start !important}.is-justify-content-end{justify-content:end !important}.is-justify-content-left{justify-content:left !important}.is-justify-content-right{justify-content:right !important}.is-align-content-flex-start{align-content:flex-start !important}.is-align-content-flex-end{align-content:flex-end !important}.is-align-content-center{align-content:center !important}.is-align-content-space-between{align-content:space-between !important}.is-align-content-space-around{align-content:space-around !important}.is-align-content-space-evenly{align-content:space-evenly !important}.is-align-content-stretch{align-content:stretch !important}.is-align-content-start{align-content:start !important}.is-align-content-end{align-content:end !important}.is-align-content-baseline{align-content:baseline !important}.is-align-items-stretch{align-items:stretch !important}.is-align-items-flex-start{align-items:flex-start !important}.is-align-items-flex-end{align-items:flex-end !important}.is-align-items-center{align-items:center !important}.is-align-items-baseline{align-items:baseline !important}.is-align-items-start{align-items:start !important}.is-align-items-end{align-items:end !important}.is-align-items-self-start{align-items:self-start !important}.is-align-items-self-end{align-items:self-end !important}.is-align-self-auto{align-self:auto !important}.is-align-self-flex-start{align-self:flex-start !important}.is-align-self-flex-end{align-self:flex-end !important}.is-align-self-center{align-self:center !important}.is-align-self-baseline{align-self:baseline !important}.is-align-self-stretch{align-self:stretch !important}.is-flex-grow-0{flex-grow:0 !important}.is-flex-grow-1{flex-grow:1 !important}.is-flex-grow-2{flex-grow:2 !important}.is-flex-grow-3{flex-grow:3 !important}.is-flex-grow-4{flex-grow:4 !important}.is-flex-grow-5{flex-grow:5 !important}.is-flex-shrink-0{flex-shrink:0 !important}.is-flex-shrink-1{flex-shrink:1 !important}.is-flex-shrink-2{flex-shrink:2 !important}.is-flex-shrink-3{flex-shrink:3 !important}.is-flex-shrink-4{flex-shrink:4 !important}.is-flex-shrink-5{flex-shrink:5 !important}.is-clearfix::after{clear:both;content:" ";display:table}.is-pulled-left{float:left !important}.is-pulled-right{float:right !important}.is-radiusless{border-radius:0 !important}.is-shadowless{box-shadow:none !important}.is-clickable{cursor:pointer !important;pointer-events:all !important}.is-clipped{overflow:hidden !important}.is-relative{position:relative !important}.is-marginless{margin:0 !important}.is-paddingless{padding:0 !important}.m-0{margin:0 !important}.mt-0{margin-top:0 !important}.mr-0{margin-right:0 !important}.mb-0{margin-bottom:0 !important}.ml-0{margin-left:0 !important}.mx-0{margin-left:0 !important;margin-right:0 !important}.my-0{margin-top:0 !important;margin-bottom:0 !important}.m-1{margin:.25rem !important}.mt-1{margin-top:.25rem !important}.mr-1{margin-right:.25rem !important}.mb-1{margin-bottom:.25rem !important}.ml-1{margin-left:.25rem !important}.mx-1{margin-left:.25rem !important;margin-right:.25rem !important}.my-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.m-2{margin:.5rem !important}.mt-2{margin-top:.5rem !important}.mr-2{margin-right:.5rem !important}.mb-2{margin-bottom:.5rem !important}.ml-2{margin-left:.5rem !important}.mx-2{margin-left:.5rem !important;margin-right:.5rem !important}.my-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.m-3{margin:.75rem !important}.mt-3{margin-top:.75rem !important}.mr-3{margin-right:.75rem !important}.mb-3{margin-bottom:.75rem !important}.ml-3{margin-left:.75rem !important}.mx-3{margin-left:.75rem !important;margin-right:.75rem !important}.my-3{margin-top:.75rem !important;margin-bottom:.75rem !important}.m-4{margin:1rem !important}.mt-4{margin-top:1rem !important}.mr-4{margin-right:1rem !important}.mb-4{margin-bottom:1rem !important}.ml-4{margin-left:1rem !important}.mx-4{margin-left:1rem !important;margin-right:1rem !important}.my-4{margin-top:1rem !important;margin-bottom:1rem !important}.m-5{margin:1.5rem !important}.mt-5{margin-top:1.5rem !important}.mr-5{margin-right:1.5rem !important}.mb-5{margin-bottom:1.5rem !important}.ml-5{margin-left:1.5rem !important}.mx-5{margin-left:1.5rem !important;margin-right:1.5rem !important}.my-5{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.m-6{margin:3rem !important}.mt-6{margin-top:3rem !important}.mr-6{margin-right:3rem !important}.mb-6{margin-bottom:3rem !important}.ml-6{margin-left:3rem !important}.mx-6{margin-left:3rem !important;margin-right:3rem !important}.my-6{margin-top:3rem !important;margin-bottom:3rem !important}.m-auto{margin:auto !important}.mt-auto{margin-top:auto !important}.mr-auto{margin-right:auto !important}.mb-auto{margin-bottom:auto !important}.ml-auto{margin-left:auto !important}.mx-auto{margin-left:auto !important;margin-right:auto !important}.my-auto{margin-top:auto !important;margin-bottom:auto !important}.p-0{padding:0 !important}.pt-0{padding-top:0 !important}.pr-0{padding-right:0 !important}.pb-0{padding-bottom:0 !important}.pl-0{padding-left:0 !important}.px-0{padding-left:0 !important;padding-right:0 !important}.py-0{padding-top:0 !important;padding-bottom:0 !important}.p-1{padding:.25rem !important}.pt-1{padding-top:.25rem !important}.pr-1{padding-right:.25rem !important}.pb-1{padding-bottom:.25rem !important}.pl-1{padding-left:.25rem !important}.px-1{padding-left:.25rem !important;padding-right:.25rem !important}.py-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.p-2{padding:.5rem !important}.pt-2{padding-top:.5rem !important}.pr-2{padding-right:.5rem !important}.pb-2{padding-bottom:.5rem !important}.pl-2{padding-left:.5rem !important}.px-2{padding-left:.5rem !important;padding-right:.5rem !important}.py-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.p-3{padding:.75rem !important}.pt-3{padding-top:.75rem !important}.pr-3{padding-right:.75rem !important}.pb-3{padding-bottom:.75rem !important}.pl-3{padding-left:.75rem !important}.px-3{padding-left:.75rem !important;padding-right:.75rem !important}.py-3{padding-top:.75rem !important;padding-bottom:.75rem !important}.p-4{padding:1rem !important}.pt-4{padding-top:1rem !important}.pr-4{padding-right:1rem !important}.pb-4{padding-bottom:1rem !important}.pl-4{padding-left:1rem !important}.px-4{padding-left:1rem !important;padding-right:1rem !important}.py-4{padding-top:1rem !important;padding-bottom:1rem !important}.p-5{padding:1.5rem !important}.pt-5{padding-top:1.5rem !important}.pr-5{padding-right:1.5rem !important}.pb-5{padding-bottom:1.5rem !important}.pl-5{padding-left:1.5rem !important}.px-5{padding-left:1.5rem !important;padding-right:1.5rem !important}.py-5{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.p-6{padding:3rem !important}.pt-6{padding-top:3rem !important}.pr-6{padding-right:3rem !important}.pb-6{padding-bottom:3rem !important}.pl-6{padding-left:3rem !important}.px-6{padding-left:3rem !important;padding-right:3rem !important}.py-6{padding-top:3rem !important;padding-bottom:3rem !important}.p-auto{padding:auto !important}.pt-auto{padding-top:auto !important}.pr-auto{padding-right:auto !important}.pb-auto{padding-bottom:auto !important}.pl-auto{padding-left:auto !important}.px-auto{padding-left:auto !important;padding-right:auto !important}.py-auto{padding-top:auto !important;padding-bottom:auto !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,html.theme--catppuccin-latte .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}.is-underlined{text-decoration:underline !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}}html.theme--catppuccin-latte html{background-color:#eff1f5;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--catppuccin-latte article,html.theme--catppuccin-latte aside,html.theme--catppuccin-latte figure,html.theme--catppuccin-latte footer,html.theme--catppuccin-latte header,html.theme--catppuccin-latte hgroup,html.theme--catppuccin-latte section{display:block}html.theme--catppuccin-latte body,html.theme--catppuccin-latte button,html.theme--catppuccin-latte input,html.theme--catppuccin-latte optgroup,html.theme--catppuccin-latte select,html.theme--catppuccin-latte textarea{font-family:"Lato Medium",-apple-system,BlinkMacSystemFont,"Segoe UI","Helvetica Neue","Helvetica","Arial",sans-serif}html.theme--catppuccin-latte code,html.theme--catppuccin-latte 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--catppuccin-latte body{color:#4c4f69;font-size:1em;font-weight:400;line-height:1.5}html.theme--catppuccin-latte a{color:#1e66f5;cursor:pointer;text-decoration:none}html.theme--catppuccin-latte a strong{color:currentColor}html.theme--catppuccin-latte a:hover{color:#04a5e5}html.theme--catppuccin-latte code{background-color:#e6e9ef;color:#4c4f69;font-size:.875em;font-weight:normal;padding:.1em}html.theme--catppuccin-latte hr{background-color:#e6e9ef;border:none;display:block;height:2px;margin:1.5rem 0}html.theme--catppuccin-latte img{height:auto;max-width:100%}html.theme--catppuccin-latte input[type="checkbox"],html.theme--catppuccin-latte input[type="radio"]{vertical-align:baseline}html.theme--catppuccin-latte small{font-size:.875em}html.theme--catppuccin-latte span{font-style:inherit;font-weight:inherit}html.theme--catppuccin-latte strong{color:#41445a;font-weight:700}html.theme--catppuccin-latte fieldset{border:none}html.theme--catppuccin-latte pre{-webkit-overflow-scrolling:touch;background-color:#e6e9ef;color:#4c4f69;font-size:.875em;overflow-x:auto;padding:1.25rem 1.5rem;white-space:pre;word-wrap:normal}html.theme--catppuccin-latte pre code{background-color:transparent;color:currentColor;font-size:1em;padding:0}html.theme--catppuccin-latte table td,html.theme--catppuccin-latte table th{vertical-align:top}html.theme--catppuccin-latte table td:not([align]),html.theme--catppuccin-latte table th:not([align]){text-align:inherit}html.theme--catppuccin-latte table th{color:#41445a}html.theme--catppuccin-latte .box{background-color:#bcc0cc;border-radius:8px;box-shadow:none;color:#4c4f69;display:block;padding:1.25rem}html.theme--catppuccin-latte a.box:hover,html.theme--catppuccin-latte a.box:focus{box-shadow:0 0.5em 1em -0.125em rgba(10,10,10,0.1),0 0 0 1px #1e66f5}html.theme--catppuccin-latte a.box:active{box-shadow:inset 0 1px 2px rgba(10,10,10,0.2),0 0 0 1px #1e66f5}html.theme--catppuccin-latte .button{background-color:#e6e9ef;border-color:#fff;border-width:1px;color:#1e66f5;cursor:pointer;justify-content:center;padding-bottom:calc(0.5em - 1px);padding-left:1em;padding-right:1em;padding-top:calc(0.5em - 1px);text-align:center;white-space:nowrap}html.theme--catppuccin-latte .button strong{color:inherit}html.theme--catppuccin-latte .button .icon,html.theme--catppuccin-latte .button .icon.is-small,html.theme--catppuccin-latte .button #documenter .docs-sidebar form.docs-search>input.icon,html.theme--catppuccin-latte #documenter .docs-sidebar .button form.docs-search>input.icon,html.theme--catppuccin-latte .button .icon.is-medium,html.theme--catppuccin-latte .button .icon.is-large{height:1.5em;width:1.5em}html.theme--catppuccin-latte .button .icon:first-child:not(:last-child){margin-left:calc(-0.5em - 1px);margin-right:.25em}html.theme--catppuccin-latte .button .icon:last-child:not(:first-child){margin-left:.25em;margin-right:calc(-0.5em - 1px)}html.theme--catppuccin-latte .button .icon:first-child:last-child{margin-left:calc(-0.5em - 1px);margin-right:calc(-0.5em - 1px)}html.theme--catppuccin-latte .button:hover,html.theme--catppuccin-latte .button.is-hovered{border-color:#9ca0b0;color:#41445a}html.theme--catppuccin-latte .button:focus,html.theme--catppuccin-latte .button.is-focused{border-color:#9ca0b0;color:#0b57ef}html.theme--catppuccin-latte .button:focus:not(:active),html.theme--catppuccin-latte .button.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(30,102,245,0.25)}html.theme--catppuccin-latte .button:active,html.theme--catppuccin-latte .button.is-active{border-color:#bcc0cc;color:#41445a}html.theme--catppuccin-latte .button.is-text{background-color:transparent;border-color:transparent;color:#4c4f69;text-decoration:underline}html.theme--catppuccin-latte .button.is-text:hover,html.theme--catppuccin-latte .button.is-text.is-hovered,html.theme--catppuccin-latte .button.is-text:focus,html.theme--catppuccin-latte .button.is-text.is-focused{background-color:#e6e9ef;color:#41445a}html.theme--catppuccin-latte .button.is-text:active,html.theme--catppuccin-latte .button.is-text.is-active{background-color:#d6dbe5;color:#41445a}html.theme--catppuccin-latte .button.is-text[disabled],fieldset[disabled] html.theme--catppuccin-latte .button.is-text{background-color:transparent;border-color:transparent;box-shadow:none}html.theme--catppuccin-latte .button.is-ghost{background:none;border-color:rgba(0,0,0,0);color:#1e66f5;text-decoration:none}html.theme--catppuccin-latte .button.is-ghost:hover,html.theme--catppuccin-latte .button.is-ghost.is-hovered{color:#1e66f5;text-decoration:underline}html.theme--catppuccin-latte .button.is-white{background-color:#fff;border-color:transparent;color:#0a0a0a}html.theme--catppuccin-latte .button.is-white:hover,html.theme--catppuccin-latte .button.is-white.is-hovered{background-color:#f9f9f9;border-color:transparent;color:#0a0a0a}html.theme--catppuccin-latte .button.is-white:focus,html.theme--catppuccin-latte .button.is-white.is-focused{border-color:transparent;color:#0a0a0a}html.theme--catppuccin-latte .button.is-white:focus:not(:active),html.theme--catppuccin-latte .button.is-white.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(255,255,255,0.25)}html.theme--catppuccin-latte .button.is-white:active,html.theme--catppuccin-latte .button.is-white.is-active{background-color:#f2f2f2;border-color:transparent;color:#0a0a0a}html.theme--catppuccin-latte .button.is-white[disabled],fieldset[disabled] html.theme--catppuccin-latte .button.is-white{background-color:#fff;border-color:#fff;box-shadow:none}html.theme--catppuccin-latte .button.is-white.is-inverted{background-color:#0a0a0a;color:#fff}html.theme--catppuccin-latte .button.is-white.is-inverted:hover,html.theme--catppuccin-latte .button.is-white.is-inverted.is-hovered{background-color:#000}html.theme--catppuccin-latte .button.is-white.is-inverted[disabled],fieldset[disabled] html.theme--catppuccin-latte .button.is-white.is-inverted{background-color:#0a0a0a;border-color:transparent;box-shadow:none;color:#fff}html.theme--catppuccin-latte .button.is-white.is-loading::after{border-color:transparent transparent #0a0a0a #0a0a0a !important}html.theme--catppuccin-latte .button.is-white.is-outlined{background-color:transparent;border-color:#fff;color:#fff}html.theme--catppuccin-latte .button.is-white.is-outlined:hover,html.theme--catppuccin-latte .button.is-white.is-outlined.is-hovered,html.theme--catppuccin-latte .button.is-white.is-outlined:focus,html.theme--catppuccin-latte .button.is-white.is-outlined.is-focused{background-color:#fff;border-color:#fff;color:#0a0a0a}html.theme--catppuccin-latte .button.is-white.is-outlined.is-loading::after{border-color:transparent transparent #fff #fff !important}html.theme--catppuccin-latte .button.is-white.is-outlined.is-loading:hover::after,html.theme--catppuccin-latte .button.is-white.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-latte .button.is-white.is-outlined.is-loading:focus::after,html.theme--catppuccin-latte .button.is-white.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #0a0a0a #0a0a0a !important}html.theme--catppuccin-latte .button.is-white.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-latte .button.is-white.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}html.theme--catppuccin-latte .button.is-white.is-inverted.is-outlined{background-color:transparent;border-color:#0a0a0a;color:#0a0a0a}html.theme--catppuccin-latte .button.is-white.is-inverted.is-outlined:hover,html.theme--catppuccin-latte .button.is-white.is-inverted.is-outlined.is-hovered,html.theme--catppuccin-latte .button.is-white.is-inverted.is-outlined:focus,html.theme--catppuccin-latte .button.is-white.is-inverted.is-outlined.is-focused{background-color:#0a0a0a;color:#fff}html.theme--catppuccin-latte .button.is-white.is-inverted.is-outlined.is-loading:hover::after,html.theme--catppuccin-latte .button.is-white.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-latte .button.is-white.is-inverted.is-outlined.is-loading:focus::after,html.theme--catppuccin-latte .button.is-white.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #fff #fff !important}html.theme--catppuccin-latte .button.is-white.is-inverted.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-latte .button.is-white.is-inverted.is-outlined{background-color:transparent;border-color:#0a0a0a;box-shadow:none;color:#0a0a0a}html.theme--catppuccin-latte .button.is-black{background-color:#0a0a0a;border-color:transparent;color:#fff}html.theme--catppuccin-latte .button.is-black:hover,html.theme--catppuccin-latte .button.is-black.is-hovered{background-color:#040404;border-color:transparent;color:#fff}html.theme--catppuccin-latte .button.is-black:focus,html.theme--catppuccin-latte .button.is-black.is-focused{border-color:transparent;color:#fff}html.theme--catppuccin-latte .button.is-black:focus:not(:active),html.theme--catppuccin-latte .button.is-black.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(10,10,10,0.25)}html.theme--catppuccin-latte .button.is-black:active,html.theme--catppuccin-latte .button.is-black.is-active{background-color:#000;border-color:transparent;color:#fff}html.theme--catppuccin-latte .button.is-black[disabled],fieldset[disabled] html.theme--catppuccin-latte .button.is-black{background-color:#0a0a0a;border-color:#0a0a0a;box-shadow:none}html.theme--catppuccin-latte .button.is-black.is-inverted{background-color:#fff;color:#0a0a0a}html.theme--catppuccin-latte .button.is-black.is-inverted:hover,html.theme--catppuccin-latte .button.is-black.is-inverted.is-hovered{background-color:#f2f2f2}html.theme--catppuccin-latte .button.is-black.is-inverted[disabled],fieldset[disabled] html.theme--catppuccin-latte .button.is-black.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#0a0a0a}html.theme--catppuccin-latte .button.is-black.is-loading::after{border-color:transparent transparent #fff #fff !important}html.theme--catppuccin-latte .button.is-black.is-outlined{background-color:transparent;border-color:#0a0a0a;color:#0a0a0a}html.theme--catppuccin-latte .button.is-black.is-outlined:hover,html.theme--catppuccin-latte .button.is-black.is-outlined.is-hovered,html.theme--catppuccin-latte .button.is-black.is-outlined:focus,html.theme--catppuccin-latte .button.is-black.is-outlined.is-focused{background-color:#0a0a0a;border-color:#0a0a0a;color:#fff}html.theme--catppuccin-latte .button.is-black.is-outlined.is-loading::after{border-color:transparent transparent #0a0a0a #0a0a0a !important}html.theme--catppuccin-latte .button.is-black.is-outlined.is-loading:hover::after,html.theme--catppuccin-latte .button.is-black.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-latte .button.is-black.is-outlined.is-loading:focus::after,html.theme--catppuccin-latte .button.is-black.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #fff #fff !important}html.theme--catppuccin-latte .button.is-black.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-latte .button.is-black.is-outlined{background-color:transparent;border-color:#0a0a0a;box-shadow:none;color:#0a0a0a}html.theme--catppuccin-latte .button.is-black.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}html.theme--catppuccin-latte .button.is-black.is-inverted.is-outlined:hover,html.theme--catppuccin-latte .button.is-black.is-inverted.is-outlined.is-hovered,html.theme--catppuccin-latte .button.is-black.is-inverted.is-outlined:focus,html.theme--catppuccin-latte .button.is-black.is-inverted.is-outlined.is-focused{background-color:#fff;color:#0a0a0a}html.theme--catppuccin-latte .button.is-black.is-inverted.is-outlined.is-loading:hover::after,html.theme--catppuccin-latte .button.is-black.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-latte .button.is-black.is-inverted.is-outlined.is-loading:focus::after,html.theme--catppuccin-latte .button.is-black.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #0a0a0a #0a0a0a !important}html.theme--catppuccin-latte .button.is-black.is-inverted.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-latte .button.is-black.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}html.theme--catppuccin-latte .button.is-light{background-color:#f5f5f5;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-latte .button.is-light:hover,html.theme--catppuccin-latte .button.is-light.is-hovered{background-color:#eee;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-latte .button.is-light:focus,html.theme--catppuccin-latte .button.is-light.is-focused{border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-latte .button.is-light:focus:not(:active),html.theme--catppuccin-latte .button.is-light.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(245,245,245,0.25)}html.theme--catppuccin-latte .button.is-light:active,html.theme--catppuccin-latte .button.is-light.is-active{background-color:#e8e8e8;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-latte .button.is-light[disabled],fieldset[disabled] html.theme--catppuccin-latte .button.is-light{background-color:#f5f5f5;border-color:#f5f5f5;box-shadow:none}html.theme--catppuccin-latte .button.is-light.is-inverted{background-color:rgba(0,0,0,0.7);color:#f5f5f5}html.theme--catppuccin-latte .button.is-light.is-inverted:hover,html.theme--catppuccin-latte .button.is-light.is-inverted.is-hovered{background-color:rgba(0,0,0,0.7)}html.theme--catppuccin-latte .button.is-light.is-inverted[disabled],fieldset[disabled] html.theme--catppuccin-latte .button.is-light.is-inverted{background-color:rgba(0,0,0,0.7);border-color:transparent;box-shadow:none;color:#f5f5f5}html.theme--catppuccin-latte .button.is-light.is-loading::after{border-color:transparent transparent rgba(0,0,0,0.7) rgba(0,0,0,0.7) !important}html.theme--catppuccin-latte .button.is-light.is-outlined{background-color:transparent;border-color:#f5f5f5;color:#f5f5f5}html.theme--catppuccin-latte .button.is-light.is-outlined:hover,html.theme--catppuccin-latte .button.is-light.is-outlined.is-hovered,html.theme--catppuccin-latte .button.is-light.is-outlined:focus,html.theme--catppuccin-latte .button.is-light.is-outlined.is-focused{background-color:#f5f5f5;border-color:#f5f5f5;color:rgba(0,0,0,0.7)}html.theme--catppuccin-latte .button.is-light.is-outlined.is-loading::after{border-color:transparent transparent #f5f5f5 #f5f5f5 !important}html.theme--catppuccin-latte .button.is-light.is-outlined.is-loading:hover::after,html.theme--catppuccin-latte .button.is-light.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-latte .button.is-light.is-outlined.is-loading:focus::after,html.theme--catppuccin-latte .button.is-light.is-outlined.is-loading.is-focused::after{border-color:transparent transparent rgba(0,0,0,0.7) rgba(0,0,0,0.7) !important}html.theme--catppuccin-latte .button.is-light.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-latte .button.is-light.is-outlined{background-color:transparent;border-color:#f5f5f5;box-shadow:none;color:#f5f5f5}html.theme--catppuccin-latte .button.is-light.is-inverted.is-outlined{background-color:transparent;border-color:rgba(0,0,0,0.7);color:rgba(0,0,0,0.7)}html.theme--catppuccin-latte .button.is-light.is-inverted.is-outlined:hover,html.theme--catppuccin-latte .button.is-light.is-inverted.is-outlined.is-hovered,html.theme--catppuccin-latte .button.is-light.is-inverted.is-outlined:focus,html.theme--catppuccin-latte .button.is-light.is-inverted.is-outlined.is-focused{background-color:rgba(0,0,0,0.7);color:#f5f5f5}html.theme--catppuccin-latte .button.is-light.is-inverted.is-outlined.is-loading:hover::after,html.theme--catppuccin-latte .button.is-light.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-latte .button.is-light.is-inverted.is-outlined.is-loading:focus::after,html.theme--catppuccin-latte .button.is-light.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #f5f5f5 #f5f5f5 !important}html.theme--catppuccin-latte .button.is-light.is-inverted.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-latte .button.is-light.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)}html.theme--catppuccin-latte .button.is-dark,html.theme--catppuccin-latte .content kbd.button{background-color:#ccd0da;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-latte .button.is-dark:hover,html.theme--catppuccin-latte .content kbd.button:hover,html.theme--catppuccin-latte .button.is-dark.is-hovered,html.theme--catppuccin-latte .content kbd.button.is-hovered{background-color:#c5c9d5;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-latte .button.is-dark:focus,html.theme--catppuccin-latte .content kbd.button:focus,html.theme--catppuccin-latte .button.is-dark.is-focused,html.theme--catppuccin-latte .content kbd.button.is-focused{border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-latte .button.is-dark:focus:not(:active),html.theme--catppuccin-latte .content kbd.button:focus:not(:active),html.theme--catppuccin-latte .button.is-dark.is-focused:not(:active),html.theme--catppuccin-latte .content kbd.button.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(204,208,218,0.25)}html.theme--catppuccin-latte .button.is-dark:active,html.theme--catppuccin-latte .content kbd.button:active,html.theme--catppuccin-latte .button.is-dark.is-active,html.theme--catppuccin-latte .content kbd.button.is-active{background-color:#bdc2cf;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-latte .button.is-dark[disabled],html.theme--catppuccin-latte .content kbd.button[disabled],fieldset[disabled] html.theme--catppuccin-latte .button.is-dark,fieldset[disabled] html.theme--catppuccin-latte .content kbd.button{background-color:#ccd0da;border-color:#ccd0da;box-shadow:none}html.theme--catppuccin-latte .button.is-dark.is-inverted,html.theme--catppuccin-latte .content kbd.button.is-inverted{background-color:rgba(0,0,0,0.7);color:#ccd0da}html.theme--catppuccin-latte .button.is-dark.is-inverted:hover,html.theme--catppuccin-latte .content kbd.button.is-inverted:hover,html.theme--catppuccin-latte .button.is-dark.is-inverted.is-hovered,html.theme--catppuccin-latte .content kbd.button.is-inverted.is-hovered{background-color:rgba(0,0,0,0.7)}html.theme--catppuccin-latte .button.is-dark.is-inverted[disabled],html.theme--catppuccin-latte .content kbd.button.is-inverted[disabled],fieldset[disabled] html.theme--catppuccin-latte .button.is-dark.is-inverted,fieldset[disabled] html.theme--catppuccin-latte .content kbd.button.is-inverted{background-color:rgba(0,0,0,0.7);border-color:transparent;box-shadow:none;color:#ccd0da}html.theme--catppuccin-latte .button.is-dark.is-loading::after,html.theme--catppuccin-latte .content kbd.button.is-loading::after{border-color:transparent transparent rgba(0,0,0,0.7) rgba(0,0,0,0.7) !important}html.theme--catppuccin-latte .button.is-dark.is-outlined,html.theme--catppuccin-latte .content kbd.button.is-outlined{background-color:transparent;border-color:#ccd0da;color:#ccd0da}html.theme--catppuccin-latte .button.is-dark.is-outlined:hover,html.theme--catppuccin-latte .content kbd.button.is-outlined:hover,html.theme--catppuccin-latte .button.is-dark.is-outlined.is-hovered,html.theme--catppuccin-latte .content kbd.button.is-outlined.is-hovered,html.theme--catppuccin-latte .button.is-dark.is-outlined:focus,html.theme--catppuccin-latte .content kbd.button.is-outlined:focus,html.theme--catppuccin-latte .button.is-dark.is-outlined.is-focused,html.theme--catppuccin-latte .content kbd.button.is-outlined.is-focused{background-color:#ccd0da;border-color:#ccd0da;color:rgba(0,0,0,0.7)}html.theme--catppuccin-latte .button.is-dark.is-outlined.is-loading::after,html.theme--catppuccin-latte .content kbd.button.is-outlined.is-loading::after{border-color:transparent transparent #ccd0da #ccd0da !important}html.theme--catppuccin-latte .button.is-dark.is-outlined.is-loading:hover::after,html.theme--catppuccin-latte .content kbd.button.is-outlined.is-loading:hover::after,html.theme--catppuccin-latte .button.is-dark.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-latte .content kbd.button.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-latte .button.is-dark.is-outlined.is-loading:focus::after,html.theme--catppuccin-latte .content kbd.button.is-outlined.is-loading:focus::after,html.theme--catppuccin-latte .button.is-dark.is-outlined.is-loading.is-focused::after,html.theme--catppuccin-latte .content kbd.button.is-outlined.is-loading.is-focused::after{border-color:transparent transparent rgba(0,0,0,0.7) rgba(0,0,0,0.7) !important}html.theme--catppuccin-latte .button.is-dark.is-outlined[disabled],html.theme--catppuccin-latte .content kbd.button.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-latte .button.is-dark.is-outlined,fieldset[disabled] html.theme--catppuccin-latte .content kbd.button.is-outlined{background-color:transparent;border-color:#ccd0da;box-shadow:none;color:#ccd0da}html.theme--catppuccin-latte .button.is-dark.is-inverted.is-outlined,html.theme--catppuccin-latte .content kbd.button.is-inverted.is-outlined{background-color:transparent;border-color:rgba(0,0,0,0.7);color:rgba(0,0,0,0.7)}html.theme--catppuccin-latte .button.is-dark.is-inverted.is-outlined:hover,html.theme--catppuccin-latte .content kbd.button.is-inverted.is-outlined:hover,html.theme--catppuccin-latte .button.is-dark.is-inverted.is-outlined.is-hovered,html.theme--catppuccin-latte .content kbd.button.is-inverted.is-outlined.is-hovered,html.theme--catppuccin-latte .button.is-dark.is-inverted.is-outlined:focus,html.theme--catppuccin-latte .content kbd.button.is-inverted.is-outlined:focus,html.theme--catppuccin-latte .button.is-dark.is-inverted.is-outlined.is-focused,html.theme--catppuccin-latte .content kbd.button.is-inverted.is-outlined.is-focused{background-color:rgba(0,0,0,0.7);color:#ccd0da}html.theme--catppuccin-latte .button.is-dark.is-inverted.is-outlined.is-loading:hover::after,html.theme--catppuccin-latte .content kbd.button.is-inverted.is-outlined.is-loading:hover::after,html.theme--catppuccin-latte .button.is-dark.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-latte .content kbd.button.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-latte .button.is-dark.is-inverted.is-outlined.is-loading:focus::after,html.theme--catppuccin-latte .content kbd.button.is-inverted.is-outlined.is-loading:focus::after,html.theme--catppuccin-latte .button.is-dark.is-inverted.is-outlined.is-loading.is-focused::after,html.theme--catppuccin-latte .content kbd.button.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #ccd0da #ccd0da !important}html.theme--catppuccin-latte .button.is-dark.is-inverted.is-outlined[disabled],html.theme--catppuccin-latte .content kbd.button.is-inverted.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-latte .button.is-dark.is-inverted.is-outlined,fieldset[disabled] html.theme--catppuccin-latte .content kbd.button.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)}html.theme--catppuccin-latte .button.is-primary,html.theme--catppuccin-latte .docstring>section>a.button.docs-sourcelink{background-color:#1e66f5;border-color:transparent;color:#fff}html.theme--catppuccin-latte .button.is-primary:hover,html.theme--catppuccin-latte .docstring>section>a.button.docs-sourcelink:hover,html.theme--catppuccin-latte .button.is-primary.is-hovered,html.theme--catppuccin-latte .docstring>section>a.button.is-hovered.docs-sourcelink{background-color:#125ef4;border-color:transparent;color:#fff}html.theme--catppuccin-latte .button.is-primary:focus,html.theme--catppuccin-latte .docstring>section>a.button.docs-sourcelink:focus,html.theme--catppuccin-latte .button.is-primary.is-focused,html.theme--catppuccin-latte .docstring>section>a.button.is-focused.docs-sourcelink{border-color:transparent;color:#fff}html.theme--catppuccin-latte .button.is-primary:focus:not(:active),html.theme--catppuccin-latte .docstring>section>a.button.docs-sourcelink:focus:not(:active),html.theme--catppuccin-latte .button.is-primary.is-focused:not(:active),html.theme--catppuccin-latte .docstring>section>a.button.is-focused.docs-sourcelink:not(:active){box-shadow:0 0 0 0.125em rgba(30,102,245,0.25)}html.theme--catppuccin-latte .button.is-primary:active,html.theme--catppuccin-latte .docstring>section>a.button.docs-sourcelink:active,html.theme--catppuccin-latte .button.is-primary.is-active,html.theme--catppuccin-latte .docstring>section>a.button.is-active.docs-sourcelink{background-color:#0b57ef;border-color:transparent;color:#fff}html.theme--catppuccin-latte .button.is-primary[disabled],html.theme--catppuccin-latte .docstring>section>a.button.docs-sourcelink[disabled],fieldset[disabled] html.theme--catppuccin-latte .button.is-primary,fieldset[disabled] html.theme--catppuccin-latte .docstring>section>a.button.docs-sourcelink{background-color:#1e66f5;border-color:#1e66f5;box-shadow:none}html.theme--catppuccin-latte .button.is-primary.is-inverted,html.theme--catppuccin-latte .docstring>section>a.button.is-inverted.docs-sourcelink{background-color:#fff;color:#1e66f5}html.theme--catppuccin-latte .button.is-primary.is-inverted:hover,html.theme--catppuccin-latte .docstring>section>a.button.is-inverted.docs-sourcelink:hover,html.theme--catppuccin-latte .button.is-primary.is-inverted.is-hovered,html.theme--catppuccin-latte .docstring>section>a.button.is-inverted.is-hovered.docs-sourcelink{background-color:#f2f2f2}html.theme--catppuccin-latte .button.is-primary.is-inverted[disabled],html.theme--catppuccin-latte .docstring>section>a.button.is-inverted.docs-sourcelink[disabled],fieldset[disabled] html.theme--catppuccin-latte .button.is-primary.is-inverted,fieldset[disabled] html.theme--catppuccin-latte .docstring>section>a.button.is-inverted.docs-sourcelink{background-color:#fff;border-color:transparent;box-shadow:none;color:#1e66f5}html.theme--catppuccin-latte .button.is-primary.is-loading::after,html.theme--catppuccin-latte .docstring>section>a.button.is-loading.docs-sourcelink::after{border-color:transparent transparent #fff #fff !important}html.theme--catppuccin-latte .button.is-primary.is-outlined,html.theme--catppuccin-latte .docstring>section>a.button.is-outlined.docs-sourcelink{background-color:transparent;border-color:#1e66f5;color:#1e66f5}html.theme--catppuccin-latte .button.is-primary.is-outlined:hover,html.theme--catppuccin-latte .docstring>section>a.button.is-outlined.docs-sourcelink:hover,html.theme--catppuccin-latte .button.is-primary.is-outlined.is-hovered,html.theme--catppuccin-latte .docstring>section>a.button.is-outlined.is-hovered.docs-sourcelink,html.theme--catppuccin-latte .button.is-primary.is-outlined:focus,html.theme--catppuccin-latte .docstring>section>a.button.is-outlined.docs-sourcelink:focus,html.theme--catppuccin-latte .button.is-primary.is-outlined.is-focused,html.theme--catppuccin-latte .docstring>section>a.button.is-outlined.is-focused.docs-sourcelink{background-color:#1e66f5;border-color:#1e66f5;color:#fff}html.theme--catppuccin-latte .button.is-primary.is-outlined.is-loading::after,html.theme--catppuccin-latte .docstring>section>a.button.is-outlined.is-loading.docs-sourcelink::after{border-color:transparent transparent #1e66f5 #1e66f5 !important}html.theme--catppuccin-latte .button.is-primary.is-outlined.is-loading:hover::after,html.theme--catppuccin-latte .docstring>section>a.button.is-outlined.is-loading.docs-sourcelink:hover::after,html.theme--catppuccin-latte .button.is-primary.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-latte .docstring>section>a.button.is-outlined.is-loading.is-hovered.docs-sourcelink::after,html.theme--catppuccin-latte .button.is-primary.is-outlined.is-loading:focus::after,html.theme--catppuccin-latte .docstring>section>a.button.is-outlined.is-loading.docs-sourcelink:focus::after,html.theme--catppuccin-latte .button.is-primary.is-outlined.is-loading.is-focused::after,html.theme--catppuccin-latte .docstring>section>a.button.is-outlined.is-loading.is-focused.docs-sourcelink::after{border-color:transparent transparent #fff #fff !important}html.theme--catppuccin-latte .button.is-primary.is-outlined[disabled],html.theme--catppuccin-latte .docstring>section>a.button.is-outlined.docs-sourcelink[disabled],fieldset[disabled] html.theme--catppuccin-latte .button.is-primary.is-outlined,fieldset[disabled] html.theme--catppuccin-latte .docstring>section>a.button.is-outlined.docs-sourcelink{background-color:transparent;border-color:#1e66f5;box-shadow:none;color:#1e66f5}html.theme--catppuccin-latte .button.is-primary.is-inverted.is-outlined,html.theme--catppuccin-latte .docstring>section>a.button.is-inverted.is-outlined.docs-sourcelink{background-color:transparent;border-color:#fff;color:#fff}html.theme--catppuccin-latte .button.is-primary.is-inverted.is-outlined:hover,html.theme--catppuccin-latte .docstring>section>a.button.is-inverted.is-outlined.docs-sourcelink:hover,html.theme--catppuccin-latte .button.is-primary.is-inverted.is-outlined.is-hovered,html.theme--catppuccin-latte .docstring>section>a.button.is-inverted.is-outlined.is-hovered.docs-sourcelink,html.theme--catppuccin-latte .button.is-primary.is-inverted.is-outlined:focus,html.theme--catppuccin-latte .docstring>section>a.button.is-inverted.is-outlined.docs-sourcelink:focus,html.theme--catppuccin-latte .button.is-primary.is-inverted.is-outlined.is-focused,html.theme--catppuccin-latte .docstring>section>a.button.is-inverted.is-outlined.is-focused.docs-sourcelink{background-color:#fff;color:#1e66f5}html.theme--catppuccin-latte .button.is-primary.is-inverted.is-outlined.is-loading:hover::after,html.theme--catppuccin-latte .docstring>section>a.button.is-inverted.is-outlined.is-loading.docs-sourcelink:hover::after,html.theme--catppuccin-latte .button.is-primary.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-latte .docstring>section>a.button.is-inverted.is-outlined.is-loading.is-hovered.docs-sourcelink::after,html.theme--catppuccin-latte .button.is-primary.is-inverted.is-outlined.is-loading:focus::after,html.theme--catppuccin-latte .docstring>section>a.button.is-inverted.is-outlined.is-loading.docs-sourcelink:focus::after,html.theme--catppuccin-latte .button.is-primary.is-inverted.is-outlined.is-loading.is-focused::after,html.theme--catppuccin-latte .docstring>section>a.button.is-inverted.is-outlined.is-loading.is-focused.docs-sourcelink::after{border-color:transparent transparent #1e66f5 #1e66f5 !important}html.theme--catppuccin-latte .button.is-primary.is-inverted.is-outlined[disabled],html.theme--catppuccin-latte .docstring>section>a.button.is-inverted.is-outlined.docs-sourcelink[disabled],fieldset[disabled] html.theme--catppuccin-latte .button.is-primary.is-inverted.is-outlined,fieldset[disabled] html.theme--catppuccin-latte .docstring>section>a.button.is-inverted.is-outlined.docs-sourcelink{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}html.theme--catppuccin-latte .button.is-primary.is-light,html.theme--catppuccin-latte .docstring>section>a.button.is-light.docs-sourcelink{background-color:#ebf2fe;color:#0a52e1}html.theme--catppuccin-latte .button.is-primary.is-light:hover,html.theme--catppuccin-latte .docstring>section>a.button.is-light.docs-sourcelink:hover,html.theme--catppuccin-latte .button.is-primary.is-light.is-hovered,html.theme--catppuccin-latte .docstring>section>a.button.is-light.is-hovered.docs-sourcelink{background-color:#dfe9fe;border-color:transparent;color:#0a52e1}html.theme--catppuccin-latte .button.is-primary.is-light:active,html.theme--catppuccin-latte .docstring>section>a.button.is-light.docs-sourcelink:active,html.theme--catppuccin-latte .button.is-primary.is-light.is-active,html.theme--catppuccin-latte .docstring>section>a.button.is-light.is-active.docs-sourcelink{background-color:#d3e1fd;border-color:transparent;color:#0a52e1}html.theme--catppuccin-latte .button.is-link{background-color:#1e66f5;border-color:transparent;color:#fff}html.theme--catppuccin-latte .button.is-link:hover,html.theme--catppuccin-latte .button.is-link.is-hovered{background-color:#125ef4;border-color:transparent;color:#fff}html.theme--catppuccin-latte .button.is-link:focus,html.theme--catppuccin-latte .button.is-link.is-focused{border-color:transparent;color:#fff}html.theme--catppuccin-latte .button.is-link:focus:not(:active),html.theme--catppuccin-latte .button.is-link.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(30,102,245,0.25)}html.theme--catppuccin-latte .button.is-link:active,html.theme--catppuccin-latte .button.is-link.is-active{background-color:#0b57ef;border-color:transparent;color:#fff}html.theme--catppuccin-latte .button.is-link[disabled],fieldset[disabled] html.theme--catppuccin-latte .button.is-link{background-color:#1e66f5;border-color:#1e66f5;box-shadow:none}html.theme--catppuccin-latte .button.is-link.is-inverted{background-color:#fff;color:#1e66f5}html.theme--catppuccin-latte .button.is-link.is-inverted:hover,html.theme--catppuccin-latte .button.is-link.is-inverted.is-hovered{background-color:#f2f2f2}html.theme--catppuccin-latte .button.is-link.is-inverted[disabled],fieldset[disabled] html.theme--catppuccin-latte .button.is-link.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#1e66f5}html.theme--catppuccin-latte .button.is-link.is-loading::after{border-color:transparent transparent #fff #fff !important}html.theme--catppuccin-latte .button.is-link.is-outlined{background-color:transparent;border-color:#1e66f5;color:#1e66f5}html.theme--catppuccin-latte .button.is-link.is-outlined:hover,html.theme--catppuccin-latte .button.is-link.is-outlined.is-hovered,html.theme--catppuccin-latte .button.is-link.is-outlined:focus,html.theme--catppuccin-latte .button.is-link.is-outlined.is-focused{background-color:#1e66f5;border-color:#1e66f5;color:#fff}html.theme--catppuccin-latte .button.is-link.is-outlined.is-loading::after{border-color:transparent transparent #1e66f5 #1e66f5 !important}html.theme--catppuccin-latte .button.is-link.is-outlined.is-loading:hover::after,html.theme--catppuccin-latte .button.is-link.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-latte .button.is-link.is-outlined.is-loading:focus::after,html.theme--catppuccin-latte .button.is-link.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #fff #fff !important}html.theme--catppuccin-latte .button.is-link.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-latte .button.is-link.is-outlined{background-color:transparent;border-color:#1e66f5;box-shadow:none;color:#1e66f5}html.theme--catppuccin-latte .button.is-link.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}html.theme--catppuccin-latte .button.is-link.is-inverted.is-outlined:hover,html.theme--catppuccin-latte .button.is-link.is-inverted.is-outlined.is-hovered,html.theme--catppuccin-latte .button.is-link.is-inverted.is-outlined:focus,html.theme--catppuccin-latte .button.is-link.is-inverted.is-outlined.is-focused{background-color:#fff;color:#1e66f5}html.theme--catppuccin-latte .button.is-link.is-inverted.is-outlined.is-loading:hover::after,html.theme--catppuccin-latte .button.is-link.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-latte .button.is-link.is-inverted.is-outlined.is-loading:focus::after,html.theme--catppuccin-latte .button.is-link.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #1e66f5 #1e66f5 !important}html.theme--catppuccin-latte .button.is-link.is-inverted.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-latte .button.is-link.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}html.theme--catppuccin-latte .button.is-link.is-light{background-color:#ebf2fe;color:#0a52e1}html.theme--catppuccin-latte .button.is-link.is-light:hover,html.theme--catppuccin-latte .button.is-link.is-light.is-hovered{background-color:#dfe9fe;border-color:transparent;color:#0a52e1}html.theme--catppuccin-latte .button.is-link.is-light:active,html.theme--catppuccin-latte .button.is-link.is-light.is-active{background-color:#d3e1fd;border-color:transparent;color:#0a52e1}html.theme--catppuccin-latte .button.is-info{background-color:#179299;border-color:transparent;color:#fff}html.theme--catppuccin-latte .button.is-info:hover,html.theme--catppuccin-latte .button.is-info.is-hovered{background-color:#15878e;border-color:transparent;color:#fff}html.theme--catppuccin-latte .button.is-info:focus,html.theme--catppuccin-latte .button.is-info.is-focused{border-color:transparent;color:#fff}html.theme--catppuccin-latte .button.is-info:focus:not(:active),html.theme--catppuccin-latte .button.is-info.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(23,146,153,0.25)}html.theme--catppuccin-latte .button.is-info:active,html.theme--catppuccin-latte .button.is-info.is-active{background-color:#147d83;border-color:transparent;color:#fff}html.theme--catppuccin-latte .button.is-info[disabled],fieldset[disabled] html.theme--catppuccin-latte .button.is-info{background-color:#179299;border-color:#179299;box-shadow:none}html.theme--catppuccin-latte .button.is-info.is-inverted{background-color:#fff;color:#179299}html.theme--catppuccin-latte .button.is-info.is-inverted:hover,html.theme--catppuccin-latte .button.is-info.is-inverted.is-hovered{background-color:#f2f2f2}html.theme--catppuccin-latte .button.is-info.is-inverted[disabled],fieldset[disabled] html.theme--catppuccin-latte .button.is-info.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#179299}html.theme--catppuccin-latte .button.is-info.is-loading::after{border-color:transparent transparent #fff #fff !important}html.theme--catppuccin-latte .button.is-info.is-outlined{background-color:transparent;border-color:#179299;color:#179299}html.theme--catppuccin-latte .button.is-info.is-outlined:hover,html.theme--catppuccin-latte .button.is-info.is-outlined.is-hovered,html.theme--catppuccin-latte .button.is-info.is-outlined:focus,html.theme--catppuccin-latte .button.is-info.is-outlined.is-focused{background-color:#179299;border-color:#179299;color:#fff}html.theme--catppuccin-latte .button.is-info.is-outlined.is-loading::after{border-color:transparent transparent #179299 #179299 !important}html.theme--catppuccin-latte .button.is-info.is-outlined.is-loading:hover::after,html.theme--catppuccin-latte .button.is-info.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-latte .button.is-info.is-outlined.is-loading:focus::after,html.theme--catppuccin-latte .button.is-info.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #fff #fff !important}html.theme--catppuccin-latte .button.is-info.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-latte .button.is-info.is-outlined{background-color:transparent;border-color:#179299;box-shadow:none;color:#179299}html.theme--catppuccin-latte .button.is-info.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}html.theme--catppuccin-latte .button.is-info.is-inverted.is-outlined:hover,html.theme--catppuccin-latte .button.is-info.is-inverted.is-outlined.is-hovered,html.theme--catppuccin-latte .button.is-info.is-inverted.is-outlined:focus,html.theme--catppuccin-latte .button.is-info.is-inverted.is-outlined.is-focused{background-color:#fff;color:#179299}html.theme--catppuccin-latte .button.is-info.is-inverted.is-outlined.is-loading:hover::after,html.theme--catppuccin-latte .button.is-info.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-latte .button.is-info.is-inverted.is-outlined.is-loading:focus::after,html.theme--catppuccin-latte .button.is-info.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #179299 #179299 !important}html.theme--catppuccin-latte .button.is-info.is-inverted.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-latte .button.is-info.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}html.theme--catppuccin-latte .button.is-info.is-light{background-color:#edfcfc;color:#1cb2ba}html.theme--catppuccin-latte .button.is-info.is-light:hover,html.theme--catppuccin-latte .button.is-info.is-light.is-hovered{background-color:#e2f9fb;border-color:transparent;color:#1cb2ba}html.theme--catppuccin-latte .button.is-info.is-light:active,html.theme--catppuccin-latte .button.is-info.is-light.is-active{background-color:#d7f7f9;border-color:transparent;color:#1cb2ba}html.theme--catppuccin-latte .button.is-success{background-color:#40a02b;border-color:transparent;color:#fff}html.theme--catppuccin-latte .button.is-success:hover,html.theme--catppuccin-latte .button.is-success.is-hovered{background-color:#3c9628;border-color:transparent;color:#fff}html.theme--catppuccin-latte .button.is-success:focus,html.theme--catppuccin-latte .button.is-success.is-focused{border-color:transparent;color:#fff}html.theme--catppuccin-latte .button.is-success:focus:not(:active),html.theme--catppuccin-latte .button.is-success.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(64,160,43,0.25)}html.theme--catppuccin-latte .button.is-success:active,html.theme--catppuccin-latte .button.is-success.is-active{background-color:#388c26;border-color:transparent;color:#fff}html.theme--catppuccin-latte .button.is-success[disabled],fieldset[disabled] html.theme--catppuccin-latte .button.is-success{background-color:#40a02b;border-color:#40a02b;box-shadow:none}html.theme--catppuccin-latte .button.is-success.is-inverted{background-color:#fff;color:#40a02b}html.theme--catppuccin-latte .button.is-success.is-inverted:hover,html.theme--catppuccin-latte .button.is-success.is-inverted.is-hovered{background-color:#f2f2f2}html.theme--catppuccin-latte .button.is-success.is-inverted[disabled],fieldset[disabled] html.theme--catppuccin-latte .button.is-success.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#40a02b}html.theme--catppuccin-latte .button.is-success.is-loading::after{border-color:transparent transparent #fff #fff !important}html.theme--catppuccin-latte .button.is-success.is-outlined{background-color:transparent;border-color:#40a02b;color:#40a02b}html.theme--catppuccin-latte .button.is-success.is-outlined:hover,html.theme--catppuccin-latte .button.is-success.is-outlined.is-hovered,html.theme--catppuccin-latte .button.is-success.is-outlined:focus,html.theme--catppuccin-latte .button.is-success.is-outlined.is-focused{background-color:#40a02b;border-color:#40a02b;color:#fff}html.theme--catppuccin-latte .button.is-success.is-outlined.is-loading::after{border-color:transparent transparent #40a02b #40a02b !important}html.theme--catppuccin-latte .button.is-success.is-outlined.is-loading:hover::after,html.theme--catppuccin-latte .button.is-success.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-latte .button.is-success.is-outlined.is-loading:focus::after,html.theme--catppuccin-latte .button.is-success.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #fff #fff !important}html.theme--catppuccin-latte .button.is-success.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-latte .button.is-success.is-outlined{background-color:transparent;border-color:#40a02b;box-shadow:none;color:#40a02b}html.theme--catppuccin-latte .button.is-success.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}html.theme--catppuccin-latte .button.is-success.is-inverted.is-outlined:hover,html.theme--catppuccin-latte .button.is-success.is-inverted.is-outlined.is-hovered,html.theme--catppuccin-latte .button.is-success.is-inverted.is-outlined:focus,html.theme--catppuccin-latte .button.is-success.is-inverted.is-outlined.is-focused{background-color:#fff;color:#40a02b}html.theme--catppuccin-latte .button.is-success.is-inverted.is-outlined.is-loading:hover::after,html.theme--catppuccin-latte .button.is-success.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-latte .button.is-success.is-inverted.is-outlined.is-loading:focus::after,html.theme--catppuccin-latte .button.is-success.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #40a02b #40a02b !important}html.theme--catppuccin-latte .button.is-success.is-inverted.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-latte .button.is-success.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}html.theme--catppuccin-latte .button.is-success.is-light{background-color:#f1fbef;color:#40a12b}html.theme--catppuccin-latte .button.is-success.is-light:hover,html.theme--catppuccin-latte .button.is-success.is-light.is-hovered{background-color:#e8f8e5;border-color:transparent;color:#40a12b}html.theme--catppuccin-latte .button.is-success.is-light:active,html.theme--catppuccin-latte .button.is-success.is-light.is-active{background-color:#e0f5db;border-color:transparent;color:#40a12b}html.theme--catppuccin-latte .button.is-warning{background-color:#df8e1d;border-color:transparent;color:#fff}html.theme--catppuccin-latte .button.is-warning:hover,html.theme--catppuccin-latte .button.is-warning.is-hovered{background-color:#d4871c;border-color:transparent;color:#fff}html.theme--catppuccin-latte .button.is-warning:focus,html.theme--catppuccin-latte .button.is-warning.is-focused{border-color:transparent;color:#fff}html.theme--catppuccin-latte .button.is-warning:focus:not(:active),html.theme--catppuccin-latte .button.is-warning.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(223,142,29,0.25)}html.theme--catppuccin-latte .button.is-warning:active,html.theme--catppuccin-latte .button.is-warning.is-active{background-color:#c8801a;border-color:transparent;color:#fff}html.theme--catppuccin-latte .button.is-warning[disabled],fieldset[disabled] html.theme--catppuccin-latte .button.is-warning{background-color:#df8e1d;border-color:#df8e1d;box-shadow:none}html.theme--catppuccin-latte .button.is-warning.is-inverted{background-color:#fff;color:#df8e1d}html.theme--catppuccin-latte .button.is-warning.is-inverted:hover,html.theme--catppuccin-latte .button.is-warning.is-inverted.is-hovered{background-color:#f2f2f2}html.theme--catppuccin-latte .button.is-warning.is-inverted[disabled],fieldset[disabled] html.theme--catppuccin-latte .button.is-warning.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#df8e1d}html.theme--catppuccin-latte .button.is-warning.is-loading::after{border-color:transparent transparent #fff #fff !important}html.theme--catppuccin-latte .button.is-warning.is-outlined{background-color:transparent;border-color:#df8e1d;color:#df8e1d}html.theme--catppuccin-latte .button.is-warning.is-outlined:hover,html.theme--catppuccin-latte .button.is-warning.is-outlined.is-hovered,html.theme--catppuccin-latte .button.is-warning.is-outlined:focus,html.theme--catppuccin-latte .button.is-warning.is-outlined.is-focused{background-color:#df8e1d;border-color:#df8e1d;color:#fff}html.theme--catppuccin-latte .button.is-warning.is-outlined.is-loading::after{border-color:transparent transparent #df8e1d #df8e1d !important}html.theme--catppuccin-latte .button.is-warning.is-outlined.is-loading:hover::after,html.theme--catppuccin-latte .button.is-warning.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-latte .button.is-warning.is-outlined.is-loading:focus::after,html.theme--catppuccin-latte .button.is-warning.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #fff #fff !important}html.theme--catppuccin-latte .button.is-warning.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-latte .button.is-warning.is-outlined{background-color:transparent;border-color:#df8e1d;box-shadow:none;color:#df8e1d}html.theme--catppuccin-latte .button.is-warning.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}html.theme--catppuccin-latte .button.is-warning.is-inverted.is-outlined:hover,html.theme--catppuccin-latte .button.is-warning.is-inverted.is-outlined.is-hovered,html.theme--catppuccin-latte .button.is-warning.is-inverted.is-outlined:focus,html.theme--catppuccin-latte .button.is-warning.is-inverted.is-outlined.is-focused{background-color:#fff;color:#df8e1d}html.theme--catppuccin-latte .button.is-warning.is-inverted.is-outlined.is-loading:hover::after,html.theme--catppuccin-latte .button.is-warning.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-latte .button.is-warning.is-inverted.is-outlined.is-loading:focus::after,html.theme--catppuccin-latte .button.is-warning.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #df8e1d #df8e1d !important}html.theme--catppuccin-latte .button.is-warning.is-inverted.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-latte .button.is-warning.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}html.theme--catppuccin-latte .button.is-warning.is-light{background-color:#fdf6ed;color:#9e6515}html.theme--catppuccin-latte .button.is-warning.is-light:hover,html.theme--catppuccin-latte .button.is-warning.is-light.is-hovered{background-color:#fbf1e2;border-color:transparent;color:#9e6515}html.theme--catppuccin-latte .button.is-warning.is-light:active,html.theme--catppuccin-latte .button.is-warning.is-light.is-active{background-color:#faebd6;border-color:transparent;color:#9e6515}html.theme--catppuccin-latte .button.is-danger{background-color:#d20f39;border-color:transparent;color:#fff}html.theme--catppuccin-latte .button.is-danger:hover,html.theme--catppuccin-latte .button.is-danger.is-hovered{background-color:#c60e36;border-color:transparent;color:#fff}html.theme--catppuccin-latte .button.is-danger:focus,html.theme--catppuccin-latte .button.is-danger.is-focused{border-color:transparent;color:#fff}html.theme--catppuccin-latte .button.is-danger:focus:not(:active),html.theme--catppuccin-latte .button.is-danger.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(210,15,57,0.25)}html.theme--catppuccin-latte .button.is-danger:active,html.theme--catppuccin-latte .button.is-danger.is-active{background-color:#ba0d33;border-color:transparent;color:#fff}html.theme--catppuccin-latte .button.is-danger[disabled],fieldset[disabled] html.theme--catppuccin-latte .button.is-danger{background-color:#d20f39;border-color:#d20f39;box-shadow:none}html.theme--catppuccin-latte .button.is-danger.is-inverted{background-color:#fff;color:#d20f39}html.theme--catppuccin-latte .button.is-danger.is-inverted:hover,html.theme--catppuccin-latte .button.is-danger.is-inverted.is-hovered{background-color:#f2f2f2}html.theme--catppuccin-latte .button.is-danger.is-inverted[disabled],fieldset[disabled] html.theme--catppuccin-latte .button.is-danger.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#d20f39}html.theme--catppuccin-latte .button.is-danger.is-loading::after{border-color:transparent transparent #fff #fff !important}html.theme--catppuccin-latte .button.is-danger.is-outlined{background-color:transparent;border-color:#d20f39;color:#d20f39}html.theme--catppuccin-latte .button.is-danger.is-outlined:hover,html.theme--catppuccin-latte .button.is-danger.is-outlined.is-hovered,html.theme--catppuccin-latte .button.is-danger.is-outlined:focus,html.theme--catppuccin-latte .button.is-danger.is-outlined.is-focused{background-color:#d20f39;border-color:#d20f39;color:#fff}html.theme--catppuccin-latte .button.is-danger.is-outlined.is-loading::after{border-color:transparent transparent #d20f39 #d20f39 !important}html.theme--catppuccin-latte .button.is-danger.is-outlined.is-loading:hover::after,html.theme--catppuccin-latte .button.is-danger.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-latte .button.is-danger.is-outlined.is-loading:focus::after,html.theme--catppuccin-latte .button.is-danger.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #fff #fff !important}html.theme--catppuccin-latte .button.is-danger.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-latte .button.is-danger.is-outlined{background-color:transparent;border-color:#d20f39;box-shadow:none;color:#d20f39}html.theme--catppuccin-latte .button.is-danger.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}html.theme--catppuccin-latte .button.is-danger.is-inverted.is-outlined:hover,html.theme--catppuccin-latte .button.is-danger.is-inverted.is-outlined.is-hovered,html.theme--catppuccin-latte .button.is-danger.is-inverted.is-outlined:focus,html.theme--catppuccin-latte .button.is-danger.is-inverted.is-outlined.is-focused{background-color:#fff;color:#d20f39}html.theme--catppuccin-latte .button.is-danger.is-inverted.is-outlined.is-loading:hover::after,html.theme--catppuccin-latte .button.is-danger.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-latte .button.is-danger.is-inverted.is-outlined.is-loading:focus::after,html.theme--catppuccin-latte .button.is-danger.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #d20f39 #d20f39 !important}html.theme--catppuccin-latte .button.is-danger.is-inverted.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-latte .button.is-danger.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}html.theme--catppuccin-latte .button.is-danger.is-light{background-color:#feecf0;color:#e9113f}html.theme--catppuccin-latte .button.is-danger.is-light:hover,html.theme--catppuccin-latte .button.is-danger.is-light.is-hovered{background-color:#fde0e6;border-color:transparent;color:#e9113f}html.theme--catppuccin-latte .button.is-danger.is-light:active,html.theme--catppuccin-latte .button.is-danger.is-light.is-active{background-color:#fcd4dd;border-color:transparent;color:#e9113f}html.theme--catppuccin-latte .button.is-small,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.button{font-size:.75rem}html.theme--catppuccin-latte .button.is-small:not(.is-rounded),html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.button:not(.is-rounded){border-radius:3px}html.theme--catppuccin-latte .button.is-normal{font-size:1rem}html.theme--catppuccin-latte .button.is-medium{font-size:1.25rem}html.theme--catppuccin-latte .button.is-large{font-size:1.5rem}html.theme--catppuccin-latte .button[disabled],fieldset[disabled] html.theme--catppuccin-latte .button{background-color:#9ca0b0;border-color:#acb0be;box-shadow:none;opacity:.5}html.theme--catppuccin-latte .button.is-fullwidth{display:flex;width:100%}html.theme--catppuccin-latte .button.is-loading{color:transparent !important;pointer-events:none}html.theme--catppuccin-latte .button.is-loading::after{position:absolute;left:calc(50% - (1em * 0.5));top:calc(50% - (1em * 0.5));position:absolute !important}html.theme--catppuccin-latte .button.is-static{background-color:#e6e9ef;border-color:#acb0be;color:#8c8fa1;box-shadow:none;pointer-events:none}html.theme--catppuccin-latte .button.is-rounded,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.button{border-radius:9999px;padding-left:calc(1em + 0.25em);padding-right:calc(1em + 0.25em)}html.theme--catppuccin-latte .buttons{align-items:center;display:flex;flex-wrap:wrap;justify-content:flex-start}html.theme--catppuccin-latte .buttons .button{margin-bottom:0.5rem}html.theme--catppuccin-latte .buttons .button:not(:last-child):not(.is-fullwidth){margin-right:.5rem}html.theme--catppuccin-latte .buttons:last-child{margin-bottom:-0.5rem}html.theme--catppuccin-latte .buttons:not(:last-child){margin-bottom:1rem}html.theme--catppuccin-latte .buttons.are-small .button:not(.is-normal):not(.is-medium):not(.is-large){font-size:.75rem}html.theme--catppuccin-latte .buttons.are-small .button:not(.is-normal):not(.is-medium):not(.is-large):not(.is-rounded){border-radius:3px}html.theme--catppuccin-latte .buttons.are-medium .button:not(.is-small):not(.is-normal):not(.is-large){font-size:1.25rem}html.theme--catppuccin-latte .buttons.are-large .button:not(.is-small):not(.is-normal):not(.is-medium){font-size:1.5rem}html.theme--catppuccin-latte .buttons.has-addons .button:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}html.theme--catppuccin-latte .buttons.has-addons .button:not(:last-child){border-bottom-right-radius:0;border-top-right-radius:0;margin-right:-1px}html.theme--catppuccin-latte .buttons.has-addons .button:last-child{margin-right:0}html.theme--catppuccin-latte .buttons.has-addons .button:hover,html.theme--catppuccin-latte .buttons.has-addons .button.is-hovered{z-index:2}html.theme--catppuccin-latte .buttons.has-addons .button:focus,html.theme--catppuccin-latte .buttons.has-addons .button.is-focused,html.theme--catppuccin-latte .buttons.has-addons .button:active,html.theme--catppuccin-latte .buttons.has-addons .button.is-active,html.theme--catppuccin-latte .buttons.has-addons .button.is-selected{z-index:3}html.theme--catppuccin-latte .buttons.has-addons .button:focus:hover,html.theme--catppuccin-latte .buttons.has-addons .button.is-focused:hover,html.theme--catppuccin-latte .buttons.has-addons .button:active:hover,html.theme--catppuccin-latte .buttons.has-addons .button.is-active:hover,html.theme--catppuccin-latte .buttons.has-addons .button.is-selected:hover{z-index:4}html.theme--catppuccin-latte .buttons.has-addons .button.is-expanded{flex-grow:1;flex-shrink:1}html.theme--catppuccin-latte .buttons.is-centered{justify-content:center}html.theme--catppuccin-latte .buttons.is-centered:not(.has-addons) .button:not(.is-fullwidth){margin-left:0.25rem;margin-right:0.25rem}html.theme--catppuccin-latte .buttons.is-right{justify-content:flex-end}html.theme--catppuccin-latte .buttons.is-right:not(.has-addons) .button:not(.is-fullwidth){margin-left:0.25rem;margin-right:0.25rem}@media screen and (max-width: 768px){html.theme--catppuccin-latte .button.is-responsive.is-small,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-responsive{font-size:.5625rem}html.theme--catppuccin-latte .button.is-responsive,html.theme--catppuccin-latte .button.is-responsive.is-normal{font-size:.65625rem}html.theme--catppuccin-latte .button.is-responsive.is-medium{font-size:.75rem}html.theme--catppuccin-latte .button.is-responsive.is-large{font-size:1rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--catppuccin-latte .button.is-responsive.is-small,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-responsive{font-size:.65625rem}html.theme--catppuccin-latte .button.is-responsive,html.theme--catppuccin-latte .button.is-responsive.is-normal{font-size:.75rem}html.theme--catppuccin-latte .button.is-responsive.is-medium{font-size:1rem}html.theme--catppuccin-latte .button.is-responsive.is-large{font-size:1.25rem}}html.theme--catppuccin-latte .container{flex-grow:1;margin:0 auto;position:relative;width:auto}html.theme--catppuccin-latte .container.is-fluid{max-width:none !important;padding-left:32px;padding-right:32px;width:100%}@media screen and (min-width: 1056px){html.theme--catppuccin-latte .container{max-width:992px}}@media screen and (max-width: 1215px){html.theme--catppuccin-latte .container.is-widescreen:not(.is-max-desktop){max-width:1152px}}@media screen and (max-width: 1407px){html.theme--catppuccin-latte .container.is-fullhd:not(.is-max-desktop):not(.is-max-widescreen){max-width:1344px}}@media screen and (min-width: 1216px){html.theme--catppuccin-latte .container:not(.is-max-desktop){max-width:1152px}}@media screen and (min-width: 1408px){html.theme--catppuccin-latte .container:not(.is-max-desktop):not(.is-max-widescreen){max-width:1344px}}html.theme--catppuccin-latte .content li+li{margin-top:0.25em}html.theme--catppuccin-latte .content p:not(:last-child),html.theme--catppuccin-latte .content dl:not(:last-child),html.theme--catppuccin-latte .content ol:not(:last-child),html.theme--catppuccin-latte .content ul:not(:last-child),html.theme--catppuccin-latte .content blockquote:not(:last-child),html.theme--catppuccin-latte .content pre:not(:last-child),html.theme--catppuccin-latte .content table:not(:last-child){margin-bottom:1em}html.theme--catppuccin-latte .content h1,html.theme--catppuccin-latte .content h2,html.theme--catppuccin-latte .content h3,html.theme--catppuccin-latte .content h4,html.theme--catppuccin-latte .content h5,html.theme--catppuccin-latte .content h6{color:#4c4f69;font-weight:600;line-height:1.125}html.theme--catppuccin-latte .content h1{font-size:2em;margin-bottom:0.5em}html.theme--catppuccin-latte .content h1:not(:first-child){margin-top:1em}html.theme--catppuccin-latte .content h2{font-size:1.75em;margin-bottom:0.5714em}html.theme--catppuccin-latte .content h2:not(:first-child){margin-top:1.1428em}html.theme--catppuccin-latte .content h3{font-size:1.5em;margin-bottom:0.6666em}html.theme--catppuccin-latte .content h3:not(:first-child){margin-top:1.3333em}html.theme--catppuccin-latte .content h4{font-size:1.25em;margin-bottom:0.8em}html.theme--catppuccin-latte .content h5{font-size:1.125em;margin-bottom:0.8888em}html.theme--catppuccin-latte .content h6{font-size:1em;margin-bottom:1em}html.theme--catppuccin-latte .content blockquote{background-color:#e6e9ef;border-left:5px solid #acb0be;padding:1.25em 1.5em}html.theme--catppuccin-latte .content ol{list-style-position:outside;margin-left:2em;margin-top:1em}html.theme--catppuccin-latte .content ol:not([type]){list-style-type:decimal}html.theme--catppuccin-latte .content ol.is-lower-alpha:not([type]){list-style-type:lower-alpha}html.theme--catppuccin-latte .content ol.is-lower-roman:not([type]){list-style-type:lower-roman}html.theme--catppuccin-latte .content ol.is-upper-alpha:not([type]){list-style-type:upper-alpha}html.theme--catppuccin-latte .content ol.is-upper-roman:not([type]){list-style-type:upper-roman}html.theme--catppuccin-latte .content ul{list-style:disc outside;margin-left:2em;margin-top:1em}html.theme--catppuccin-latte .content ul ul{list-style-type:circle;margin-top:0.5em}html.theme--catppuccin-latte .content ul ul ul{list-style-type:square}html.theme--catppuccin-latte .content dd{margin-left:2em}html.theme--catppuccin-latte .content figure{margin-left:2em;margin-right:2em;text-align:center}html.theme--catppuccin-latte .content figure:not(:first-child){margin-top:2em}html.theme--catppuccin-latte .content figure:not(:last-child){margin-bottom:2em}html.theme--catppuccin-latte .content figure img{display:inline-block}html.theme--catppuccin-latte .content figure figcaption{font-style:italic}html.theme--catppuccin-latte .content pre{-webkit-overflow-scrolling:touch;overflow-x:auto;padding:0;white-space:pre;word-wrap:normal}html.theme--catppuccin-latte .content sup,html.theme--catppuccin-latte .content sub{font-size:75%}html.theme--catppuccin-latte .content table{width:100%}html.theme--catppuccin-latte .content table td,html.theme--catppuccin-latte .content table th{border:1px solid #acb0be;border-width:0 0 1px;padding:0.5em 0.75em;vertical-align:top}html.theme--catppuccin-latte .content table th{color:#41445a}html.theme--catppuccin-latte .content table th:not([align]){text-align:inherit}html.theme--catppuccin-latte .content table thead td,html.theme--catppuccin-latte .content table thead th{border-width:0 0 2px;color:#41445a}html.theme--catppuccin-latte .content table tfoot td,html.theme--catppuccin-latte .content table tfoot th{border-width:2px 0 0;color:#41445a}html.theme--catppuccin-latte .content table tbody tr:last-child td,html.theme--catppuccin-latte .content table tbody tr:last-child th{border-bottom-width:0}html.theme--catppuccin-latte .content .tabs li+li{margin-top:0}html.theme--catppuccin-latte .content.is-small,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.content{font-size:.75rem}html.theme--catppuccin-latte .content.is-normal{font-size:1rem}html.theme--catppuccin-latte .content.is-medium{font-size:1.25rem}html.theme--catppuccin-latte .content.is-large{font-size:1.5rem}html.theme--catppuccin-latte .icon{align-items:center;display:inline-flex;justify-content:center;height:1.5rem;width:1.5rem}html.theme--catppuccin-latte .icon.is-small,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.icon{height:1rem;width:1rem}html.theme--catppuccin-latte .icon.is-medium{height:2rem;width:2rem}html.theme--catppuccin-latte .icon.is-large{height:3rem;width:3rem}html.theme--catppuccin-latte .icon-text{align-items:flex-start;color:inherit;display:inline-flex;flex-wrap:wrap;line-height:1.5rem;vertical-align:top}html.theme--catppuccin-latte .icon-text .icon{flex-grow:0;flex-shrink:0}html.theme--catppuccin-latte .icon-text .icon:not(:last-child){margin-right:.25em}html.theme--catppuccin-latte .icon-text .icon:not(:first-child){margin-left:.25em}html.theme--catppuccin-latte div.icon-text{display:flex}html.theme--catppuccin-latte .image,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img{display:block;position:relative}html.theme--catppuccin-latte .image img,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img img{display:block;height:auto;width:100%}html.theme--catppuccin-latte .image img.is-rounded,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img img.is-rounded{border-radius:9999px}html.theme--catppuccin-latte .image.is-fullwidth,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-fullwidth{width:100%}html.theme--catppuccin-latte .image.is-square img,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-square img,html.theme--catppuccin-latte .image.is-square .has-ratio,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-square .has-ratio,html.theme--catppuccin-latte .image.is-1by1 img,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-1by1 img,html.theme--catppuccin-latte .image.is-1by1 .has-ratio,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-1by1 .has-ratio,html.theme--catppuccin-latte .image.is-5by4 img,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-5by4 img,html.theme--catppuccin-latte .image.is-5by4 .has-ratio,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-5by4 .has-ratio,html.theme--catppuccin-latte .image.is-4by3 img,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-4by3 img,html.theme--catppuccin-latte .image.is-4by3 .has-ratio,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-4by3 .has-ratio,html.theme--catppuccin-latte .image.is-3by2 img,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-3by2 img,html.theme--catppuccin-latte .image.is-3by2 .has-ratio,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-3by2 .has-ratio,html.theme--catppuccin-latte .image.is-5by3 img,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-5by3 img,html.theme--catppuccin-latte .image.is-5by3 .has-ratio,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-5by3 .has-ratio,html.theme--catppuccin-latte .image.is-16by9 img,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-16by9 img,html.theme--catppuccin-latte .image.is-16by9 .has-ratio,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-16by9 .has-ratio,html.theme--catppuccin-latte .image.is-2by1 img,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-2by1 img,html.theme--catppuccin-latte .image.is-2by1 .has-ratio,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-2by1 .has-ratio,html.theme--catppuccin-latte .image.is-3by1 img,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-3by1 img,html.theme--catppuccin-latte .image.is-3by1 .has-ratio,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-3by1 .has-ratio,html.theme--catppuccin-latte .image.is-4by5 img,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-4by5 img,html.theme--catppuccin-latte .image.is-4by5 .has-ratio,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-4by5 .has-ratio,html.theme--catppuccin-latte .image.is-3by4 img,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-3by4 img,html.theme--catppuccin-latte .image.is-3by4 .has-ratio,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-3by4 .has-ratio,html.theme--catppuccin-latte .image.is-2by3 img,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-2by3 img,html.theme--catppuccin-latte .image.is-2by3 .has-ratio,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-2by3 .has-ratio,html.theme--catppuccin-latte .image.is-3by5 img,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-3by5 img,html.theme--catppuccin-latte .image.is-3by5 .has-ratio,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-3by5 .has-ratio,html.theme--catppuccin-latte .image.is-9by16 img,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-9by16 img,html.theme--catppuccin-latte .image.is-9by16 .has-ratio,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-9by16 .has-ratio,html.theme--catppuccin-latte .image.is-1by2 img,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-1by2 img,html.theme--catppuccin-latte .image.is-1by2 .has-ratio,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-1by2 .has-ratio,html.theme--catppuccin-latte .image.is-1by3 img,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-1by3 img,html.theme--catppuccin-latte .image.is-1by3 .has-ratio,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-1by3 .has-ratio{height:100%;width:100%}html.theme--catppuccin-latte .image.is-square,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-square,html.theme--catppuccin-latte .image.is-1by1,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-1by1{padding-top:100%}html.theme--catppuccin-latte .image.is-5by4,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-5by4{padding-top:80%}html.theme--catppuccin-latte .image.is-4by3,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-4by3{padding-top:75%}html.theme--catppuccin-latte .image.is-3by2,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-3by2{padding-top:66.6666%}html.theme--catppuccin-latte .image.is-5by3,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-5by3{padding-top:60%}html.theme--catppuccin-latte .image.is-16by9,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-16by9{padding-top:56.25%}html.theme--catppuccin-latte .image.is-2by1,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-2by1{padding-top:50%}html.theme--catppuccin-latte .image.is-3by1,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-3by1{padding-top:33.3333%}html.theme--catppuccin-latte .image.is-4by5,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-4by5{padding-top:125%}html.theme--catppuccin-latte .image.is-3by4,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-3by4{padding-top:133.3333%}html.theme--catppuccin-latte .image.is-2by3,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-2by3{padding-top:150%}html.theme--catppuccin-latte .image.is-3by5,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-3by5{padding-top:166.6666%}html.theme--catppuccin-latte .image.is-9by16,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-9by16{padding-top:177.7777%}html.theme--catppuccin-latte .image.is-1by2,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-1by2{padding-top:200%}html.theme--catppuccin-latte .image.is-1by3,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-1by3{padding-top:300%}html.theme--catppuccin-latte .image.is-16x16,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-16x16{height:16px;width:16px}html.theme--catppuccin-latte .image.is-24x24,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-24x24{height:24px;width:24px}html.theme--catppuccin-latte .image.is-32x32,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-32x32{height:32px;width:32px}html.theme--catppuccin-latte .image.is-48x48,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-48x48{height:48px;width:48px}html.theme--catppuccin-latte .image.is-64x64,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-64x64{height:64px;width:64px}html.theme--catppuccin-latte .image.is-96x96,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-96x96{height:96px;width:96px}html.theme--catppuccin-latte .image.is-128x128,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-128x128{height:128px;width:128px}html.theme--catppuccin-latte .notification{background-color:#e6e9ef;border-radius:.4em;position:relative;padding:1.25rem 2.5rem 1.25rem 1.5rem}html.theme--catppuccin-latte .notification a:not(.button):not(.dropdown-item){color:currentColor;text-decoration:underline}html.theme--catppuccin-latte .notification strong{color:currentColor}html.theme--catppuccin-latte .notification code,html.theme--catppuccin-latte .notification pre{background:#fff}html.theme--catppuccin-latte .notification pre code{background:transparent}html.theme--catppuccin-latte .notification>.delete{right:.5rem;position:absolute;top:0.5rem}html.theme--catppuccin-latte .notification .title,html.theme--catppuccin-latte .notification .subtitle,html.theme--catppuccin-latte .notification .content{color:currentColor}html.theme--catppuccin-latte .notification.is-white{background-color:#fff;color:#0a0a0a}html.theme--catppuccin-latte .notification.is-black{background-color:#0a0a0a;color:#fff}html.theme--catppuccin-latte .notification.is-light{background-color:#f5f5f5;color:rgba(0,0,0,0.7)}html.theme--catppuccin-latte .notification.is-dark,html.theme--catppuccin-latte .content kbd.notification{background-color:#ccd0da;color:rgba(0,0,0,0.7)}html.theme--catppuccin-latte .notification.is-primary,html.theme--catppuccin-latte .docstring>section>a.notification.docs-sourcelink{background-color:#1e66f5;color:#fff}html.theme--catppuccin-latte .notification.is-primary.is-light,html.theme--catppuccin-latte .docstring>section>a.notification.is-light.docs-sourcelink{background-color:#ebf2fe;color:#0a52e1}html.theme--catppuccin-latte .notification.is-link{background-color:#1e66f5;color:#fff}html.theme--catppuccin-latte .notification.is-link.is-light{background-color:#ebf2fe;color:#0a52e1}html.theme--catppuccin-latte .notification.is-info{background-color:#179299;color:#fff}html.theme--catppuccin-latte .notification.is-info.is-light{background-color:#edfcfc;color:#1cb2ba}html.theme--catppuccin-latte .notification.is-success{background-color:#40a02b;color:#fff}html.theme--catppuccin-latte .notification.is-success.is-light{background-color:#f1fbef;color:#40a12b}html.theme--catppuccin-latte .notification.is-warning{background-color:#df8e1d;color:#fff}html.theme--catppuccin-latte .notification.is-warning.is-light{background-color:#fdf6ed;color:#9e6515}html.theme--catppuccin-latte .notification.is-danger{background-color:#d20f39;color:#fff}html.theme--catppuccin-latte .notification.is-danger.is-light{background-color:#feecf0;color:#e9113f}html.theme--catppuccin-latte .progress{-moz-appearance:none;-webkit-appearance:none;border:none;border-radius:9999px;display:block;height:1rem;overflow:hidden;padding:0;width:100%}html.theme--catppuccin-latte .progress::-webkit-progress-bar{background-color:#bcc0cc}html.theme--catppuccin-latte .progress::-webkit-progress-value{background-color:#8c8fa1}html.theme--catppuccin-latte .progress::-moz-progress-bar{background-color:#8c8fa1}html.theme--catppuccin-latte .progress::-ms-fill{background-color:#8c8fa1;border:none}html.theme--catppuccin-latte .progress.is-white::-webkit-progress-value{background-color:#fff}html.theme--catppuccin-latte .progress.is-white::-moz-progress-bar{background-color:#fff}html.theme--catppuccin-latte .progress.is-white::-ms-fill{background-color:#fff}html.theme--catppuccin-latte .progress.is-white:indeterminate{background-image:linear-gradient(to right, #fff 30%, #bcc0cc 30%)}html.theme--catppuccin-latte .progress.is-black::-webkit-progress-value{background-color:#0a0a0a}html.theme--catppuccin-latte .progress.is-black::-moz-progress-bar{background-color:#0a0a0a}html.theme--catppuccin-latte .progress.is-black::-ms-fill{background-color:#0a0a0a}html.theme--catppuccin-latte .progress.is-black:indeterminate{background-image:linear-gradient(to right, #0a0a0a 30%, #bcc0cc 30%)}html.theme--catppuccin-latte .progress.is-light::-webkit-progress-value{background-color:#f5f5f5}html.theme--catppuccin-latte .progress.is-light::-moz-progress-bar{background-color:#f5f5f5}html.theme--catppuccin-latte .progress.is-light::-ms-fill{background-color:#f5f5f5}html.theme--catppuccin-latte .progress.is-light:indeterminate{background-image:linear-gradient(to right, #f5f5f5 30%, #bcc0cc 30%)}html.theme--catppuccin-latte .progress.is-dark::-webkit-progress-value,html.theme--catppuccin-latte .content kbd.progress::-webkit-progress-value{background-color:#ccd0da}html.theme--catppuccin-latte .progress.is-dark::-moz-progress-bar,html.theme--catppuccin-latte .content kbd.progress::-moz-progress-bar{background-color:#ccd0da}html.theme--catppuccin-latte .progress.is-dark::-ms-fill,html.theme--catppuccin-latte .content kbd.progress::-ms-fill{background-color:#ccd0da}html.theme--catppuccin-latte .progress.is-dark:indeterminate,html.theme--catppuccin-latte .content kbd.progress:indeterminate{background-image:linear-gradient(to right, #ccd0da 30%, #bcc0cc 30%)}html.theme--catppuccin-latte .progress.is-primary::-webkit-progress-value,html.theme--catppuccin-latte .docstring>section>a.progress.docs-sourcelink::-webkit-progress-value{background-color:#1e66f5}html.theme--catppuccin-latte .progress.is-primary::-moz-progress-bar,html.theme--catppuccin-latte .docstring>section>a.progress.docs-sourcelink::-moz-progress-bar{background-color:#1e66f5}html.theme--catppuccin-latte .progress.is-primary::-ms-fill,html.theme--catppuccin-latte .docstring>section>a.progress.docs-sourcelink::-ms-fill{background-color:#1e66f5}html.theme--catppuccin-latte .progress.is-primary:indeterminate,html.theme--catppuccin-latte .docstring>section>a.progress.docs-sourcelink:indeterminate{background-image:linear-gradient(to right, #1e66f5 30%, #bcc0cc 30%)}html.theme--catppuccin-latte .progress.is-link::-webkit-progress-value{background-color:#1e66f5}html.theme--catppuccin-latte .progress.is-link::-moz-progress-bar{background-color:#1e66f5}html.theme--catppuccin-latte .progress.is-link::-ms-fill{background-color:#1e66f5}html.theme--catppuccin-latte .progress.is-link:indeterminate{background-image:linear-gradient(to right, #1e66f5 30%, #bcc0cc 30%)}html.theme--catppuccin-latte .progress.is-info::-webkit-progress-value{background-color:#179299}html.theme--catppuccin-latte .progress.is-info::-moz-progress-bar{background-color:#179299}html.theme--catppuccin-latte .progress.is-info::-ms-fill{background-color:#179299}html.theme--catppuccin-latte .progress.is-info:indeterminate{background-image:linear-gradient(to right, #179299 30%, #bcc0cc 30%)}html.theme--catppuccin-latte .progress.is-success::-webkit-progress-value{background-color:#40a02b}html.theme--catppuccin-latte .progress.is-success::-moz-progress-bar{background-color:#40a02b}html.theme--catppuccin-latte .progress.is-success::-ms-fill{background-color:#40a02b}html.theme--catppuccin-latte .progress.is-success:indeterminate{background-image:linear-gradient(to right, #40a02b 30%, #bcc0cc 30%)}html.theme--catppuccin-latte .progress.is-warning::-webkit-progress-value{background-color:#df8e1d}html.theme--catppuccin-latte .progress.is-warning::-moz-progress-bar{background-color:#df8e1d}html.theme--catppuccin-latte .progress.is-warning::-ms-fill{background-color:#df8e1d}html.theme--catppuccin-latte .progress.is-warning:indeterminate{background-image:linear-gradient(to right, #df8e1d 30%, #bcc0cc 30%)}html.theme--catppuccin-latte .progress.is-danger::-webkit-progress-value{background-color:#d20f39}html.theme--catppuccin-latte .progress.is-danger::-moz-progress-bar{background-color:#d20f39}html.theme--catppuccin-latte .progress.is-danger::-ms-fill{background-color:#d20f39}html.theme--catppuccin-latte .progress.is-danger:indeterminate{background-image:linear-gradient(to right, #d20f39 30%, #bcc0cc 30%)}html.theme--catppuccin-latte .progress:indeterminate{animation-duration:1.5s;animation-iteration-count:infinite;animation-name:moveIndeterminate;animation-timing-function:linear;background-color:#bcc0cc;background-image:linear-gradient(to right, #4c4f69 30%, #bcc0cc 30%);background-position:top left;background-repeat:no-repeat;background-size:150% 150%}html.theme--catppuccin-latte .progress:indeterminate::-webkit-progress-bar{background-color:transparent}html.theme--catppuccin-latte .progress:indeterminate::-moz-progress-bar{background-color:transparent}html.theme--catppuccin-latte .progress:indeterminate::-ms-fill{animation-name:none}html.theme--catppuccin-latte .progress.is-small,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.progress{height:.75rem}html.theme--catppuccin-latte .progress.is-medium{height:1.25rem}html.theme--catppuccin-latte .progress.is-large{height:1.5rem}@keyframes moveIndeterminate{from{background-position:200% 0}to{background-position:-200% 0}}html.theme--catppuccin-latte .table{background-color:#bcc0cc;color:#4c4f69}html.theme--catppuccin-latte .table td,html.theme--catppuccin-latte .table th{border:1px solid #acb0be;border-width:0 0 1px;padding:0.5em 0.75em;vertical-align:top}html.theme--catppuccin-latte .table td.is-white,html.theme--catppuccin-latte .table th.is-white{background-color:#fff;border-color:#fff;color:#0a0a0a}html.theme--catppuccin-latte .table td.is-black,html.theme--catppuccin-latte .table th.is-black{background-color:#0a0a0a;border-color:#0a0a0a;color:#fff}html.theme--catppuccin-latte .table td.is-light,html.theme--catppuccin-latte .table th.is-light{background-color:#f5f5f5;border-color:#f5f5f5;color:rgba(0,0,0,0.7)}html.theme--catppuccin-latte .table td.is-dark,html.theme--catppuccin-latte .table th.is-dark{background-color:#ccd0da;border-color:#ccd0da;color:rgba(0,0,0,0.7)}html.theme--catppuccin-latte .table td.is-primary,html.theme--catppuccin-latte .table th.is-primary{background-color:#1e66f5;border-color:#1e66f5;color:#fff}html.theme--catppuccin-latte .table td.is-link,html.theme--catppuccin-latte .table th.is-link{background-color:#1e66f5;border-color:#1e66f5;color:#fff}html.theme--catppuccin-latte .table td.is-info,html.theme--catppuccin-latte .table th.is-info{background-color:#179299;border-color:#179299;color:#fff}html.theme--catppuccin-latte .table td.is-success,html.theme--catppuccin-latte .table th.is-success{background-color:#40a02b;border-color:#40a02b;color:#fff}html.theme--catppuccin-latte .table td.is-warning,html.theme--catppuccin-latte .table th.is-warning{background-color:#df8e1d;border-color:#df8e1d;color:#fff}html.theme--catppuccin-latte .table td.is-danger,html.theme--catppuccin-latte .table th.is-danger{background-color:#d20f39;border-color:#d20f39;color:#fff}html.theme--catppuccin-latte .table td.is-narrow,html.theme--catppuccin-latte .table th.is-narrow{white-space:nowrap;width:1%}html.theme--catppuccin-latte .table td.is-selected,html.theme--catppuccin-latte .table th.is-selected{background-color:#1e66f5;color:#fff}html.theme--catppuccin-latte .table td.is-selected a,html.theme--catppuccin-latte .table td.is-selected strong,html.theme--catppuccin-latte .table th.is-selected a,html.theme--catppuccin-latte .table th.is-selected strong{color:currentColor}html.theme--catppuccin-latte .table td.is-vcentered,html.theme--catppuccin-latte .table th.is-vcentered{vertical-align:middle}html.theme--catppuccin-latte .table th{color:#41445a}html.theme--catppuccin-latte .table th:not([align]){text-align:left}html.theme--catppuccin-latte .table tr.is-selected{background-color:#1e66f5;color:#fff}html.theme--catppuccin-latte .table tr.is-selected a,html.theme--catppuccin-latte .table tr.is-selected strong{color:currentColor}html.theme--catppuccin-latte .table tr.is-selected td,html.theme--catppuccin-latte .table tr.is-selected th{border-color:#fff;color:currentColor}html.theme--catppuccin-latte .table thead{background-color:rgba(0,0,0,0)}html.theme--catppuccin-latte .table thead td,html.theme--catppuccin-latte .table thead th{border-width:0 0 2px;color:#41445a}html.theme--catppuccin-latte .table tfoot{background-color:rgba(0,0,0,0)}html.theme--catppuccin-latte .table tfoot td,html.theme--catppuccin-latte .table tfoot th{border-width:2px 0 0;color:#41445a}html.theme--catppuccin-latte .table tbody{background-color:rgba(0,0,0,0)}html.theme--catppuccin-latte .table tbody tr:last-child td,html.theme--catppuccin-latte .table tbody tr:last-child th{border-bottom-width:0}html.theme--catppuccin-latte .table.is-bordered td,html.theme--catppuccin-latte .table.is-bordered th{border-width:1px}html.theme--catppuccin-latte .table.is-bordered tr:last-child td,html.theme--catppuccin-latte .table.is-bordered tr:last-child th{border-bottom-width:1px}html.theme--catppuccin-latte .table.is-fullwidth{width:100%}html.theme--catppuccin-latte .table.is-hoverable tbody tr:not(.is-selected):hover{background-color:#ccd0da}html.theme--catppuccin-latte .table.is-hoverable.is-striped tbody tr:not(.is-selected):hover{background-color:#ccd0da}html.theme--catppuccin-latte .table.is-hoverable.is-striped tbody tr:not(.is-selected):hover:nth-child(even){background-color:#d2d5de}html.theme--catppuccin-latte .table.is-narrow td,html.theme--catppuccin-latte .table.is-narrow th{padding:0.25em 0.5em}html.theme--catppuccin-latte .table.is-striped tbody tr:not(.is-selected):nth-child(even){background-color:#ccd0da}html.theme--catppuccin-latte .table-container{-webkit-overflow-scrolling:touch;overflow:auto;overflow-y:hidden;max-width:100%}html.theme--catppuccin-latte .tags{align-items:center;display:flex;flex-wrap:wrap;justify-content:flex-start}html.theme--catppuccin-latte .tags .tag,html.theme--catppuccin-latte .tags .content kbd,html.theme--catppuccin-latte .content .tags kbd,html.theme--catppuccin-latte .tags .docstring>section>a.docs-sourcelink{margin-bottom:0.5rem}html.theme--catppuccin-latte .tags .tag:not(:last-child),html.theme--catppuccin-latte .tags .content kbd:not(:last-child),html.theme--catppuccin-latte .content .tags kbd:not(:last-child),html.theme--catppuccin-latte .tags .docstring>section>a.docs-sourcelink:not(:last-child){margin-right:.5rem}html.theme--catppuccin-latte .tags:last-child{margin-bottom:-0.5rem}html.theme--catppuccin-latte .tags:not(:last-child){margin-bottom:1rem}html.theme--catppuccin-latte .tags.are-medium .tag:not(.is-normal):not(.is-large),html.theme--catppuccin-latte .tags.are-medium .content kbd:not(.is-normal):not(.is-large),html.theme--catppuccin-latte .content .tags.are-medium kbd:not(.is-normal):not(.is-large),html.theme--catppuccin-latte .tags.are-medium .docstring>section>a.docs-sourcelink:not(.is-normal):not(.is-large){font-size:1rem}html.theme--catppuccin-latte .tags.are-large .tag:not(.is-normal):not(.is-medium),html.theme--catppuccin-latte .tags.are-large .content kbd:not(.is-normal):not(.is-medium),html.theme--catppuccin-latte .content .tags.are-large kbd:not(.is-normal):not(.is-medium),html.theme--catppuccin-latte .tags.are-large .docstring>section>a.docs-sourcelink:not(.is-normal):not(.is-medium){font-size:1.25rem}html.theme--catppuccin-latte .tags.is-centered{justify-content:center}html.theme--catppuccin-latte .tags.is-centered .tag,html.theme--catppuccin-latte .tags.is-centered .content kbd,html.theme--catppuccin-latte .content .tags.is-centered kbd,html.theme--catppuccin-latte .tags.is-centered .docstring>section>a.docs-sourcelink{margin-right:0.25rem;margin-left:0.25rem}html.theme--catppuccin-latte .tags.is-right{justify-content:flex-end}html.theme--catppuccin-latte .tags.is-right .tag:not(:first-child),html.theme--catppuccin-latte .tags.is-right .content kbd:not(:first-child),html.theme--catppuccin-latte .content .tags.is-right kbd:not(:first-child),html.theme--catppuccin-latte .tags.is-right .docstring>section>a.docs-sourcelink:not(:first-child){margin-left:0.5rem}html.theme--catppuccin-latte .tags.is-right .tag:not(:last-child),html.theme--catppuccin-latte .tags.is-right .content kbd:not(:last-child),html.theme--catppuccin-latte .content .tags.is-right kbd:not(:last-child),html.theme--catppuccin-latte .tags.is-right .docstring>section>a.docs-sourcelink:not(:last-child){margin-right:0}html.theme--catppuccin-latte .tags.has-addons .tag,html.theme--catppuccin-latte .tags.has-addons .content kbd,html.theme--catppuccin-latte .content .tags.has-addons kbd,html.theme--catppuccin-latte .tags.has-addons .docstring>section>a.docs-sourcelink{margin-right:0}html.theme--catppuccin-latte .tags.has-addons .tag:not(:first-child),html.theme--catppuccin-latte .tags.has-addons .content kbd:not(:first-child),html.theme--catppuccin-latte .content .tags.has-addons kbd:not(:first-child),html.theme--catppuccin-latte .tags.has-addons .docstring>section>a.docs-sourcelink:not(:first-child){margin-left:0;border-top-left-radius:0;border-bottom-left-radius:0}html.theme--catppuccin-latte .tags.has-addons .tag:not(:last-child),html.theme--catppuccin-latte .tags.has-addons .content kbd:not(:last-child),html.theme--catppuccin-latte .content .tags.has-addons kbd:not(:last-child),html.theme--catppuccin-latte .tags.has-addons .docstring>section>a.docs-sourcelink:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}html.theme--catppuccin-latte .tag:not(body),html.theme--catppuccin-latte .content kbd:not(body),html.theme--catppuccin-latte .docstring>section>a.docs-sourcelink:not(body){align-items:center;background-color:#e6e9ef;border-radius:.4em;color:#4c4f69;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}html.theme--catppuccin-latte .tag:not(body) .delete,html.theme--catppuccin-latte .content kbd:not(body) .delete,html.theme--catppuccin-latte .docstring>section>a.docs-sourcelink:not(body) .delete{margin-left:.25rem;margin-right:-.375rem}html.theme--catppuccin-latte .tag.is-white:not(body),html.theme--catppuccin-latte .content kbd.is-white:not(body),html.theme--catppuccin-latte .docstring>section>a.docs-sourcelink.is-white:not(body){background-color:#fff;color:#0a0a0a}html.theme--catppuccin-latte .tag.is-black:not(body),html.theme--catppuccin-latte .content kbd.is-black:not(body),html.theme--catppuccin-latte .docstring>section>a.docs-sourcelink.is-black:not(body){background-color:#0a0a0a;color:#fff}html.theme--catppuccin-latte .tag.is-light:not(body),html.theme--catppuccin-latte .content kbd.is-light:not(body),html.theme--catppuccin-latte .docstring>section>a.docs-sourcelink.is-light:not(body){background-color:#f5f5f5;color:rgba(0,0,0,0.7)}html.theme--catppuccin-latte .tag.is-dark:not(body),html.theme--catppuccin-latte .content kbd:not(body),html.theme--catppuccin-latte .docstring>section>a.docs-sourcelink.is-dark:not(body),html.theme--catppuccin-latte .content .docstring>section>kbd:not(body){background-color:#ccd0da;color:rgba(0,0,0,0.7)}html.theme--catppuccin-latte .tag.is-primary:not(body),html.theme--catppuccin-latte .content kbd.is-primary:not(body),html.theme--catppuccin-latte .docstring>section>a.docs-sourcelink:not(body){background-color:#1e66f5;color:#fff}html.theme--catppuccin-latte .tag.is-primary.is-light:not(body),html.theme--catppuccin-latte .content kbd.is-primary.is-light:not(body),html.theme--catppuccin-latte .docstring>section>a.docs-sourcelink.is-light:not(body){background-color:#ebf2fe;color:#0a52e1}html.theme--catppuccin-latte .tag.is-link:not(body),html.theme--catppuccin-latte .content kbd.is-link:not(body),html.theme--catppuccin-latte .docstring>section>a.docs-sourcelink.is-link:not(body){background-color:#1e66f5;color:#fff}html.theme--catppuccin-latte .tag.is-link.is-light:not(body),html.theme--catppuccin-latte .content kbd.is-link.is-light:not(body),html.theme--catppuccin-latte .docstring>section>a.docs-sourcelink.is-link.is-light:not(body){background-color:#ebf2fe;color:#0a52e1}html.theme--catppuccin-latte .tag.is-info:not(body),html.theme--catppuccin-latte .content kbd.is-info:not(body),html.theme--catppuccin-latte .docstring>section>a.docs-sourcelink.is-info:not(body){background-color:#179299;color:#fff}html.theme--catppuccin-latte .tag.is-info.is-light:not(body),html.theme--catppuccin-latte .content kbd.is-info.is-light:not(body),html.theme--catppuccin-latte .docstring>section>a.docs-sourcelink.is-info.is-light:not(body){background-color:#edfcfc;color:#1cb2ba}html.theme--catppuccin-latte .tag.is-success:not(body),html.theme--catppuccin-latte .content kbd.is-success:not(body),html.theme--catppuccin-latte .docstring>section>a.docs-sourcelink.is-success:not(body){background-color:#40a02b;color:#fff}html.theme--catppuccin-latte .tag.is-success.is-light:not(body),html.theme--catppuccin-latte .content kbd.is-success.is-light:not(body),html.theme--catppuccin-latte .docstring>section>a.docs-sourcelink.is-success.is-light:not(body){background-color:#f1fbef;color:#40a12b}html.theme--catppuccin-latte .tag.is-warning:not(body),html.theme--catppuccin-latte .content kbd.is-warning:not(body),html.theme--catppuccin-latte .docstring>section>a.docs-sourcelink.is-warning:not(body){background-color:#df8e1d;color:#fff}html.theme--catppuccin-latte .tag.is-warning.is-light:not(body),html.theme--catppuccin-latte .content kbd.is-warning.is-light:not(body),html.theme--catppuccin-latte .docstring>section>a.docs-sourcelink.is-warning.is-light:not(body){background-color:#fdf6ed;color:#9e6515}html.theme--catppuccin-latte .tag.is-danger:not(body),html.theme--catppuccin-latte .content kbd.is-danger:not(body),html.theme--catppuccin-latte .docstring>section>a.docs-sourcelink.is-danger:not(body){background-color:#d20f39;color:#fff}html.theme--catppuccin-latte .tag.is-danger.is-light:not(body),html.theme--catppuccin-latte .content kbd.is-danger.is-light:not(body),html.theme--catppuccin-latte .docstring>section>a.docs-sourcelink.is-danger.is-light:not(body){background-color:#feecf0;color:#e9113f}html.theme--catppuccin-latte .tag.is-normal:not(body),html.theme--catppuccin-latte .content kbd.is-normal:not(body),html.theme--catppuccin-latte .docstring>section>a.docs-sourcelink.is-normal:not(body){font-size:.75rem}html.theme--catppuccin-latte .tag.is-medium:not(body),html.theme--catppuccin-latte .content kbd.is-medium:not(body),html.theme--catppuccin-latte .docstring>section>a.docs-sourcelink.is-medium:not(body){font-size:1rem}html.theme--catppuccin-latte .tag.is-large:not(body),html.theme--catppuccin-latte .content kbd.is-large:not(body),html.theme--catppuccin-latte .docstring>section>a.docs-sourcelink.is-large:not(body){font-size:1.25rem}html.theme--catppuccin-latte .tag:not(body) .icon:first-child:not(:last-child),html.theme--catppuccin-latte .content kbd:not(body) .icon:first-child:not(:last-child),html.theme--catppuccin-latte .docstring>section>a.docs-sourcelink:not(body) .icon:first-child:not(:last-child){margin-left:-.375em;margin-right:.1875em}html.theme--catppuccin-latte .tag:not(body) .icon:last-child:not(:first-child),html.theme--catppuccin-latte .content kbd:not(body) .icon:last-child:not(:first-child),html.theme--catppuccin-latte .docstring>section>a.docs-sourcelink:not(body) .icon:last-child:not(:first-child){margin-left:.1875em;margin-right:-.375em}html.theme--catppuccin-latte .tag:not(body) .icon:first-child:last-child,html.theme--catppuccin-latte .content kbd:not(body) .icon:first-child:last-child,html.theme--catppuccin-latte .docstring>section>a.docs-sourcelink:not(body) .icon:first-child:last-child{margin-left:-.375em;margin-right:-.375em}html.theme--catppuccin-latte .tag.is-delete:not(body),html.theme--catppuccin-latte .content kbd.is-delete:not(body),html.theme--catppuccin-latte .docstring>section>a.docs-sourcelink.is-delete:not(body){margin-left:1px;padding:0;position:relative;width:2em}html.theme--catppuccin-latte .tag.is-delete:not(body)::before,html.theme--catppuccin-latte .content kbd.is-delete:not(body)::before,html.theme--catppuccin-latte .docstring>section>a.docs-sourcelink.is-delete:not(body)::before,html.theme--catppuccin-latte .tag.is-delete:not(body)::after,html.theme--catppuccin-latte .content kbd.is-delete:not(body)::after,html.theme--catppuccin-latte .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--catppuccin-latte .tag.is-delete:not(body)::before,html.theme--catppuccin-latte .content kbd.is-delete:not(body)::before,html.theme--catppuccin-latte .docstring>section>a.docs-sourcelink.is-delete:not(body)::before{height:1px;width:50%}html.theme--catppuccin-latte .tag.is-delete:not(body)::after,html.theme--catppuccin-latte .content kbd.is-delete:not(body)::after,html.theme--catppuccin-latte .docstring>section>a.docs-sourcelink.is-delete:not(body)::after{height:50%;width:1px}html.theme--catppuccin-latte .tag.is-delete:not(body):hover,html.theme--catppuccin-latte .content kbd.is-delete:not(body):hover,html.theme--catppuccin-latte .docstring>section>a.docs-sourcelink.is-delete:not(body):hover,html.theme--catppuccin-latte .tag.is-delete:not(body):focus,html.theme--catppuccin-latte .content kbd.is-delete:not(body):focus,html.theme--catppuccin-latte .docstring>section>a.docs-sourcelink.is-delete:not(body):focus{background-color:#d6dbe5}html.theme--catppuccin-latte .tag.is-delete:not(body):active,html.theme--catppuccin-latte .content kbd.is-delete:not(body):active,html.theme--catppuccin-latte .docstring>section>a.docs-sourcelink.is-delete:not(body):active{background-color:#c7cedb}html.theme--catppuccin-latte .tag.is-rounded:not(body),html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input:not(body),html.theme--catppuccin-latte .content kbd.is-rounded:not(body),html.theme--catppuccin-latte #documenter .docs-sidebar .content form.docs-search>input:not(body),html.theme--catppuccin-latte .docstring>section>a.docs-sourcelink.is-rounded:not(body){border-radius:9999px}html.theme--catppuccin-latte a.tag:hover,html.theme--catppuccin-latte .docstring>section>a.docs-sourcelink:hover{text-decoration:underline}html.theme--catppuccin-latte .title,html.theme--catppuccin-latte .subtitle{word-break:break-word}html.theme--catppuccin-latte .title em,html.theme--catppuccin-latte .title span,html.theme--catppuccin-latte .subtitle em,html.theme--catppuccin-latte .subtitle span{font-weight:inherit}html.theme--catppuccin-latte .title sub,html.theme--catppuccin-latte .subtitle sub{font-size:.75em}html.theme--catppuccin-latte .title sup,html.theme--catppuccin-latte .subtitle sup{font-size:.75em}html.theme--catppuccin-latte .title .tag,html.theme--catppuccin-latte .title .content kbd,html.theme--catppuccin-latte .content .title kbd,html.theme--catppuccin-latte .title .docstring>section>a.docs-sourcelink,html.theme--catppuccin-latte .subtitle .tag,html.theme--catppuccin-latte .subtitle .content kbd,html.theme--catppuccin-latte .content .subtitle kbd,html.theme--catppuccin-latte .subtitle .docstring>section>a.docs-sourcelink{vertical-align:middle}html.theme--catppuccin-latte .title{color:#fff;font-size:2rem;font-weight:500;line-height:1.125}html.theme--catppuccin-latte .title strong{color:inherit;font-weight:inherit}html.theme--catppuccin-latte .title:not(.is-spaced)+.subtitle{margin-top:-1.25rem}html.theme--catppuccin-latte .title.is-1{font-size:3rem}html.theme--catppuccin-latte .title.is-2{font-size:2.5rem}html.theme--catppuccin-latte .title.is-3{font-size:2rem}html.theme--catppuccin-latte .title.is-4{font-size:1.5rem}html.theme--catppuccin-latte .title.is-5{font-size:1.25rem}html.theme--catppuccin-latte .title.is-6{font-size:1rem}html.theme--catppuccin-latte .title.is-7{font-size:.75rem}html.theme--catppuccin-latte .subtitle{color:#9ca0b0;font-size:1.25rem;font-weight:400;line-height:1.25}html.theme--catppuccin-latte .subtitle strong{color:#9ca0b0;font-weight:600}html.theme--catppuccin-latte .subtitle:not(.is-spaced)+.title{margin-top:-1.25rem}html.theme--catppuccin-latte .subtitle.is-1{font-size:3rem}html.theme--catppuccin-latte .subtitle.is-2{font-size:2.5rem}html.theme--catppuccin-latte .subtitle.is-3{font-size:2rem}html.theme--catppuccin-latte .subtitle.is-4{font-size:1.5rem}html.theme--catppuccin-latte .subtitle.is-5{font-size:1.25rem}html.theme--catppuccin-latte .subtitle.is-6{font-size:1rem}html.theme--catppuccin-latte .subtitle.is-7{font-size:.75rem}html.theme--catppuccin-latte .heading{display:block;font-size:11px;letter-spacing:1px;margin-bottom:5px;text-transform:uppercase}html.theme--catppuccin-latte .number{align-items:center;background-color:#e6e9ef;border-radius:9999px;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--catppuccin-latte .select select,html.theme--catppuccin-latte .textarea,html.theme--catppuccin-latte .input,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input{background-color:#eff1f5;border-color:#acb0be;border-radius:.4em;color:#8c8fa1}html.theme--catppuccin-latte .select select::-moz-placeholder,html.theme--catppuccin-latte .textarea::-moz-placeholder,html.theme--catppuccin-latte .input::-moz-placeholder,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input::-moz-placeholder{color:#868c98}html.theme--catppuccin-latte .select select::-webkit-input-placeholder,html.theme--catppuccin-latte .textarea::-webkit-input-placeholder,html.theme--catppuccin-latte .input::-webkit-input-placeholder,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input::-webkit-input-placeholder{color:#868c98}html.theme--catppuccin-latte .select select:-moz-placeholder,html.theme--catppuccin-latte .textarea:-moz-placeholder,html.theme--catppuccin-latte .input:-moz-placeholder,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input:-moz-placeholder{color:#868c98}html.theme--catppuccin-latte .select select:-ms-input-placeholder,html.theme--catppuccin-latte .textarea:-ms-input-placeholder,html.theme--catppuccin-latte .input:-ms-input-placeholder,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input:-ms-input-placeholder{color:#868c98}html.theme--catppuccin-latte .select select:hover,html.theme--catppuccin-latte .textarea:hover,html.theme--catppuccin-latte .input:hover,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input:hover,html.theme--catppuccin-latte .select select.is-hovered,html.theme--catppuccin-latte .is-hovered.textarea,html.theme--catppuccin-latte .is-hovered.input,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-hovered{border-color:#9ca0b0}html.theme--catppuccin-latte .select select:focus,html.theme--catppuccin-latte .textarea:focus,html.theme--catppuccin-latte .input:focus,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input:focus,html.theme--catppuccin-latte .select select.is-focused,html.theme--catppuccin-latte .is-focused.textarea,html.theme--catppuccin-latte .is-focused.input,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--catppuccin-latte .select select:active,html.theme--catppuccin-latte .textarea:active,html.theme--catppuccin-latte .input:active,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input:active,html.theme--catppuccin-latte .select select.is-active,html.theme--catppuccin-latte .is-active.textarea,html.theme--catppuccin-latte .is-active.input,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-active{border-color:#1e66f5;box-shadow:0 0 0 0.125em rgba(30,102,245,0.25)}html.theme--catppuccin-latte .select select[disabled],html.theme--catppuccin-latte .textarea[disabled],html.theme--catppuccin-latte .input[disabled],html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input[disabled],fieldset[disabled] html.theme--catppuccin-latte .select select,fieldset[disabled] html.theme--catppuccin-latte .textarea,fieldset[disabled] html.theme--catppuccin-latte .input,fieldset[disabled] html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input{background-color:#9ca0b0;border-color:#e6e9ef;box-shadow:none;color:#616587}html.theme--catppuccin-latte .select select[disabled]::-moz-placeholder,html.theme--catppuccin-latte .textarea[disabled]::-moz-placeholder,html.theme--catppuccin-latte .input[disabled]::-moz-placeholder,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input[disabled]::-moz-placeholder,fieldset[disabled] html.theme--catppuccin-latte .select select::-moz-placeholder,fieldset[disabled] html.theme--catppuccin-latte .textarea::-moz-placeholder,fieldset[disabled] html.theme--catppuccin-latte .input::-moz-placeholder,fieldset[disabled] html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input::-moz-placeholder{color:rgba(97,101,135,0.3)}html.theme--catppuccin-latte .select select[disabled]::-webkit-input-placeholder,html.theme--catppuccin-latte .textarea[disabled]::-webkit-input-placeholder,html.theme--catppuccin-latte .input[disabled]::-webkit-input-placeholder,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input[disabled]::-webkit-input-placeholder,fieldset[disabled] html.theme--catppuccin-latte .select select::-webkit-input-placeholder,fieldset[disabled] html.theme--catppuccin-latte .textarea::-webkit-input-placeholder,fieldset[disabled] html.theme--catppuccin-latte .input::-webkit-input-placeholder,fieldset[disabled] html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input::-webkit-input-placeholder{color:rgba(97,101,135,0.3)}html.theme--catppuccin-latte .select select[disabled]:-moz-placeholder,html.theme--catppuccin-latte .textarea[disabled]:-moz-placeholder,html.theme--catppuccin-latte .input[disabled]:-moz-placeholder,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input[disabled]:-moz-placeholder,fieldset[disabled] html.theme--catppuccin-latte .select select:-moz-placeholder,fieldset[disabled] html.theme--catppuccin-latte .textarea:-moz-placeholder,fieldset[disabled] html.theme--catppuccin-latte .input:-moz-placeholder,fieldset[disabled] html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input:-moz-placeholder{color:rgba(97,101,135,0.3)}html.theme--catppuccin-latte .select select[disabled]:-ms-input-placeholder,html.theme--catppuccin-latte .textarea[disabled]:-ms-input-placeholder,html.theme--catppuccin-latte .input[disabled]:-ms-input-placeholder,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input[disabled]:-ms-input-placeholder,fieldset[disabled] html.theme--catppuccin-latte .select select:-ms-input-placeholder,fieldset[disabled] html.theme--catppuccin-latte .textarea:-ms-input-placeholder,fieldset[disabled] html.theme--catppuccin-latte .input:-ms-input-placeholder,fieldset[disabled] html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input:-ms-input-placeholder{color:rgba(97,101,135,0.3)}html.theme--catppuccin-latte .textarea,html.theme--catppuccin-latte .input,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input{box-shadow:inset 0 0.0625em 0.125em rgba(10,10,10,0.05);max-width:100%;width:100%}html.theme--catppuccin-latte .textarea[readonly],html.theme--catppuccin-latte .input[readonly],html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input[readonly]{box-shadow:none}html.theme--catppuccin-latte .is-white.textarea,html.theme--catppuccin-latte .is-white.input,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-white{border-color:#fff}html.theme--catppuccin-latte .is-white.textarea:focus,html.theme--catppuccin-latte .is-white.input:focus,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-white:focus,html.theme--catppuccin-latte .is-white.is-focused.textarea,html.theme--catppuccin-latte .is-white.is-focused.input,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--catppuccin-latte .is-white.textarea:active,html.theme--catppuccin-latte .is-white.input:active,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-white:active,html.theme--catppuccin-latte .is-white.is-active.textarea,html.theme--catppuccin-latte .is-white.is-active.input,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(255,255,255,0.25)}html.theme--catppuccin-latte .is-black.textarea,html.theme--catppuccin-latte .is-black.input,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-black{border-color:#0a0a0a}html.theme--catppuccin-latte .is-black.textarea:focus,html.theme--catppuccin-latte .is-black.input:focus,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-black:focus,html.theme--catppuccin-latte .is-black.is-focused.textarea,html.theme--catppuccin-latte .is-black.is-focused.input,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--catppuccin-latte .is-black.textarea:active,html.theme--catppuccin-latte .is-black.input:active,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-black:active,html.theme--catppuccin-latte .is-black.is-active.textarea,html.theme--catppuccin-latte .is-black.is-active.input,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(10,10,10,0.25)}html.theme--catppuccin-latte .is-light.textarea,html.theme--catppuccin-latte .is-light.input,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-light{border-color:#f5f5f5}html.theme--catppuccin-latte .is-light.textarea:focus,html.theme--catppuccin-latte .is-light.input:focus,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-light:focus,html.theme--catppuccin-latte .is-light.is-focused.textarea,html.theme--catppuccin-latte .is-light.is-focused.input,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--catppuccin-latte .is-light.textarea:active,html.theme--catppuccin-latte .is-light.input:active,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-light:active,html.theme--catppuccin-latte .is-light.is-active.textarea,html.theme--catppuccin-latte .is-light.is-active.input,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(245,245,245,0.25)}html.theme--catppuccin-latte .is-dark.textarea,html.theme--catppuccin-latte .content kbd.textarea,html.theme--catppuccin-latte .is-dark.input,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-dark,html.theme--catppuccin-latte .content kbd.input{border-color:#ccd0da}html.theme--catppuccin-latte .is-dark.textarea:focus,html.theme--catppuccin-latte .content kbd.textarea:focus,html.theme--catppuccin-latte .is-dark.input:focus,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-dark:focus,html.theme--catppuccin-latte .content kbd.input:focus,html.theme--catppuccin-latte .is-dark.is-focused.textarea,html.theme--catppuccin-latte .content kbd.is-focused.textarea,html.theme--catppuccin-latte .is-dark.is-focused.input,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--catppuccin-latte .content kbd.is-focused.input,html.theme--catppuccin-latte #documenter .docs-sidebar .content form.docs-search>input.is-focused,html.theme--catppuccin-latte .is-dark.textarea:active,html.theme--catppuccin-latte .content kbd.textarea:active,html.theme--catppuccin-latte .is-dark.input:active,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-dark:active,html.theme--catppuccin-latte .content kbd.input:active,html.theme--catppuccin-latte .is-dark.is-active.textarea,html.theme--catppuccin-latte .content kbd.is-active.textarea,html.theme--catppuccin-latte .is-dark.is-active.input,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-active,html.theme--catppuccin-latte .content kbd.is-active.input,html.theme--catppuccin-latte #documenter .docs-sidebar .content form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(204,208,218,0.25)}html.theme--catppuccin-latte .is-primary.textarea,html.theme--catppuccin-latte .docstring>section>a.textarea.docs-sourcelink,html.theme--catppuccin-latte .is-primary.input,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-primary,html.theme--catppuccin-latte .docstring>section>a.input.docs-sourcelink{border-color:#1e66f5}html.theme--catppuccin-latte .is-primary.textarea:focus,html.theme--catppuccin-latte .docstring>section>a.textarea.docs-sourcelink:focus,html.theme--catppuccin-latte .is-primary.input:focus,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-primary:focus,html.theme--catppuccin-latte .docstring>section>a.input.docs-sourcelink:focus,html.theme--catppuccin-latte .is-primary.is-focused.textarea,html.theme--catppuccin-latte .docstring>section>a.is-focused.textarea.docs-sourcelink,html.theme--catppuccin-latte .is-primary.is-focused.input,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--catppuccin-latte .docstring>section>a.is-focused.input.docs-sourcelink,html.theme--catppuccin-latte .is-primary.textarea:active,html.theme--catppuccin-latte .docstring>section>a.textarea.docs-sourcelink:active,html.theme--catppuccin-latte .is-primary.input:active,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-primary:active,html.theme--catppuccin-latte .docstring>section>a.input.docs-sourcelink:active,html.theme--catppuccin-latte .is-primary.is-active.textarea,html.theme--catppuccin-latte .docstring>section>a.is-active.textarea.docs-sourcelink,html.theme--catppuccin-latte .is-primary.is-active.input,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-active,html.theme--catppuccin-latte .docstring>section>a.is-active.input.docs-sourcelink{box-shadow:0 0 0 0.125em rgba(30,102,245,0.25)}html.theme--catppuccin-latte .is-link.textarea,html.theme--catppuccin-latte .is-link.input,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-link{border-color:#1e66f5}html.theme--catppuccin-latte .is-link.textarea:focus,html.theme--catppuccin-latte .is-link.input:focus,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-link:focus,html.theme--catppuccin-latte .is-link.is-focused.textarea,html.theme--catppuccin-latte .is-link.is-focused.input,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--catppuccin-latte .is-link.textarea:active,html.theme--catppuccin-latte .is-link.input:active,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-link:active,html.theme--catppuccin-latte .is-link.is-active.textarea,html.theme--catppuccin-latte .is-link.is-active.input,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(30,102,245,0.25)}html.theme--catppuccin-latte .is-info.textarea,html.theme--catppuccin-latte .is-info.input,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-info{border-color:#179299}html.theme--catppuccin-latte .is-info.textarea:focus,html.theme--catppuccin-latte .is-info.input:focus,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-info:focus,html.theme--catppuccin-latte .is-info.is-focused.textarea,html.theme--catppuccin-latte .is-info.is-focused.input,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--catppuccin-latte .is-info.textarea:active,html.theme--catppuccin-latte .is-info.input:active,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-info:active,html.theme--catppuccin-latte .is-info.is-active.textarea,html.theme--catppuccin-latte .is-info.is-active.input,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(23,146,153,0.25)}html.theme--catppuccin-latte .is-success.textarea,html.theme--catppuccin-latte .is-success.input,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-success{border-color:#40a02b}html.theme--catppuccin-latte .is-success.textarea:focus,html.theme--catppuccin-latte .is-success.input:focus,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-success:focus,html.theme--catppuccin-latte .is-success.is-focused.textarea,html.theme--catppuccin-latte .is-success.is-focused.input,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--catppuccin-latte .is-success.textarea:active,html.theme--catppuccin-latte .is-success.input:active,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-success:active,html.theme--catppuccin-latte .is-success.is-active.textarea,html.theme--catppuccin-latte .is-success.is-active.input,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(64,160,43,0.25)}html.theme--catppuccin-latte .is-warning.textarea,html.theme--catppuccin-latte .is-warning.input,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-warning{border-color:#df8e1d}html.theme--catppuccin-latte .is-warning.textarea:focus,html.theme--catppuccin-latte .is-warning.input:focus,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-warning:focus,html.theme--catppuccin-latte .is-warning.is-focused.textarea,html.theme--catppuccin-latte .is-warning.is-focused.input,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--catppuccin-latte .is-warning.textarea:active,html.theme--catppuccin-latte .is-warning.input:active,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-warning:active,html.theme--catppuccin-latte .is-warning.is-active.textarea,html.theme--catppuccin-latte .is-warning.is-active.input,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(223,142,29,0.25)}html.theme--catppuccin-latte .is-danger.textarea,html.theme--catppuccin-latte .is-danger.input,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-danger{border-color:#d20f39}html.theme--catppuccin-latte .is-danger.textarea:focus,html.theme--catppuccin-latte .is-danger.input:focus,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-danger:focus,html.theme--catppuccin-latte .is-danger.is-focused.textarea,html.theme--catppuccin-latte .is-danger.is-focused.input,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--catppuccin-latte .is-danger.textarea:active,html.theme--catppuccin-latte .is-danger.input:active,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-danger:active,html.theme--catppuccin-latte .is-danger.is-active.textarea,html.theme--catppuccin-latte .is-danger.is-active.input,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(210,15,57,0.25)}html.theme--catppuccin-latte .is-small.textarea,html.theme--catppuccin-latte .is-small.input,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input{border-radius:3px;font-size:.75rem}html.theme--catppuccin-latte .is-medium.textarea,html.theme--catppuccin-latte .is-medium.input,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-medium{font-size:1.25rem}html.theme--catppuccin-latte .is-large.textarea,html.theme--catppuccin-latte .is-large.input,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-large{font-size:1.5rem}html.theme--catppuccin-latte .is-fullwidth.textarea,html.theme--catppuccin-latte .is-fullwidth.input,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-fullwidth{display:block;width:100%}html.theme--catppuccin-latte .is-inline.textarea,html.theme--catppuccin-latte .is-inline.input,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-inline{display:inline;width:auto}html.theme--catppuccin-latte .input.is-rounded,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input{border-radius:9999px;padding-left:calc(calc(0.75em - 1px) + 0.375em);padding-right:calc(calc(0.75em - 1px) + 0.375em)}html.theme--catppuccin-latte .input.is-static,html.theme--catppuccin-latte #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--catppuccin-latte .textarea{display:block;max-width:100%;min-width:100%;padding:calc(0.75em - 1px);resize:vertical}html.theme--catppuccin-latte .textarea:not([rows]){max-height:40em;min-height:8em}html.theme--catppuccin-latte .textarea[rows]{height:initial}html.theme--catppuccin-latte .textarea.has-fixed-size{resize:none}html.theme--catppuccin-latte .radio,html.theme--catppuccin-latte .checkbox{cursor:pointer;display:inline-block;line-height:1.25;position:relative}html.theme--catppuccin-latte .radio input,html.theme--catppuccin-latte .checkbox input{cursor:pointer}html.theme--catppuccin-latte .radio:hover,html.theme--catppuccin-latte .checkbox:hover{color:#04a5e5}html.theme--catppuccin-latte .radio[disabled],html.theme--catppuccin-latte .checkbox[disabled],fieldset[disabled] html.theme--catppuccin-latte .radio,fieldset[disabled] html.theme--catppuccin-latte .checkbox,html.theme--catppuccin-latte .radio input[disabled],html.theme--catppuccin-latte .checkbox input[disabled]{color:#616587;cursor:not-allowed}html.theme--catppuccin-latte .radio+.radio{margin-left:.5em}html.theme--catppuccin-latte .select{display:inline-block;max-width:100%;position:relative;vertical-align:top}html.theme--catppuccin-latte .select:not(.is-multiple){height:2.5em}html.theme--catppuccin-latte .select:not(.is-multiple):not(.is-loading)::after{border-color:#1e66f5;right:1.125em;z-index:4}html.theme--catppuccin-latte .select.is-rounded select,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.select select{border-radius:9999px;padding-left:1em}html.theme--catppuccin-latte .select select{cursor:pointer;display:block;font-size:1em;max-width:100%;outline:none}html.theme--catppuccin-latte .select select::-ms-expand{display:none}html.theme--catppuccin-latte .select select[disabled]:hover,fieldset[disabled] html.theme--catppuccin-latte .select select:hover{border-color:#e6e9ef}html.theme--catppuccin-latte .select select:not([multiple]){padding-right:2.5em}html.theme--catppuccin-latte .select select[multiple]{height:auto;padding:0}html.theme--catppuccin-latte .select select[multiple] option{padding:0.5em 1em}html.theme--catppuccin-latte .select:not(.is-multiple):not(.is-loading):hover::after{border-color:#04a5e5}html.theme--catppuccin-latte .select.is-white:not(:hover)::after{border-color:#fff}html.theme--catppuccin-latte .select.is-white select{border-color:#fff}html.theme--catppuccin-latte .select.is-white select:hover,html.theme--catppuccin-latte .select.is-white select.is-hovered{border-color:#f2f2f2}html.theme--catppuccin-latte .select.is-white select:focus,html.theme--catppuccin-latte .select.is-white select.is-focused,html.theme--catppuccin-latte .select.is-white select:active,html.theme--catppuccin-latte .select.is-white select.is-active{box-shadow:0 0 0 0.125em rgba(255,255,255,0.25)}html.theme--catppuccin-latte .select.is-black:not(:hover)::after{border-color:#0a0a0a}html.theme--catppuccin-latte .select.is-black select{border-color:#0a0a0a}html.theme--catppuccin-latte .select.is-black select:hover,html.theme--catppuccin-latte .select.is-black select.is-hovered{border-color:#000}html.theme--catppuccin-latte .select.is-black select:focus,html.theme--catppuccin-latte .select.is-black select.is-focused,html.theme--catppuccin-latte .select.is-black select:active,html.theme--catppuccin-latte .select.is-black select.is-active{box-shadow:0 0 0 0.125em rgba(10,10,10,0.25)}html.theme--catppuccin-latte .select.is-light:not(:hover)::after{border-color:#f5f5f5}html.theme--catppuccin-latte .select.is-light select{border-color:#f5f5f5}html.theme--catppuccin-latte .select.is-light select:hover,html.theme--catppuccin-latte .select.is-light select.is-hovered{border-color:#e8e8e8}html.theme--catppuccin-latte .select.is-light select:focus,html.theme--catppuccin-latte .select.is-light select.is-focused,html.theme--catppuccin-latte .select.is-light select:active,html.theme--catppuccin-latte .select.is-light select.is-active{box-shadow:0 0 0 0.125em rgba(245,245,245,0.25)}html.theme--catppuccin-latte .select.is-dark:not(:hover)::after,html.theme--catppuccin-latte .content kbd.select:not(:hover)::after{border-color:#ccd0da}html.theme--catppuccin-latte .select.is-dark select,html.theme--catppuccin-latte .content kbd.select select{border-color:#ccd0da}html.theme--catppuccin-latte .select.is-dark select:hover,html.theme--catppuccin-latte .content kbd.select select:hover,html.theme--catppuccin-latte .select.is-dark select.is-hovered,html.theme--catppuccin-latte .content kbd.select select.is-hovered{border-color:#bdc2cf}html.theme--catppuccin-latte .select.is-dark select:focus,html.theme--catppuccin-latte .content kbd.select select:focus,html.theme--catppuccin-latte .select.is-dark select.is-focused,html.theme--catppuccin-latte .content kbd.select select.is-focused,html.theme--catppuccin-latte .select.is-dark select:active,html.theme--catppuccin-latte .content kbd.select select:active,html.theme--catppuccin-latte .select.is-dark select.is-active,html.theme--catppuccin-latte .content kbd.select select.is-active{box-shadow:0 0 0 0.125em rgba(204,208,218,0.25)}html.theme--catppuccin-latte .select.is-primary:not(:hover)::after,html.theme--catppuccin-latte .docstring>section>a.select.docs-sourcelink:not(:hover)::after{border-color:#1e66f5}html.theme--catppuccin-latte .select.is-primary select,html.theme--catppuccin-latte .docstring>section>a.select.docs-sourcelink select{border-color:#1e66f5}html.theme--catppuccin-latte .select.is-primary select:hover,html.theme--catppuccin-latte .docstring>section>a.select.docs-sourcelink select:hover,html.theme--catppuccin-latte .select.is-primary select.is-hovered,html.theme--catppuccin-latte .docstring>section>a.select.docs-sourcelink select.is-hovered{border-color:#0b57ef}html.theme--catppuccin-latte .select.is-primary select:focus,html.theme--catppuccin-latte .docstring>section>a.select.docs-sourcelink select:focus,html.theme--catppuccin-latte .select.is-primary select.is-focused,html.theme--catppuccin-latte .docstring>section>a.select.docs-sourcelink select.is-focused,html.theme--catppuccin-latte .select.is-primary select:active,html.theme--catppuccin-latte .docstring>section>a.select.docs-sourcelink select:active,html.theme--catppuccin-latte .select.is-primary select.is-active,html.theme--catppuccin-latte .docstring>section>a.select.docs-sourcelink select.is-active{box-shadow:0 0 0 0.125em rgba(30,102,245,0.25)}html.theme--catppuccin-latte .select.is-link:not(:hover)::after{border-color:#1e66f5}html.theme--catppuccin-latte .select.is-link select{border-color:#1e66f5}html.theme--catppuccin-latte .select.is-link select:hover,html.theme--catppuccin-latte .select.is-link select.is-hovered{border-color:#0b57ef}html.theme--catppuccin-latte .select.is-link select:focus,html.theme--catppuccin-latte .select.is-link select.is-focused,html.theme--catppuccin-latte .select.is-link select:active,html.theme--catppuccin-latte .select.is-link select.is-active{box-shadow:0 0 0 0.125em rgba(30,102,245,0.25)}html.theme--catppuccin-latte .select.is-info:not(:hover)::after{border-color:#179299}html.theme--catppuccin-latte .select.is-info select{border-color:#179299}html.theme--catppuccin-latte .select.is-info select:hover,html.theme--catppuccin-latte .select.is-info select.is-hovered{border-color:#147d83}html.theme--catppuccin-latte .select.is-info select:focus,html.theme--catppuccin-latte .select.is-info select.is-focused,html.theme--catppuccin-latte .select.is-info select:active,html.theme--catppuccin-latte .select.is-info select.is-active{box-shadow:0 0 0 0.125em rgba(23,146,153,0.25)}html.theme--catppuccin-latte .select.is-success:not(:hover)::after{border-color:#40a02b}html.theme--catppuccin-latte .select.is-success select{border-color:#40a02b}html.theme--catppuccin-latte .select.is-success select:hover,html.theme--catppuccin-latte .select.is-success select.is-hovered{border-color:#388c26}html.theme--catppuccin-latte .select.is-success select:focus,html.theme--catppuccin-latte .select.is-success select.is-focused,html.theme--catppuccin-latte .select.is-success select:active,html.theme--catppuccin-latte .select.is-success select.is-active{box-shadow:0 0 0 0.125em rgba(64,160,43,0.25)}html.theme--catppuccin-latte .select.is-warning:not(:hover)::after{border-color:#df8e1d}html.theme--catppuccin-latte .select.is-warning select{border-color:#df8e1d}html.theme--catppuccin-latte .select.is-warning select:hover,html.theme--catppuccin-latte .select.is-warning select.is-hovered{border-color:#c8801a}html.theme--catppuccin-latte .select.is-warning select:focus,html.theme--catppuccin-latte .select.is-warning select.is-focused,html.theme--catppuccin-latte .select.is-warning select:active,html.theme--catppuccin-latte .select.is-warning select.is-active{box-shadow:0 0 0 0.125em rgba(223,142,29,0.25)}html.theme--catppuccin-latte .select.is-danger:not(:hover)::after{border-color:#d20f39}html.theme--catppuccin-latte .select.is-danger select{border-color:#d20f39}html.theme--catppuccin-latte .select.is-danger select:hover,html.theme--catppuccin-latte .select.is-danger select.is-hovered{border-color:#ba0d33}html.theme--catppuccin-latte .select.is-danger select:focus,html.theme--catppuccin-latte .select.is-danger select.is-focused,html.theme--catppuccin-latte .select.is-danger select:active,html.theme--catppuccin-latte .select.is-danger select.is-active{box-shadow:0 0 0 0.125em rgba(210,15,57,0.25)}html.theme--catppuccin-latte .select.is-small,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.select{border-radius:3px;font-size:.75rem}html.theme--catppuccin-latte .select.is-medium{font-size:1.25rem}html.theme--catppuccin-latte .select.is-large{font-size:1.5rem}html.theme--catppuccin-latte .select.is-disabled::after{border-color:#616587 !important;opacity:0.5}html.theme--catppuccin-latte .select.is-fullwidth{width:100%}html.theme--catppuccin-latte .select.is-fullwidth select{width:100%}html.theme--catppuccin-latte .select.is-loading::after{margin-top:0;position:absolute;right:.625em;top:0.625em;transform:none}html.theme--catppuccin-latte .select.is-loading.is-small:after,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-loading:after{font-size:.75rem}html.theme--catppuccin-latte .select.is-loading.is-medium:after{font-size:1.25rem}html.theme--catppuccin-latte .select.is-loading.is-large:after{font-size:1.5rem}html.theme--catppuccin-latte .file{align-items:stretch;display:flex;justify-content:flex-start;position:relative}html.theme--catppuccin-latte .file.is-white .file-cta{background-color:#fff;border-color:transparent;color:#0a0a0a}html.theme--catppuccin-latte .file.is-white:hover .file-cta,html.theme--catppuccin-latte .file.is-white.is-hovered .file-cta{background-color:#f9f9f9;border-color:transparent;color:#0a0a0a}html.theme--catppuccin-latte .file.is-white:focus .file-cta,html.theme--catppuccin-latte .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--catppuccin-latte .file.is-white:active .file-cta,html.theme--catppuccin-latte .file.is-white.is-active .file-cta{background-color:#f2f2f2;border-color:transparent;color:#0a0a0a}html.theme--catppuccin-latte .file.is-black .file-cta{background-color:#0a0a0a;border-color:transparent;color:#fff}html.theme--catppuccin-latte .file.is-black:hover .file-cta,html.theme--catppuccin-latte .file.is-black.is-hovered .file-cta{background-color:#040404;border-color:transparent;color:#fff}html.theme--catppuccin-latte .file.is-black:focus .file-cta,html.theme--catppuccin-latte .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--catppuccin-latte .file.is-black:active .file-cta,html.theme--catppuccin-latte .file.is-black.is-active .file-cta{background-color:#000;border-color:transparent;color:#fff}html.theme--catppuccin-latte .file.is-light .file-cta{background-color:#f5f5f5;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-latte .file.is-light:hover .file-cta,html.theme--catppuccin-latte .file.is-light.is-hovered .file-cta{background-color:#eee;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-latte .file.is-light:focus .file-cta,html.theme--catppuccin-latte .file.is-light.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(245,245,245,0.25);color:rgba(0,0,0,0.7)}html.theme--catppuccin-latte .file.is-light:active .file-cta,html.theme--catppuccin-latte .file.is-light.is-active .file-cta{background-color:#e8e8e8;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-latte .file.is-dark .file-cta,html.theme--catppuccin-latte .content kbd.file .file-cta{background-color:#ccd0da;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-latte .file.is-dark:hover .file-cta,html.theme--catppuccin-latte .content kbd.file:hover .file-cta,html.theme--catppuccin-latte .file.is-dark.is-hovered .file-cta,html.theme--catppuccin-latte .content kbd.file.is-hovered .file-cta{background-color:#c5c9d5;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-latte .file.is-dark:focus .file-cta,html.theme--catppuccin-latte .content kbd.file:focus .file-cta,html.theme--catppuccin-latte .file.is-dark.is-focused .file-cta,html.theme--catppuccin-latte .content kbd.file.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(204,208,218,0.25);color:rgba(0,0,0,0.7)}html.theme--catppuccin-latte .file.is-dark:active .file-cta,html.theme--catppuccin-latte .content kbd.file:active .file-cta,html.theme--catppuccin-latte .file.is-dark.is-active .file-cta,html.theme--catppuccin-latte .content kbd.file.is-active .file-cta{background-color:#bdc2cf;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-latte .file.is-primary .file-cta,html.theme--catppuccin-latte .docstring>section>a.file.docs-sourcelink .file-cta{background-color:#1e66f5;border-color:transparent;color:#fff}html.theme--catppuccin-latte .file.is-primary:hover .file-cta,html.theme--catppuccin-latte .docstring>section>a.file.docs-sourcelink:hover .file-cta,html.theme--catppuccin-latte .file.is-primary.is-hovered .file-cta,html.theme--catppuccin-latte .docstring>section>a.file.is-hovered.docs-sourcelink .file-cta{background-color:#125ef4;border-color:transparent;color:#fff}html.theme--catppuccin-latte .file.is-primary:focus .file-cta,html.theme--catppuccin-latte .docstring>section>a.file.docs-sourcelink:focus .file-cta,html.theme--catppuccin-latte .file.is-primary.is-focused .file-cta,html.theme--catppuccin-latte .docstring>section>a.file.is-focused.docs-sourcelink .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(30,102,245,0.25);color:#fff}html.theme--catppuccin-latte .file.is-primary:active .file-cta,html.theme--catppuccin-latte .docstring>section>a.file.docs-sourcelink:active .file-cta,html.theme--catppuccin-latte .file.is-primary.is-active .file-cta,html.theme--catppuccin-latte .docstring>section>a.file.is-active.docs-sourcelink .file-cta{background-color:#0b57ef;border-color:transparent;color:#fff}html.theme--catppuccin-latte .file.is-link .file-cta{background-color:#1e66f5;border-color:transparent;color:#fff}html.theme--catppuccin-latte .file.is-link:hover .file-cta,html.theme--catppuccin-latte .file.is-link.is-hovered .file-cta{background-color:#125ef4;border-color:transparent;color:#fff}html.theme--catppuccin-latte .file.is-link:focus .file-cta,html.theme--catppuccin-latte .file.is-link.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(30,102,245,0.25);color:#fff}html.theme--catppuccin-latte .file.is-link:active .file-cta,html.theme--catppuccin-latte .file.is-link.is-active .file-cta{background-color:#0b57ef;border-color:transparent;color:#fff}html.theme--catppuccin-latte .file.is-info .file-cta{background-color:#179299;border-color:transparent;color:#fff}html.theme--catppuccin-latte .file.is-info:hover .file-cta,html.theme--catppuccin-latte .file.is-info.is-hovered .file-cta{background-color:#15878e;border-color:transparent;color:#fff}html.theme--catppuccin-latte .file.is-info:focus .file-cta,html.theme--catppuccin-latte .file.is-info.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(23,146,153,0.25);color:#fff}html.theme--catppuccin-latte .file.is-info:active .file-cta,html.theme--catppuccin-latte .file.is-info.is-active .file-cta{background-color:#147d83;border-color:transparent;color:#fff}html.theme--catppuccin-latte .file.is-success .file-cta{background-color:#40a02b;border-color:transparent;color:#fff}html.theme--catppuccin-latte .file.is-success:hover .file-cta,html.theme--catppuccin-latte .file.is-success.is-hovered .file-cta{background-color:#3c9628;border-color:transparent;color:#fff}html.theme--catppuccin-latte .file.is-success:focus .file-cta,html.theme--catppuccin-latte .file.is-success.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(64,160,43,0.25);color:#fff}html.theme--catppuccin-latte .file.is-success:active .file-cta,html.theme--catppuccin-latte .file.is-success.is-active .file-cta{background-color:#388c26;border-color:transparent;color:#fff}html.theme--catppuccin-latte .file.is-warning .file-cta{background-color:#df8e1d;border-color:transparent;color:#fff}html.theme--catppuccin-latte .file.is-warning:hover .file-cta,html.theme--catppuccin-latte .file.is-warning.is-hovered .file-cta{background-color:#d4871c;border-color:transparent;color:#fff}html.theme--catppuccin-latte .file.is-warning:focus .file-cta,html.theme--catppuccin-latte .file.is-warning.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(223,142,29,0.25);color:#fff}html.theme--catppuccin-latte .file.is-warning:active .file-cta,html.theme--catppuccin-latte .file.is-warning.is-active .file-cta{background-color:#c8801a;border-color:transparent;color:#fff}html.theme--catppuccin-latte .file.is-danger .file-cta{background-color:#d20f39;border-color:transparent;color:#fff}html.theme--catppuccin-latte .file.is-danger:hover .file-cta,html.theme--catppuccin-latte .file.is-danger.is-hovered .file-cta{background-color:#c60e36;border-color:transparent;color:#fff}html.theme--catppuccin-latte .file.is-danger:focus .file-cta,html.theme--catppuccin-latte .file.is-danger.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(210,15,57,0.25);color:#fff}html.theme--catppuccin-latte .file.is-danger:active .file-cta,html.theme--catppuccin-latte .file.is-danger.is-active .file-cta{background-color:#ba0d33;border-color:transparent;color:#fff}html.theme--catppuccin-latte .file.is-small,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.file{font-size:.75rem}html.theme--catppuccin-latte .file.is-normal{font-size:1rem}html.theme--catppuccin-latte .file.is-medium{font-size:1.25rem}html.theme--catppuccin-latte .file.is-medium .file-icon .fa{font-size:21px}html.theme--catppuccin-latte .file.is-large{font-size:1.5rem}html.theme--catppuccin-latte .file.is-large .file-icon .fa{font-size:28px}html.theme--catppuccin-latte .file.has-name .file-cta{border-bottom-right-radius:0;border-top-right-radius:0}html.theme--catppuccin-latte .file.has-name .file-name{border-bottom-left-radius:0;border-top-left-radius:0}html.theme--catppuccin-latte .file.has-name.is-empty .file-cta{border-radius:.4em}html.theme--catppuccin-latte .file.has-name.is-empty .file-name{display:none}html.theme--catppuccin-latte .file.is-boxed .file-label{flex-direction:column}html.theme--catppuccin-latte .file.is-boxed .file-cta{flex-direction:column;height:auto;padding:1em 3em}html.theme--catppuccin-latte .file.is-boxed .file-name{border-width:0 1px 1px}html.theme--catppuccin-latte .file.is-boxed .file-icon{height:1.5em;width:1.5em}html.theme--catppuccin-latte .file.is-boxed .file-icon .fa{font-size:21px}html.theme--catppuccin-latte .file.is-boxed.is-small .file-icon .fa,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-boxed .file-icon .fa{font-size:14px}html.theme--catppuccin-latte .file.is-boxed.is-medium .file-icon .fa{font-size:28px}html.theme--catppuccin-latte .file.is-boxed.is-large .file-icon .fa{font-size:35px}html.theme--catppuccin-latte .file.is-boxed.has-name .file-cta{border-radius:.4em .4em 0 0}html.theme--catppuccin-latte .file.is-boxed.has-name .file-name{border-radius:0 0 .4em .4em;border-width:0 1px 1px}html.theme--catppuccin-latte .file.is-centered{justify-content:center}html.theme--catppuccin-latte .file.is-fullwidth .file-label{width:100%}html.theme--catppuccin-latte .file.is-fullwidth .file-name{flex-grow:1;max-width:none}html.theme--catppuccin-latte .file.is-right{justify-content:flex-end}html.theme--catppuccin-latte .file.is-right .file-cta{border-radius:0 .4em .4em 0}html.theme--catppuccin-latte .file.is-right .file-name{border-radius:.4em 0 0 .4em;border-width:1px 0 1px 1px;order:-1}html.theme--catppuccin-latte .file-label{align-items:stretch;display:flex;cursor:pointer;justify-content:flex-start;overflow:hidden;position:relative}html.theme--catppuccin-latte .file-label:hover .file-cta{background-color:#c5c9d5;color:#41445a}html.theme--catppuccin-latte .file-label:hover .file-name{border-color:#a5a9b8}html.theme--catppuccin-latte .file-label:active .file-cta{background-color:#bdc2cf;color:#41445a}html.theme--catppuccin-latte .file-label:active .file-name{border-color:#9ea2b3}html.theme--catppuccin-latte .file-input{height:100%;left:0;opacity:0;outline:none;position:absolute;top:0;width:100%}html.theme--catppuccin-latte .file-cta,html.theme--catppuccin-latte .file-name{border-color:#acb0be;border-radius:.4em;font-size:1em;padding-left:1em;padding-right:1em;white-space:nowrap}html.theme--catppuccin-latte .file-cta{background-color:#ccd0da;color:#4c4f69}html.theme--catppuccin-latte .file-name{border-color:#acb0be;border-style:solid;border-width:1px 1px 1px 0;display:block;max-width:16em;overflow:hidden;text-align:inherit;text-overflow:ellipsis}html.theme--catppuccin-latte .file-icon{align-items:center;display:flex;height:1em;justify-content:center;margin-right:.5em;width:1em}html.theme--catppuccin-latte .file-icon .fa{font-size:14px}html.theme--catppuccin-latte .label{color:#41445a;display:block;font-size:1rem;font-weight:700}html.theme--catppuccin-latte .label:not(:last-child){margin-bottom:0.5em}html.theme--catppuccin-latte .label.is-small,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.label{font-size:.75rem}html.theme--catppuccin-latte .label.is-medium{font-size:1.25rem}html.theme--catppuccin-latte .label.is-large{font-size:1.5rem}html.theme--catppuccin-latte .help{display:block;font-size:.75rem;margin-top:0.25rem}html.theme--catppuccin-latte .help.is-white{color:#fff}html.theme--catppuccin-latte .help.is-black{color:#0a0a0a}html.theme--catppuccin-latte .help.is-light{color:#f5f5f5}html.theme--catppuccin-latte .help.is-dark,html.theme--catppuccin-latte .content kbd.help{color:#ccd0da}html.theme--catppuccin-latte .help.is-primary,html.theme--catppuccin-latte .docstring>section>a.help.docs-sourcelink{color:#1e66f5}html.theme--catppuccin-latte .help.is-link{color:#1e66f5}html.theme--catppuccin-latte .help.is-info{color:#179299}html.theme--catppuccin-latte .help.is-success{color:#40a02b}html.theme--catppuccin-latte .help.is-warning{color:#df8e1d}html.theme--catppuccin-latte .help.is-danger{color:#d20f39}html.theme--catppuccin-latte .field:not(:last-child){margin-bottom:0.75rem}html.theme--catppuccin-latte .field.has-addons{display:flex;justify-content:flex-start}html.theme--catppuccin-latte .field.has-addons .control:not(:last-child){margin-right:-1px}html.theme--catppuccin-latte .field.has-addons .control:not(:first-child):not(:last-child) .button,html.theme--catppuccin-latte .field.has-addons .control:not(:first-child):not(:last-child) .input,html.theme--catppuccin-latte .field.has-addons .control:not(:first-child):not(:last-child) #documenter .docs-sidebar form.docs-search>input,html.theme--catppuccin-latte #documenter .docs-sidebar .field.has-addons .control:not(:first-child):not(:last-child) form.docs-search>input,html.theme--catppuccin-latte .field.has-addons .control:not(:first-child):not(:last-child) .select select{border-radius:0}html.theme--catppuccin-latte .field.has-addons .control:first-child:not(:only-child) .button,html.theme--catppuccin-latte .field.has-addons .control:first-child:not(:only-child) .input,html.theme--catppuccin-latte .field.has-addons .control:first-child:not(:only-child) #documenter .docs-sidebar form.docs-search>input,html.theme--catppuccin-latte #documenter .docs-sidebar .field.has-addons .control:first-child:not(:only-child) form.docs-search>input,html.theme--catppuccin-latte .field.has-addons .control:first-child:not(:only-child) .select select{border-bottom-right-radius:0;border-top-right-radius:0}html.theme--catppuccin-latte .field.has-addons .control:last-child:not(:only-child) .button,html.theme--catppuccin-latte .field.has-addons .control:last-child:not(:only-child) .input,html.theme--catppuccin-latte .field.has-addons .control:last-child:not(:only-child) #documenter .docs-sidebar form.docs-search>input,html.theme--catppuccin-latte #documenter .docs-sidebar .field.has-addons .control:last-child:not(:only-child) form.docs-search>input,html.theme--catppuccin-latte .field.has-addons .control:last-child:not(:only-child) .select select{border-bottom-left-radius:0;border-top-left-radius:0}html.theme--catppuccin-latte .field.has-addons .control .button:not([disabled]):hover,html.theme--catppuccin-latte .field.has-addons .control .button.is-hovered:not([disabled]),html.theme--catppuccin-latte .field.has-addons .control .input:not([disabled]):hover,html.theme--catppuccin-latte .field.has-addons .control #documenter .docs-sidebar form.docs-search>input:not([disabled]):hover,html.theme--catppuccin-latte #documenter .docs-sidebar .field.has-addons .control form.docs-search>input:not([disabled]):hover,html.theme--catppuccin-latte .field.has-addons .control .input.is-hovered:not([disabled]),html.theme--catppuccin-latte .field.has-addons .control #documenter .docs-sidebar form.docs-search>input.is-hovered:not([disabled]),html.theme--catppuccin-latte #documenter .docs-sidebar .field.has-addons .control form.docs-search>input.is-hovered:not([disabled]),html.theme--catppuccin-latte .field.has-addons .control .select select:not([disabled]):hover,html.theme--catppuccin-latte .field.has-addons .control .select select.is-hovered:not([disabled]){z-index:2}html.theme--catppuccin-latte .field.has-addons .control .button:not([disabled]):focus,html.theme--catppuccin-latte .field.has-addons .control .button.is-focused:not([disabled]),html.theme--catppuccin-latte .field.has-addons .control .button:not([disabled]):active,html.theme--catppuccin-latte .field.has-addons .control .button.is-active:not([disabled]),html.theme--catppuccin-latte .field.has-addons .control .input:not([disabled]):focus,html.theme--catppuccin-latte .field.has-addons .control #documenter .docs-sidebar form.docs-search>input:not([disabled]):focus,html.theme--catppuccin-latte #documenter .docs-sidebar .field.has-addons .control form.docs-search>input:not([disabled]):focus,html.theme--catppuccin-latte .field.has-addons .control .input.is-focused:not([disabled]),html.theme--catppuccin-latte .field.has-addons .control #documenter .docs-sidebar form.docs-search>input.is-focused:not([disabled]),html.theme--catppuccin-latte #documenter .docs-sidebar .field.has-addons .control form.docs-search>input.is-focused:not([disabled]),html.theme--catppuccin-latte .field.has-addons .control .input:not([disabled]):active,html.theme--catppuccin-latte .field.has-addons .control #documenter .docs-sidebar form.docs-search>input:not([disabled]):active,html.theme--catppuccin-latte #documenter .docs-sidebar .field.has-addons .control form.docs-search>input:not([disabled]):active,html.theme--catppuccin-latte .field.has-addons .control .input.is-active:not([disabled]),html.theme--catppuccin-latte .field.has-addons .control #documenter .docs-sidebar form.docs-search>input.is-active:not([disabled]),html.theme--catppuccin-latte #documenter .docs-sidebar .field.has-addons .control form.docs-search>input.is-active:not([disabled]),html.theme--catppuccin-latte .field.has-addons .control .select select:not([disabled]):focus,html.theme--catppuccin-latte .field.has-addons .control .select select.is-focused:not([disabled]),html.theme--catppuccin-latte .field.has-addons .control .select select:not([disabled]):active,html.theme--catppuccin-latte .field.has-addons .control .select select.is-active:not([disabled]){z-index:3}html.theme--catppuccin-latte .field.has-addons .control .button:not([disabled]):focus:hover,html.theme--catppuccin-latte .field.has-addons .control .button.is-focused:not([disabled]):hover,html.theme--catppuccin-latte .field.has-addons .control .button:not([disabled]):active:hover,html.theme--catppuccin-latte .field.has-addons .control .button.is-active:not([disabled]):hover,html.theme--catppuccin-latte .field.has-addons .control .input:not([disabled]):focus:hover,html.theme--catppuccin-latte .field.has-addons .control #documenter .docs-sidebar form.docs-search>input:not([disabled]):focus:hover,html.theme--catppuccin-latte #documenter .docs-sidebar .field.has-addons .control form.docs-search>input:not([disabled]):focus:hover,html.theme--catppuccin-latte .field.has-addons .control .input.is-focused:not([disabled]):hover,html.theme--catppuccin-latte .field.has-addons .control #documenter .docs-sidebar form.docs-search>input.is-focused:not([disabled]):hover,html.theme--catppuccin-latte #documenter .docs-sidebar .field.has-addons .control form.docs-search>input.is-focused:not([disabled]):hover,html.theme--catppuccin-latte .field.has-addons .control .input:not([disabled]):active:hover,html.theme--catppuccin-latte .field.has-addons .control #documenter .docs-sidebar form.docs-search>input:not([disabled]):active:hover,html.theme--catppuccin-latte #documenter .docs-sidebar .field.has-addons .control form.docs-search>input:not([disabled]):active:hover,html.theme--catppuccin-latte .field.has-addons .control .input.is-active:not([disabled]):hover,html.theme--catppuccin-latte .field.has-addons .control #documenter .docs-sidebar form.docs-search>input.is-active:not([disabled]):hover,html.theme--catppuccin-latte #documenter .docs-sidebar .field.has-addons .control form.docs-search>input.is-active:not([disabled]):hover,html.theme--catppuccin-latte .field.has-addons .control .select select:not([disabled]):focus:hover,html.theme--catppuccin-latte .field.has-addons .control .select select.is-focused:not([disabled]):hover,html.theme--catppuccin-latte .field.has-addons .control .select select:not([disabled]):active:hover,html.theme--catppuccin-latte .field.has-addons .control .select select.is-active:not([disabled]):hover{z-index:4}html.theme--catppuccin-latte .field.has-addons .control.is-expanded{flex-grow:1;flex-shrink:1}html.theme--catppuccin-latte .field.has-addons.has-addons-centered{justify-content:center}html.theme--catppuccin-latte .field.has-addons.has-addons-right{justify-content:flex-end}html.theme--catppuccin-latte .field.has-addons.has-addons-fullwidth .control{flex-grow:1;flex-shrink:0}html.theme--catppuccin-latte .field.is-grouped{display:flex;justify-content:flex-start}html.theme--catppuccin-latte .field.is-grouped>.control{flex-shrink:0}html.theme--catppuccin-latte .field.is-grouped>.control:not(:last-child){margin-bottom:0;margin-right:.75rem}html.theme--catppuccin-latte .field.is-grouped>.control.is-expanded{flex-grow:1;flex-shrink:1}html.theme--catppuccin-latte .field.is-grouped.is-grouped-centered{justify-content:center}html.theme--catppuccin-latte .field.is-grouped.is-grouped-right{justify-content:flex-end}html.theme--catppuccin-latte .field.is-grouped.is-grouped-multiline{flex-wrap:wrap}html.theme--catppuccin-latte .field.is-grouped.is-grouped-multiline>.control:last-child,html.theme--catppuccin-latte .field.is-grouped.is-grouped-multiline>.control:not(:last-child){margin-bottom:0.75rem}html.theme--catppuccin-latte .field.is-grouped.is-grouped-multiline:last-child{margin-bottom:-0.75rem}html.theme--catppuccin-latte .field.is-grouped.is-grouped-multiline:not(:last-child){margin-bottom:0}@media screen and (min-width: 769px),print{html.theme--catppuccin-latte .field.is-horizontal{display:flex}}html.theme--catppuccin-latte .field-label .label{font-size:inherit}@media screen and (max-width: 768px){html.theme--catppuccin-latte .field-label{margin-bottom:0.5rem}}@media screen and (min-width: 769px),print{html.theme--catppuccin-latte .field-label{flex-basis:0;flex-grow:1;flex-shrink:0;margin-right:1.5rem;text-align:right}html.theme--catppuccin-latte .field-label.is-small,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.field-label{font-size:.75rem;padding-top:0.375em}html.theme--catppuccin-latte .field-label.is-normal{padding-top:0.375em}html.theme--catppuccin-latte .field-label.is-medium{font-size:1.25rem;padding-top:0.375em}html.theme--catppuccin-latte .field-label.is-large{font-size:1.5rem;padding-top:0.375em}}html.theme--catppuccin-latte .field-body .field .field{margin-bottom:0}@media screen and (min-width: 769px),print{html.theme--catppuccin-latte .field-body{display:flex;flex-basis:0;flex-grow:5;flex-shrink:1}html.theme--catppuccin-latte .field-body .field{margin-bottom:0}html.theme--catppuccin-latte .field-body>.field{flex-shrink:1}html.theme--catppuccin-latte .field-body>.field:not(.is-narrow){flex-grow:1}html.theme--catppuccin-latte .field-body>.field:not(:last-child){margin-right:.75rem}}html.theme--catppuccin-latte .control{box-sizing:border-box;clear:both;font-size:1rem;position:relative;text-align:inherit}html.theme--catppuccin-latte .control.has-icons-left .input:focus~.icon,html.theme--catppuccin-latte .control.has-icons-left #documenter .docs-sidebar form.docs-search>input:focus~.icon,html.theme--catppuccin-latte #documenter .docs-sidebar .control.has-icons-left form.docs-search>input:focus~.icon,html.theme--catppuccin-latte .control.has-icons-left .select:focus~.icon,html.theme--catppuccin-latte .control.has-icons-right .input:focus~.icon,html.theme--catppuccin-latte .control.has-icons-right #documenter .docs-sidebar form.docs-search>input:focus~.icon,html.theme--catppuccin-latte #documenter .docs-sidebar .control.has-icons-right form.docs-search>input:focus~.icon,html.theme--catppuccin-latte .control.has-icons-right .select:focus~.icon{color:#ccd0da}html.theme--catppuccin-latte .control.has-icons-left .input.is-small~.icon,html.theme--catppuccin-latte .control.has-icons-left #documenter .docs-sidebar form.docs-search>input~.icon,html.theme--catppuccin-latte #documenter .docs-sidebar .control.has-icons-left form.docs-search>input~.icon,html.theme--catppuccin-latte .control.has-icons-left .select.is-small~.icon,html.theme--catppuccin-latte .control.has-icons-right .input.is-small~.icon,html.theme--catppuccin-latte .control.has-icons-right #documenter .docs-sidebar form.docs-search>input~.icon,html.theme--catppuccin-latte #documenter .docs-sidebar .control.has-icons-right form.docs-search>input~.icon,html.theme--catppuccin-latte .control.has-icons-right .select.is-small~.icon{font-size:.75rem}html.theme--catppuccin-latte .control.has-icons-left .input.is-medium~.icon,html.theme--catppuccin-latte .control.has-icons-left #documenter .docs-sidebar form.docs-search>input.is-medium~.icon,html.theme--catppuccin-latte #documenter .docs-sidebar .control.has-icons-left form.docs-search>input.is-medium~.icon,html.theme--catppuccin-latte .control.has-icons-left .select.is-medium~.icon,html.theme--catppuccin-latte .control.has-icons-right .input.is-medium~.icon,html.theme--catppuccin-latte .control.has-icons-right #documenter .docs-sidebar form.docs-search>input.is-medium~.icon,html.theme--catppuccin-latte #documenter .docs-sidebar .control.has-icons-right form.docs-search>input.is-medium~.icon,html.theme--catppuccin-latte .control.has-icons-right .select.is-medium~.icon{font-size:1.25rem}html.theme--catppuccin-latte .control.has-icons-left .input.is-large~.icon,html.theme--catppuccin-latte .control.has-icons-left #documenter .docs-sidebar form.docs-search>input.is-large~.icon,html.theme--catppuccin-latte #documenter .docs-sidebar .control.has-icons-left form.docs-search>input.is-large~.icon,html.theme--catppuccin-latte .control.has-icons-left .select.is-large~.icon,html.theme--catppuccin-latte .control.has-icons-right .input.is-large~.icon,html.theme--catppuccin-latte .control.has-icons-right #documenter .docs-sidebar form.docs-search>input.is-large~.icon,html.theme--catppuccin-latte #documenter .docs-sidebar .control.has-icons-right form.docs-search>input.is-large~.icon,html.theme--catppuccin-latte .control.has-icons-right .select.is-large~.icon{font-size:1.5rem}html.theme--catppuccin-latte .control.has-icons-left .icon,html.theme--catppuccin-latte .control.has-icons-right .icon{color:#acb0be;height:2.5em;pointer-events:none;position:absolute;top:0;width:2.5em;z-index:4}html.theme--catppuccin-latte .control.has-icons-left .input,html.theme--catppuccin-latte .control.has-icons-left #documenter .docs-sidebar form.docs-search>input,html.theme--catppuccin-latte #documenter .docs-sidebar .control.has-icons-left form.docs-search>input,html.theme--catppuccin-latte .control.has-icons-left .select select{padding-left:2.5em}html.theme--catppuccin-latte .control.has-icons-left .icon.is-left{left:0}html.theme--catppuccin-latte .control.has-icons-right .input,html.theme--catppuccin-latte .control.has-icons-right #documenter .docs-sidebar form.docs-search>input,html.theme--catppuccin-latte #documenter .docs-sidebar .control.has-icons-right form.docs-search>input,html.theme--catppuccin-latte .control.has-icons-right .select select{padding-right:2.5em}html.theme--catppuccin-latte .control.has-icons-right .icon.is-right{right:0}html.theme--catppuccin-latte .control.is-loading::after{position:absolute !important;right:.625em;top:0.625em;z-index:4}html.theme--catppuccin-latte .control.is-loading.is-small:after,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-loading:after{font-size:.75rem}html.theme--catppuccin-latte .control.is-loading.is-medium:after{font-size:1.25rem}html.theme--catppuccin-latte .control.is-loading.is-large:after{font-size:1.5rem}html.theme--catppuccin-latte .breadcrumb{font-size:1rem;white-space:nowrap}html.theme--catppuccin-latte .breadcrumb a{align-items:center;color:#1e66f5;display:flex;justify-content:center;padding:0 .75em}html.theme--catppuccin-latte .breadcrumb a:hover{color:#04a5e5}html.theme--catppuccin-latte .breadcrumb li{align-items:center;display:flex}html.theme--catppuccin-latte .breadcrumb li:first-child a{padding-left:0}html.theme--catppuccin-latte .breadcrumb li.is-active a{color:#41445a;cursor:default;pointer-events:none}html.theme--catppuccin-latte .breadcrumb li+li::before{color:#9ca0b0;content:"\0002f"}html.theme--catppuccin-latte .breadcrumb ul,html.theme--catppuccin-latte .breadcrumb ol{align-items:flex-start;display:flex;flex-wrap:wrap;justify-content:flex-start}html.theme--catppuccin-latte .breadcrumb .icon:first-child{margin-right:.5em}html.theme--catppuccin-latte .breadcrumb .icon:last-child{margin-left:.5em}html.theme--catppuccin-latte .breadcrumb.is-centered ol,html.theme--catppuccin-latte .breadcrumb.is-centered ul{justify-content:center}html.theme--catppuccin-latte .breadcrumb.is-right ol,html.theme--catppuccin-latte .breadcrumb.is-right ul{justify-content:flex-end}html.theme--catppuccin-latte .breadcrumb.is-small,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.breadcrumb{font-size:.75rem}html.theme--catppuccin-latte .breadcrumb.is-medium{font-size:1.25rem}html.theme--catppuccin-latte .breadcrumb.is-large{font-size:1.5rem}html.theme--catppuccin-latte .breadcrumb.has-arrow-separator li+li::before{content:"\02192"}html.theme--catppuccin-latte .breadcrumb.has-bullet-separator li+li::before{content:"\02022"}html.theme--catppuccin-latte .breadcrumb.has-dot-separator li+li::before{content:"\000b7"}html.theme--catppuccin-latte .breadcrumb.has-succeeds-separator li+li::before{content:"\0227B"}html.theme--catppuccin-latte .card{background-color:#fff;border-radius:.25rem;box-shadow:#171717;color:#4c4f69;max-width:100%;position:relative}html.theme--catppuccin-latte .card-footer:first-child,html.theme--catppuccin-latte .card-content:first-child,html.theme--catppuccin-latte .card-header:first-child{border-top-left-radius:.25rem;border-top-right-radius:.25rem}html.theme--catppuccin-latte .card-footer:last-child,html.theme--catppuccin-latte .card-content:last-child,html.theme--catppuccin-latte .card-header:last-child{border-bottom-left-radius:.25rem;border-bottom-right-radius:.25rem}html.theme--catppuccin-latte .card-header{background-color:rgba(0,0,0,0);align-items:stretch;box-shadow:0 0.125em 0.25em rgba(10,10,10,0.1);display:flex}html.theme--catppuccin-latte .card-header-title{align-items:center;color:#41445a;display:flex;flex-grow:1;font-weight:700;padding:0.75rem 1rem}html.theme--catppuccin-latte .card-header-title.is-centered{justify-content:center}html.theme--catppuccin-latte .card-header-icon{-moz-appearance:none;-webkit-appearance:none;appearance:none;background:none;border:none;color:currentColor;font-family:inherit;font-size:1em;margin:0;padding:0;align-items:center;cursor:pointer;display:flex;justify-content:center;padding:0.75rem 1rem}html.theme--catppuccin-latte .card-image{display:block;position:relative}html.theme--catppuccin-latte .card-image:first-child img{border-top-left-radius:.25rem;border-top-right-radius:.25rem}html.theme--catppuccin-latte .card-image:last-child img{border-bottom-left-radius:.25rem;border-bottom-right-radius:.25rem}html.theme--catppuccin-latte .card-content{background-color:rgba(0,0,0,0);padding:1.5rem}html.theme--catppuccin-latte .card-footer{background-color:rgba(0,0,0,0);border-top:1px solid #ededed;align-items:stretch;display:flex}html.theme--catppuccin-latte .card-footer-item{align-items:center;display:flex;flex-basis:0;flex-grow:1;flex-shrink:0;justify-content:center;padding:.75rem}html.theme--catppuccin-latte .card-footer-item:not(:last-child){border-right:1px solid #ededed}html.theme--catppuccin-latte .card .media:not(:last-child){margin-bottom:1.5rem}html.theme--catppuccin-latte .dropdown{display:inline-flex;position:relative;vertical-align:top}html.theme--catppuccin-latte .dropdown.is-active .dropdown-menu,html.theme--catppuccin-latte .dropdown.is-hoverable:hover .dropdown-menu{display:block}html.theme--catppuccin-latte .dropdown.is-right .dropdown-menu{left:auto;right:0}html.theme--catppuccin-latte .dropdown.is-up .dropdown-menu{bottom:100%;padding-bottom:4px;padding-top:initial;top:auto}html.theme--catppuccin-latte .dropdown-menu{display:none;left:0;min-width:12rem;padding-top:4px;position:absolute;top:100%;z-index:20}html.theme--catppuccin-latte .dropdown-content{background-color:#e6e9ef;border-radius:.4em;box-shadow:#171717;padding-bottom:.5rem;padding-top:.5rem}html.theme--catppuccin-latte .dropdown-item{color:#4c4f69;display:block;font-size:0.875rem;line-height:1.5;padding:0.375rem 1rem;position:relative}html.theme--catppuccin-latte a.dropdown-item,html.theme--catppuccin-latte button.dropdown-item{padding-right:3rem;text-align:inherit;white-space:nowrap;width:100%}html.theme--catppuccin-latte a.dropdown-item:hover,html.theme--catppuccin-latte button.dropdown-item:hover{background-color:#e6e9ef;color:#0a0a0a}html.theme--catppuccin-latte a.dropdown-item.is-active,html.theme--catppuccin-latte button.dropdown-item.is-active{background-color:#1e66f5;color:#fff}html.theme--catppuccin-latte .dropdown-divider{background-color:#ededed;border:none;display:block;height:1px;margin:0.5rem 0}html.theme--catppuccin-latte .level{align-items:center;justify-content:space-between}html.theme--catppuccin-latte .level code{border-radius:.4em}html.theme--catppuccin-latte .level img{display:inline-block;vertical-align:top}html.theme--catppuccin-latte .level.is-mobile{display:flex}html.theme--catppuccin-latte .level.is-mobile .level-left,html.theme--catppuccin-latte .level.is-mobile .level-right{display:flex}html.theme--catppuccin-latte .level.is-mobile .level-left+.level-right{margin-top:0}html.theme--catppuccin-latte .level.is-mobile .level-item:not(:last-child){margin-bottom:0;margin-right:.75rem}html.theme--catppuccin-latte .level.is-mobile .level-item:not(.is-narrow){flex-grow:1}@media screen and (min-width: 769px),print{html.theme--catppuccin-latte .level{display:flex}html.theme--catppuccin-latte .level>.level-item:not(.is-narrow){flex-grow:1}}html.theme--catppuccin-latte .level-item{align-items:center;display:flex;flex-basis:auto;flex-grow:0;flex-shrink:0;justify-content:center}html.theme--catppuccin-latte .level-item .title,html.theme--catppuccin-latte .level-item .subtitle{margin-bottom:0}@media screen and (max-width: 768px){html.theme--catppuccin-latte .level-item:not(:last-child){margin-bottom:.75rem}}html.theme--catppuccin-latte .level-left,html.theme--catppuccin-latte .level-right{flex-basis:auto;flex-grow:0;flex-shrink:0}html.theme--catppuccin-latte .level-left .level-item.is-flexible,html.theme--catppuccin-latte .level-right .level-item.is-flexible{flex-grow:1}@media screen and (min-width: 769px),print{html.theme--catppuccin-latte .level-left .level-item:not(:last-child),html.theme--catppuccin-latte .level-right .level-item:not(:last-child){margin-right:.75rem}}html.theme--catppuccin-latte .level-left{align-items:center;justify-content:flex-start}@media screen and (max-width: 768px){html.theme--catppuccin-latte .level-left+.level-right{margin-top:1.5rem}}@media screen and (min-width: 769px),print{html.theme--catppuccin-latte .level-left{display:flex}}html.theme--catppuccin-latte .level-right{align-items:center;justify-content:flex-end}@media screen and (min-width: 769px),print{html.theme--catppuccin-latte .level-right{display:flex}}html.theme--catppuccin-latte .media{align-items:flex-start;display:flex;text-align:inherit}html.theme--catppuccin-latte .media .content:not(:last-child){margin-bottom:.75rem}html.theme--catppuccin-latte .media .media{border-top:1px solid rgba(172,176,190,0.5);display:flex;padding-top:.75rem}html.theme--catppuccin-latte .media .media .content:not(:last-child),html.theme--catppuccin-latte .media .media .control:not(:last-child){margin-bottom:.5rem}html.theme--catppuccin-latte .media .media .media{padding-top:.5rem}html.theme--catppuccin-latte .media .media .media+.media{margin-top:.5rem}html.theme--catppuccin-latte .media+.media{border-top:1px solid rgba(172,176,190,0.5);margin-top:1rem;padding-top:1rem}html.theme--catppuccin-latte .media.is-large+.media{margin-top:1.5rem;padding-top:1.5rem}html.theme--catppuccin-latte .media-left,html.theme--catppuccin-latte .media-right{flex-basis:auto;flex-grow:0;flex-shrink:0}html.theme--catppuccin-latte .media-left{margin-right:1rem}html.theme--catppuccin-latte .media-right{margin-left:1rem}html.theme--catppuccin-latte .media-content{flex-basis:auto;flex-grow:1;flex-shrink:1;text-align:inherit}@media screen and (max-width: 768px){html.theme--catppuccin-latte .media-content{overflow-x:auto}}html.theme--catppuccin-latte .menu{font-size:1rem}html.theme--catppuccin-latte .menu.is-small,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.menu{font-size:.75rem}html.theme--catppuccin-latte .menu.is-medium{font-size:1.25rem}html.theme--catppuccin-latte .menu.is-large{font-size:1.5rem}html.theme--catppuccin-latte .menu-list{line-height:1.25}html.theme--catppuccin-latte .menu-list a{border-radius:3px;color:#4c4f69;display:block;padding:0.5em 0.75em}html.theme--catppuccin-latte .menu-list a:hover{background-color:#e6e9ef;color:#41445a}html.theme--catppuccin-latte .menu-list a.is-active{background-color:#1e66f5;color:#fff}html.theme--catppuccin-latte .menu-list li ul{border-left:1px solid #acb0be;margin:.75em;padding-left:.75em}html.theme--catppuccin-latte .menu-label{color:#616587;font-size:.75em;letter-spacing:.1em;text-transform:uppercase}html.theme--catppuccin-latte .menu-label:not(:first-child){margin-top:1em}html.theme--catppuccin-latte .menu-label:not(:last-child){margin-bottom:1em}html.theme--catppuccin-latte .message{background-color:#e6e9ef;border-radius:.4em;font-size:1rem}html.theme--catppuccin-latte .message strong{color:currentColor}html.theme--catppuccin-latte .message a:not(.button):not(.tag):not(.dropdown-item){color:currentColor;text-decoration:underline}html.theme--catppuccin-latte .message.is-small,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.message{font-size:.75rem}html.theme--catppuccin-latte .message.is-medium{font-size:1.25rem}html.theme--catppuccin-latte .message.is-large{font-size:1.5rem}html.theme--catppuccin-latte .message.is-white{background-color:#fff}html.theme--catppuccin-latte .message.is-white .message-header{background-color:#fff;color:#0a0a0a}html.theme--catppuccin-latte .message.is-white .message-body{border-color:#fff}html.theme--catppuccin-latte .message.is-black{background-color:#fafafa}html.theme--catppuccin-latte .message.is-black .message-header{background-color:#0a0a0a;color:#fff}html.theme--catppuccin-latte .message.is-black .message-body{border-color:#0a0a0a}html.theme--catppuccin-latte .message.is-light{background-color:#fafafa}html.theme--catppuccin-latte .message.is-light .message-header{background-color:#f5f5f5;color:rgba(0,0,0,0.7)}html.theme--catppuccin-latte .message.is-light .message-body{border-color:#f5f5f5}html.theme--catppuccin-latte .message.is-dark,html.theme--catppuccin-latte .content kbd.message{background-color:#f9fafb}html.theme--catppuccin-latte .message.is-dark .message-header,html.theme--catppuccin-latte .content kbd.message .message-header{background-color:#ccd0da;color:rgba(0,0,0,0.7)}html.theme--catppuccin-latte .message.is-dark .message-body,html.theme--catppuccin-latte .content kbd.message .message-body{border-color:#ccd0da}html.theme--catppuccin-latte .message.is-primary,html.theme--catppuccin-latte .docstring>section>a.message.docs-sourcelink{background-color:#ebf2fe}html.theme--catppuccin-latte .message.is-primary .message-header,html.theme--catppuccin-latte .docstring>section>a.message.docs-sourcelink .message-header{background-color:#1e66f5;color:#fff}html.theme--catppuccin-latte .message.is-primary .message-body,html.theme--catppuccin-latte .docstring>section>a.message.docs-sourcelink .message-body{border-color:#1e66f5;color:#0a52e1}html.theme--catppuccin-latte .message.is-link{background-color:#ebf2fe}html.theme--catppuccin-latte .message.is-link .message-header{background-color:#1e66f5;color:#fff}html.theme--catppuccin-latte .message.is-link .message-body{border-color:#1e66f5;color:#0a52e1}html.theme--catppuccin-latte .message.is-info{background-color:#edfcfc}html.theme--catppuccin-latte .message.is-info .message-header{background-color:#179299;color:#fff}html.theme--catppuccin-latte .message.is-info .message-body{border-color:#179299;color:#1cb2ba}html.theme--catppuccin-latte .message.is-success{background-color:#f1fbef}html.theme--catppuccin-latte .message.is-success .message-header{background-color:#40a02b;color:#fff}html.theme--catppuccin-latte .message.is-success .message-body{border-color:#40a02b;color:#40a12b}html.theme--catppuccin-latte .message.is-warning{background-color:#fdf6ed}html.theme--catppuccin-latte .message.is-warning .message-header{background-color:#df8e1d;color:#fff}html.theme--catppuccin-latte .message.is-warning .message-body{border-color:#df8e1d;color:#9e6515}html.theme--catppuccin-latte .message.is-danger{background-color:#feecf0}html.theme--catppuccin-latte .message.is-danger .message-header{background-color:#d20f39;color:#fff}html.theme--catppuccin-latte .message.is-danger .message-body{border-color:#d20f39;color:#e9113f}html.theme--catppuccin-latte .message-header{align-items:center;background-color:#4c4f69;border-radius:.4em .4em 0 0;color:#fff;display:flex;font-weight:700;justify-content:space-between;line-height:1.25;padding:0.75em 1em;position:relative}html.theme--catppuccin-latte .message-header .delete{flex-grow:0;flex-shrink:0;margin-left:.75em}html.theme--catppuccin-latte .message-header+.message-body{border-width:0;border-top-left-radius:0;border-top-right-radius:0}html.theme--catppuccin-latte .message-body{border-color:#acb0be;border-radius:.4em;border-style:solid;border-width:0 0 0 4px;color:#4c4f69;padding:1.25em 1.5em}html.theme--catppuccin-latte .message-body code,html.theme--catppuccin-latte .message-body pre{background-color:#fff}html.theme--catppuccin-latte .message-body pre code{background-color:rgba(0,0,0,0)}html.theme--catppuccin-latte .modal{align-items:center;display:none;flex-direction:column;justify-content:center;overflow:hidden;position:fixed;z-index:40}html.theme--catppuccin-latte .modal.is-active{display:flex}html.theme--catppuccin-latte .modal-background{background-color:rgba(10,10,10,0.86)}html.theme--catppuccin-latte .modal-content,html.theme--catppuccin-latte .modal-card{margin:0 20px;max-height:calc(100vh - 160px);overflow:auto;position:relative;width:100%}@media screen and (min-width: 769px){html.theme--catppuccin-latte .modal-content,html.theme--catppuccin-latte .modal-card{margin:0 auto;max-height:calc(100vh - 40px);width:640px}}html.theme--catppuccin-latte .modal-close{background:none;height:40px;position:fixed;right:20px;top:20px;width:40px}html.theme--catppuccin-latte .modal-card{display:flex;flex-direction:column;max-height:calc(100vh - 40px);overflow:hidden;-ms-overflow-y:visible}html.theme--catppuccin-latte .modal-card-head,html.theme--catppuccin-latte .modal-card-foot{align-items:center;background-color:#e6e9ef;display:flex;flex-shrink:0;justify-content:flex-start;padding:20px;position:relative}html.theme--catppuccin-latte .modal-card-head{border-bottom:1px solid #acb0be;border-top-left-radius:8px;border-top-right-radius:8px}html.theme--catppuccin-latte .modal-card-title{color:#4c4f69;flex-grow:1;flex-shrink:0;font-size:1.5rem;line-height:1}html.theme--catppuccin-latte .modal-card-foot{border-bottom-left-radius:8px;border-bottom-right-radius:8px;border-top:1px solid #acb0be}html.theme--catppuccin-latte .modal-card-foot .button:not(:last-child){margin-right:.5em}html.theme--catppuccin-latte .modal-card-body{-webkit-overflow-scrolling:touch;background-color:#eff1f5;flex-grow:1;flex-shrink:1;overflow:auto;padding:20px}html.theme--catppuccin-latte .navbar{background-color:#1e66f5;min-height:4rem;position:relative;z-index:30}html.theme--catppuccin-latte .navbar.is-white{background-color:#fff;color:#0a0a0a}html.theme--catppuccin-latte .navbar.is-white .navbar-brand>.navbar-item,html.theme--catppuccin-latte .navbar.is-white .navbar-brand .navbar-link{color:#0a0a0a}html.theme--catppuccin-latte .navbar.is-white .navbar-brand>a.navbar-item:focus,html.theme--catppuccin-latte .navbar.is-white .navbar-brand>a.navbar-item:hover,html.theme--catppuccin-latte .navbar.is-white .navbar-brand>a.navbar-item.is-active,html.theme--catppuccin-latte .navbar.is-white .navbar-brand .navbar-link:focus,html.theme--catppuccin-latte .navbar.is-white .navbar-brand .navbar-link:hover,html.theme--catppuccin-latte .navbar.is-white .navbar-brand .navbar-link.is-active{background-color:#f2f2f2;color:#0a0a0a}html.theme--catppuccin-latte .navbar.is-white .navbar-brand .navbar-link::after{border-color:#0a0a0a}html.theme--catppuccin-latte .navbar.is-white .navbar-burger{color:#0a0a0a}@media screen and (min-width: 1056px){html.theme--catppuccin-latte .navbar.is-white .navbar-start>.navbar-item,html.theme--catppuccin-latte .navbar.is-white .navbar-start .navbar-link,html.theme--catppuccin-latte .navbar.is-white .navbar-end>.navbar-item,html.theme--catppuccin-latte .navbar.is-white .navbar-end .navbar-link{color:#0a0a0a}html.theme--catppuccin-latte .navbar.is-white .navbar-start>a.navbar-item:focus,html.theme--catppuccin-latte .navbar.is-white .navbar-start>a.navbar-item:hover,html.theme--catppuccin-latte .navbar.is-white .navbar-start>a.navbar-item.is-active,html.theme--catppuccin-latte .navbar.is-white .navbar-start .navbar-link:focus,html.theme--catppuccin-latte .navbar.is-white .navbar-start .navbar-link:hover,html.theme--catppuccin-latte .navbar.is-white .navbar-start .navbar-link.is-active,html.theme--catppuccin-latte .navbar.is-white .navbar-end>a.navbar-item:focus,html.theme--catppuccin-latte .navbar.is-white .navbar-end>a.navbar-item:hover,html.theme--catppuccin-latte .navbar.is-white .navbar-end>a.navbar-item.is-active,html.theme--catppuccin-latte .navbar.is-white .navbar-end .navbar-link:focus,html.theme--catppuccin-latte .navbar.is-white .navbar-end .navbar-link:hover,html.theme--catppuccin-latte .navbar.is-white .navbar-end .navbar-link.is-active{background-color:#f2f2f2;color:#0a0a0a}html.theme--catppuccin-latte .navbar.is-white .navbar-start .navbar-link::after,html.theme--catppuccin-latte .navbar.is-white .navbar-end .navbar-link::after{border-color:#0a0a0a}html.theme--catppuccin-latte .navbar.is-white .navbar-item.has-dropdown:focus .navbar-link,html.theme--catppuccin-latte .navbar.is-white .navbar-item.has-dropdown:hover .navbar-link,html.theme--catppuccin-latte .navbar.is-white .navbar-item.has-dropdown.is-active .navbar-link{background-color:#f2f2f2;color:#0a0a0a}html.theme--catppuccin-latte .navbar.is-white .navbar-dropdown a.navbar-item.is-active{background-color:#fff;color:#0a0a0a}}html.theme--catppuccin-latte .navbar.is-black{background-color:#0a0a0a;color:#fff}html.theme--catppuccin-latte .navbar.is-black .navbar-brand>.navbar-item,html.theme--catppuccin-latte .navbar.is-black .navbar-brand .navbar-link{color:#fff}html.theme--catppuccin-latte .navbar.is-black .navbar-brand>a.navbar-item:focus,html.theme--catppuccin-latte .navbar.is-black .navbar-brand>a.navbar-item:hover,html.theme--catppuccin-latte .navbar.is-black .navbar-brand>a.navbar-item.is-active,html.theme--catppuccin-latte .navbar.is-black .navbar-brand .navbar-link:focus,html.theme--catppuccin-latte .navbar.is-black .navbar-brand .navbar-link:hover,html.theme--catppuccin-latte .navbar.is-black .navbar-brand .navbar-link.is-active{background-color:#000;color:#fff}html.theme--catppuccin-latte .navbar.is-black .navbar-brand .navbar-link::after{border-color:#fff}html.theme--catppuccin-latte .navbar.is-black .navbar-burger{color:#fff}@media screen and (min-width: 1056px){html.theme--catppuccin-latte .navbar.is-black .navbar-start>.navbar-item,html.theme--catppuccin-latte .navbar.is-black .navbar-start .navbar-link,html.theme--catppuccin-latte .navbar.is-black .navbar-end>.navbar-item,html.theme--catppuccin-latte .navbar.is-black .navbar-end .navbar-link{color:#fff}html.theme--catppuccin-latte .navbar.is-black .navbar-start>a.navbar-item:focus,html.theme--catppuccin-latte .navbar.is-black .navbar-start>a.navbar-item:hover,html.theme--catppuccin-latte .navbar.is-black .navbar-start>a.navbar-item.is-active,html.theme--catppuccin-latte .navbar.is-black .navbar-start .navbar-link:focus,html.theme--catppuccin-latte .navbar.is-black .navbar-start .navbar-link:hover,html.theme--catppuccin-latte .navbar.is-black .navbar-start .navbar-link.is-active,html.theme--catppuccin-latte .navbar.is-black .navbar-end>a.navbar-item:focus,html.theme--catppuccin-latte .navbar.is-black .navbar-end>a.navbar-item:hover,html.theme--catppuccin-latte .navbar.is-black .navbar-end>a.navbar-item.is-active,html.theme--catppuccin-latte .navbar.is-black .navbar-end .navbar-link:focus,html.theme--catppuccin-latte .navbar.is-black .navbar-end .navbar-link:hover,html.theme--catppuccin-latte .navbar.is-black .navbar-end .navbar-link.is-active{background-color:#000;color:#fff}html.theme--catppuccin-latte .navbar.is-black .navbar-start .navbar-link::after,html.theme--catppuccin-latte .navbar.is-black .navbar-end .navbar-link::after{border-color:#fff}html.theme--catppuccin-latte .navbar.is-black .navbar-item.has-dropdown:focus .navbar-link,html.theme--catppuccin-latte .navbar.is-black .navbar-item.has-dropdown:hover .navbar-link,html.theme--catppuccin-latte .navbar.is-black .navbar-item.has-dropdown.is-active .navbar-link{background-color:#000;color:#fff}html.theme--catppuccin-latte .navbar.is-black .navbar-dropdown a.navbar-item.is-active{background-color:#0a0a0a;color:#fff}}html.theme--catppuccin-latte .navbar.is-light{background-color:#f5f5f5;color:rgba(0,0,0,0.7)}html.theme--catppuccin-latte .navbar.is-light .navbar-brand>.navbar-item,html.theme--catppuccin-latte .navbar.is-light .navbar-brand .navbar-link{color:rgba(0,0,0,0.7)}html.theme--catppuccin-latte .navbar.is-light .navbar-brand>a.navbar-item:focus,html.theme--catppuccin-latte .navbar.is-light .navbar-brand>a.navbar-item:hover,html.theme--catppuccin-latte .navbar.is-light .navbar-brand>a.navbar-item.is-active,html.theme--catppuccin-latte .navbar.is-light .navbar-brand .navbar-link:focus,html.theme--catppuccin-latte .navbar.is-light .navbar-brand .navbar-link:hover,html.theme--catppuccin-latte .navbar.is-light .navbar-brand .navbar-link.is-active{background-color:#e8e8e8;color:rgba(0,0,0,0.7)}html.theme--catppuccin-latte .navbar.is-light .navbar-brand .navbar-link::after{border-color:rgba(0,0,0,0.7)}html.theme--catppuccin-latte .navbar.is-light .navbar-burger{color:rgba(0,0,0,0.7)}@media screen and (min-width: 1056px){html.theme--catppuccin-latte .navbar.is-light .navbar-start>.navbar-item,html.theme--catppuccin-latte .navbar.is-light .navbar-start .navbar-link,html.theme--catppuccin-latte .navbar.is-light .navbar-end>.navbar-item,html.theme--catppuccin-latte .navbar.is-light .navbar-end .navbar-link{color:rgba(0,0,0,0.7)}html.theme--catppuccin-latte .navbar.is-light .navbar-start>a.navbar-item:focus,html.theme--catppuccin-latte .navbar.is-light .navbar-start>a.navbar-item:hover,html.theme--catppuccin-latte .navbar.is-light .navbar-start>a.navbar-item.is-active,html.theme--catppuccin-latte .navbar.is-light .navbar-start .navbar-link:focus,html.theme--catppuccin-latte .navbar.is-light .navbar-start .navbar-link:hover,html.theme--catppuccin-latte .navbar.is-light .navbar-start .navbar-link.is-active,html.theme--catppuccin-latte .navbar.is-light .navbar-end>a.navbar-item:focus,html.theme--catppuccin-latte .navbar.is-light .navbar-end>a.navbar-item:hover,html.theme--catppuccin-latte .navbar.is-light .navbar-end>a.navbar-item.is-active,html.theme--catppuccin-latte .navbar.is-light .navbar-end .navbar-link:focus,html.theme--catppuccin-latte .navbar.is-light .navbar-end .navbar-link:hover,html.theme--catppuccin-latte .navbar.is-light .navbar-end .navbar-link.is-active{background-color:#e8e8e8;color:rgba(0,0,0,0.7)}html.theme--catppuccin-latte .navbar.is-light .navbar-start .navbar-link::after,html.theme--catppuccin-latte .navbar.is-light .navbar-end .navbar-link::after{border-color:rgba(0,0,0,0.7)}html.theme--catppuccin-latte .navbar.is-light .navbar-item.has-dropdown:focus .navbar-link,html.theme--catppuccin-latte .navbar.is-light .navbar-item.has-dropdown:hover .navbar-link,html.theme--catppuccin-latte .navbar.is-light .navbar-item.has-dropdown.is-active .navbar-link{background-color:#e8e8e8;color:rgba(0,0,0,0.7)}html.theme--catppuccin-latte .navbar.is-light .navbar-dropdown a.navbar-item.is-active{background-color:#f5f5f5;color:rgba(0,0,0,0.7)}}html.theme--catppuccin-latte .navbar.is-dark,html.theme--catppuccin-latte .content kbd.navbar{background-color:#ccd0da;color:rgba(0,0,0,0.7)}html.theme--catppuccin-latte .navbar.is-dark .navbar-brand>.navbar-item,html.theme--catppuccin-latte .content kbd.navbar .navbar-brand>.navbar-item,html.theme--catppuccin-latte .navbar.is-dark .navbar-brand .navbar-link,html.theme--catppuccin-latte .content kbd.navbar .navbar-brand .navbar-link{color:rgba(0,0,0,0.7)}html.theme--catppuccin-latte .navbar.is-dark .navbar-brand>a.navbar-item:focus,html.theme--catppuccin-latte .content kbd.navbar .navbar-brand>a.navbar-item:focus,html.theme--catppuccin-latte .navbar.is-dark .navbar-brand>a.navbar-item:hover,html.theme--catppuccin-latte .content kbd.navbar .navbar-brand>a.navbar-item:hover,html.theme--catppuccin-latte .navbar.is-dark .navbar-brand>a.navbar-item.is-active,html.theme--catppuccin-latte .content kbd.navbar .navbar-brand>a.navbar-item.is-active,html.theme--catppuccin-latte .navbar.is-dark .navbar-brand .navbar-link:focus,html.theme--catppuccin-latte .content kbd.navbar .navbar-brand .navbar-link:focus,html.theme--catppuccin-latte .navbar.is-dark .navbar-brand .navbar-link:hover,html.theme--catppuccin-latte .content kbd.navbar .navbar-brand .navbar-link:hover,html.theme--catppuccin-latte .navbar.is-dark .navbar-brand .navbar-link.is-active,html.theme--catppuccin-latte .content kbd.navbar .navbar-brand .navbar-link.is-active{background-color:#bdc2cf;color:rgba(0,0,0,0.7)}html.theme--catppuccin-latte .navbar.is-dark .navbar-brand .navbar-link::after,html.theme--catppuccin-latte .content kbd.navbar .navbar-brand .navbar-link::after{border-color:rgba(0,0,0,0.7)}html.theme--catppuccin-latte .navbar.is-dark .navbar-burger,html.theme--catppuccin-latte .content kbd.navbar .navbar-burger{color:rgba(0,0,0,0.7)}@media screen and (min-width: 1056px){html.theme--catppuccin-latte .navbar.is-dark .navbar-start>.navbar-item,html.theme--catppuccin-latte .content kbd.navbar .navbar-start>.navbar-item,html.theme--catppuccin-latte .navbar.is-dark .navbar-start .navbar-link,html.theme--catppuccin-latte .content kbd.navbar .navbar-start .navbar-link,html.theme--catppuccin-latte .navbar.is-dark .navbar-end>.navbar-item,html.theme--catppuccin-latte .content kbd.navbar .navbar-end>.navbar-item,html.theme--catppuccin-latte .navbar.is-dark .navbar-end .navbar-link,html.theme--catppuccin-latte .content kbd.navbar .navbar-end .navbar-link{color:rgba(0,0,0,0.7)}html.theme--catppuccin-latte .navbar.is-dark .navbar-start>a.navbar-item:focus,html.theme--catppuccin-latte .content kbd.navbar .navbar-start>a.navbar-item:focus,html.theme--catppuccin-latte .navbar.is-dark .navbar-start>a.navbar-item:hover,html.theme--catppuccin-latte .content kbd.navbar .navbar-start>a.navbar-item:hover,html.theme--catppuccin-latte .navbar.is-dark .navbar-start>a.navbar-item.is-active,html.theme--catppuccin-latte .content kbd.navbar .navbar-start>a.navbar-item.is-active,html.theme--catppuccin-latte .navbar.is-dark .navbar-start .navbar-link:focus,html.theme--catppuccin-latte .content kbd.navbar .navbar-start .navbar-link:focus,html.theme--catppuccin-latte .navbar.is-dark .navbar-start .navbar-link:hover,html.theme--catppuccin-latte .content kbd.navbar .navbar-start .navbar-link:hover,html.theme--catppuccin-latte .navbar.is-dark .navbar-start .navbar-link.is-active,html.theme--catppuccin-latte .content kbd.navbar .navbar-start .navbar-link.is-active,html.theme--catppuccin-latte .navbar.is-dark .navbar-end>a.navbar-item:focus,html.theme--catppuccin-latte .content kbd.navbar .navbar-end>a.navbar-item:focus,html.theme--catppuccin-latte .navbar.is-dark .navbar-end>a.navbar-item:hover,html.theme--catppuccin-latte .content kbd.navbar .navbar-end>a.navbar-item:hover,html.theme--catppuccin-latte .navbar.is-dark .navbar-end>a.navbar-item.is-active,html.theme--catppuccin-latte .content kbd.navbar .navbar-end>a.navbar-item.is-active,html.theme--catppuccin-latte .navbar.is-dark .navbar-end .navbar-link:focus,html.theme--catppuccin-latte .content kbd.navbar .navbar-end .navbar-link:focus,html.theme--catppuccin-latte .navbar.is-dark .navbar-end .navbar-link:hover,html.theme--catppuccin-latte .content kbd.navbar .navbar-end .navbar-link:hover,html.theme--catppuccin-latte .navbar.is-dark .navbar-end .navbar-link.is-active,html.theme--catppuccin-latte .content kbd.navbar .navbar-end .navbar-link.is-active{background-color:#bdc2cf;color:rgba(0,0,0,0.7)}html.theme--catppuccin-latte .navbar.is-dark .navbar-start .navbar-link::after,html.theme--catppuccin-latte .content kbd.navbar .navbar-start .navbar-link::after,html.theme--catppuccin-latte .navbar.is-dark .navbar-end .navbar-link::after,html.theme--catppuccin-latte .content kbd.navbar .navbar-end .navbar-link::after{border-color:rgba(0,0,0,0.7)}html.theme--catppuccin-latte .navbar.is-dark .navbar-item.has-dropdown:focus .navbar-link,html.theme--catppuccin-latte .content kbd.navbar .navbar-item.has-dropdown:focus .navbar-link,html.theme--catppuccin-latte .navbar.is-dark .navbar-item.has-dropdown:hover .navbar-link,html.theme--catppuccin-latte .content kbd.navbar .navbar-item.has-dropdown:hover .navbar-link,html.theme--catppuccin-latte .navbar.is-dark .navbar-item.has-dropdown.is-active .navbar-link,html.theme--catppuccin-latte .content kbd.navbar .navbar-item.has-dropdown.is-active .navbar-link{background-color:#bdc2cf;color:rgba(0,0,0,0.7)}html.theme--catppuccin-latte .navbar.is-dark .navbar-dropdown a.navbar-item.is-active,html.theme--catppuccin-latte .content kbd.navbar .navbar-dropdown a.navbar-item.is-active{background-color:#ccd0da;color:rgba(0,0,0,0.7)}}html.theme--catppuccin-latte .navbar.is-primary,html.theme--catppuccin-latte .docstring>section>a.navbar.docs-sourcelink{background-color:#1e66f5;color:#fff}html.theme--catppuccin-latte .navbar.is-primary .navbar-brand>.navbar-item,html.theme--catppuccin-latte .docstring>section>a.navbar.docs-sourcelink .navbar-brand>.navbar-item,html.theme--catppuccin-latte .navbar.is-primary .navbar-brand .navbar-link,html.theme--catppuccin-latte .docstring>section>a.navbar.docs-sourcelink .navbar-brand .navbar-link{color:#fff}html.theme--catppuccin-latte .navbar.is-primary .navbar-brand>a.navbar-item:focus,html.theme--catppuccin-latte .docstring>section>a.navbar.docs-sourcelink .navbar-brand>a.navbar-item:focus,html.theme--catppuccin-latte .navbar.is-primary .navbar-brand>a.navbar-item:hover,html.theme--catppuccin-latte .docstring>section>a.navbar.docs-sourcelink .navbar-brand>a.navbar-item:hover,html.theme--catppuccin-latte .navbar.is-primary .navbar-brand>a.navbar-item.is-active,html.theme--catppuccin-latte .docstring>section>a.navbar.docs-sourcelink .navbar-brand>a.navbar-item.is-active,html.theme--catppuccin-latte .navbar.is-primary .navbar-brand .navbar-link:focus,html.theme--catppuccin-latte .docstring>section>a.navbar.docs-sourcelink .navbar-brand .navbar-link:focus,html.theme--catppuccin-latte .navbar.is-primary .navbar-brand .navbar-link:hover,html.theme--catppuccin-latte .docstring>section>a.navbar.docs-sourcelink .navbar-brand .navbar-link:hover,html.theme--catppuccin-latte .navbar.is-primary .navbar-brand .navbar-link.is-active,html.theme--catppuccin-latte .docstring>section>a.navbar.docs-sourcelink .navbar-brand .navbar-link.is-active{background-color:#0b57ef;color:#fff}html.theme--catppuccin-latte .navbar.is-primary .navbar-brand .navbar-link::after,html.theme--catppuccin-latte .docstring>section>a.navbar.docs-sourcelink .navbar-brand .navbar-link::after{border-color:#fff}html.theme--catppuccin-latte .navbar.is-primary .navbar-burger,html.theme--catppuccin-latte .docstring>section>a.navbar.docs-sourcelink .navbar-burger{color:#fff}@media screen and (min-width: 1056px){html.theme--catppuccin-latte .navbar.is-primary .navbar-start>.navbar-item,html.theme--catppuccin-latte .docstring>section>a.navbar.docs-sourcelink .navbar-start>.navbar-item,html.theme--catppuccin-latte .navbar.is-primary .navbar-start .navbar-link,html.theme--catppuccin-latte .docstring>section>a.navbar.docs-sourcelink .navbar-start .navbar-link,html.theme--catppuccin-latte .navbar.is-primary .navbar-end>.navbar-item,html.theme--catppuccin-latte .docstring>section>a.navbar.docs-sourcelink .navbar-end>.navbar-item,html.theme--catppuccin-latte .navbar.is-primary .navbar-end .navbar-link,html.theme--catppuccin-latte .docstring>section>a.navbar.docs-sourcelink .navbar-end .navbar-link{color:#fff}html.theme--catppuccin-latte .navbar.is-primary .navbar-start>a.navbar-item:focus,html.theme--catppuccin-latte .docstring>section>a.navbar.docs-sourcelink .navbar-start>a.navbar-item:focus,html.theme--catppuccin-latte .navbar.is-primary .navbar-start>a.navbar-item:hover,html.theme--catppuccin-latte .docstring>section>a.navbar.docs-sourcelink .navbar-start>a.navbar-item:hover,html.theme--catppuccin-latte .navbar.is-primary .navbar-start>a.navbar-item.is-active,html.theme--catppuccin-latte .docstring>section>a.navbar.docs-sourcelink .navbar-start>a.navbar-item.is-active,html.theme--catppuccin-latte .navbar.is-primary .navbar-start .navbar-link:focus,html.theme--catppuccin-latte .docstring>section>a.navbar.docs-sourcelink .navbar-start .navbar-link:focus,html.theme--catppuccin-latte .navbar.is-primary .navbar-start .navbar-link:hover,html.theme--catppuccin-latte .docstring>section>a.navbar.docs-sourcelink .navbar-start .navbar-link:hover,html.theme--catppuccin-latte .navbar.is-primary .navbar-start .navbar-link.is-active,html.theme--catppuccin-latte .docstring>section>a.navbar.docs-sourcelink .navbar-start .navbar-link.is-active,html.theme--catppuccin-latte .navbar.is-primary .navbar-end>a.navbar-item:focus,html.theme--catppuccin-latte .docstring>section>a.navbar.docs-sourcelink .navbar-end>a.navbar-item:focus,html.theme--catppuccin-latte .navbar.is-primary .navbar-end>a.navbar-item:hover,html.theme--catppuccin-latte .docstring>section>a.navbar.docs-sourcelink .navbar-end>a.navbar-item:hover,html.theme--catppuccin-latte .navbar.is-primary .navbar-end>a.navbar-item.is-active,html.theme--catppuccin-latte .docstring>section>a.navbar.docs-sourcelink .navbar-end>a.navbar-item.is-active,html.theme--catppuccin-latte .navbar.is-primary .navbar-end .navbar-link:focus,html.theme--catppuccin-latte .docstring>section>a.navbar.docs-sourcelink .navbar-end .navbar-link:focus,html.theme--catppuccin-latte .navbar.is-primary .navbar-end .navbar-link:hover,html.theme--catppuccin-latte .docstring>section>a.navbar.docs-sourcelink .navbar-end .navbar-link:hover,html.theme--catppuccin-latte .navbar.is-primary .navbar-end .navbar-link.is-active,html.theme--catppuccin-latte .docstring>section>a.navbar.docs-sourcelink .navbar-end .navbar-link.is-active{background-color:#0b57ef;color:#fff}html.theme--catppuccin-latte .navbar.is-primary .navbar-start .navbar-link::after,html.theme--catppuccin-latte .docstring>section>a.navbar.docs-sourcelink .navbar-start .navbar-link::after,html.theme--catppuccin-latte .navbar.is-primary .navbar-end .navbar-link::after,html.theme--catppuccin-latte .docstring>section>a.navbar.docs-sourcelink .navbar-end .navbar-link::after{border-color:#fff}html.theme--catppuccin-latte .navbar.is-primary .navbar-item.has-dropdown:focus .navbar-link,html.theme--catppuccin-latte .docstring>section>a.navbar.docs-sourcelink .navbar-item.has-dropdown:focus .navbar-link,html.theme--catppuccin-latte .navbar.is-primary .navbar-item.has-dropdown:hover .navbar-link,html.theme--catppuccin-latte .docstring>section>a.navbar.docs-sourcelink .navbar-item.has-dropdown:hover .navbar-link,html.theme--catppuccin-latte .navbar.is-primary .navbar-item.has-dropdown.is-active .navbar-link,html.theme--catppuccin-latte .docstring>section>a.navbar.docs-sourcelink .navbar-item.has-dropdown.is-active .navbar-link{background-color:#0b57ef;color:#fff}html.theme--catppuccin-latte .navbar.is-primary .navbar-dropdown a.navbar-item.is-active,html.theme--catppuccin-latte .docstring>section>a.navbar.docs-sourcelink .navbar-dropdown a.navbar-item.is-active{background-color:#1e66f5;color:#fff}}html.theme--catppuccin-latte .navbar.is-link{background-color:#1e66f5;color:#fff}html.theme--catppuccin-latte .navbar.is-link .navbar-brand>.navbar-item,html.theme--catppuccin-latte .navbar.is-link .navbar-brand .navbar-link{color:#fff}html.theme--catppuccin-latte .navbar.is-link .navbar-brand>a.navbar-item:focus,html.theme--catppuccin-latte .navbar.is-link .navbar-brand>a.navbar-item:hover,html.theme--catppuccin-latte .navbar.is-link .navbar-brand>a.navbar-item.is-active,html.theme--catppuccin-latte .navbar.is-link .navbar-brand .navbar-link:focus,html.theme--catppuccin-latte .navbar.is-link .navbar-brand .navbar-link:hover,html.theme--catppuccin-latte .navbar.is-link .navbar-brand .navbar-link.is-active{background-color:#0b57ef;color:#fff}html.theme--catppuccin-latte .navbar.is-link .navbar-brand .navbar-link::after{border-color:#fff}html.theme--catppuccin-latte .navbar.is-link .navbar-burger{color:#fff}@media screen and (min-width: 1056px){html.theme--catppuccin-latte .navbar.is-link .navbar-start>.navbar-item,html.theme--catppuccin-latte .navbar.is-link .navbar-start .navbar-link,html.theme--catppuccin-latte .navbar.is-link .navbar-end>.navbar-item,html.theme--catppuccin-latte .navbar.is-link .navbar-end .navbar-link{color:#fff}html.theme--catppuccin-latte .navbar.is-link .navbar-start>a.navbar-item:focus,html.theme--catppuccin-latte .navbar.is-link .navbar-start>a.navbar-item:hover,html.theme--catppuccin-latte .navbar.is-link .navbar-start>a.navbar-item.is-active,html.theme--catppuccin-latte .navbar.is-link .navbar-start .navbar-link:focus,html.theme--catppuccin-latte .navbar.is-link .navbar-start .navbar-link:hover,html.theme--catppuccin-latte .navbar.is-link .navbar-start .navbar-link.is-active,html.theme--catppuccin-latte .navbar.is-link .navbar-end>a.navbar-item:focus,html.theme--catppuccin-latte .navbar.is-link .navbar-end>a.navbar-item:hover,html.theme--catppuccin-latte .navbar.is-link .navbar-end>a.navbar-item.is-active,html.theme--catppuccin-latte .navbar.is-link .navbar-end .navbar-link:focus,html.theme--catppuccin-latte .navbar.is-link .navbar-end .navbar-link:hover,html.theme--catppuccin-latte .navbar.is-link .navbar-end .navbar-link.is-active{background-color:#0b57ef;color:#fff}html.theme--catppuccin-latte .navbar.is-link .navbar-start .navbar-link::after,html.theme--catppuccin-latte .navbar.is-link .navbar-end .navbar-link::after{border-color:#fff}html.theme--catppuccin-latte .navbar.is-link .navbar-item.has-dropdown:focus .navbar-link,html.theme--catppuccin-latte .navbar.is-link .navbar-item.has-dropdown:hover .navbar-link,html.theme--catppuccin-latte .navbar.is-link .navbar-item.has-dropdown.is-active .navbar-link{background-color:#0b57ef;color:#fff}html.theme--catppuccin-latte .navbar.is-link .navbar-dropdown a.navbar-item.is-active{background-color:#1e66f5;color:#fff}}html.theme--catppuccin-latte .navbar.is-info{background-color:#179299;color:#fff}html.theme--catppuccin-latte .navbar.is-info .navbar-brand>.navbar-item,html.theme--catppuccin-latte .navbar.is-info .navbar-brand .navbar-link{color:#fff}html.theme--catppuccin-latte .navbar.is-info .navbar-brand>a.navbar-item:focus,html.theme--catppuccin-latte .navbar.is-info .navbar-brand>a.navbar-item:hover,html.theme--catppuccin-latte .navbar.is-info .navbar-brand>a.navbar-item.is-active,html.theme--catppuccin-latte .navbar.is-info .navbar-brand .navbar-link:focus,html.theme--catppuccin-latte .navbar.is-info .navbar-brand .navbar-link:hover,html.theme--catppuccin-latte .navbar.is-info .navbar-brand .navbar-link.is-active{background-color:#147d83;color:#fff}html.theme--catppuccin-latte .navbar.is-info .navbar-brand .navbar-link::after{border-color:#fff}html.theme--catppuccin-latte .navbar.is-info .navbar-burger{color:#fff}@media screen and (min-width: 1056px){html.theme--catppuccin-latte .navbar.is-info .navbar-start>.navbar-item,html.theme--catppuccin-latte .navbar.is-info .navbar-start .navbar-link,html.theme--catppuccin-latte .navbar.is-info .navbar-end>.navbar-item,html.theme--catppuccin-latte .navbar.is-info .navbar-end .navbar-link{color:#fff}html.theme--catppuccin-latte .navbar.is-info .navbar-start>a.navbar-item:focus,html.theme--catppuccin-latte .navbar.is-info .navbar-start>a.navbar-item:hover,html.theme--catppuccin-latte .navbar.is-info .navbar-start>a.navbar-item.is-active,html.theme--catppuccin-latte .navbar.is-info .navbar-start .navbar-link:focus,html.theme--catppuccin-latte .navbar.is-info .navbar-start .navbar-link:hover,html.theme--catppuccin-latte .navbar.is-info .navbar-start .navbar-link.is-active,html.theme--catppuccin-latte .navbar.is-info .navbar-end>a.navbar-item:focus,html.theme--catppuccin-latte .navbar.is-info .navbar-end>a.navbar-item:hover,html.theme--catppuccin-latte .navbar.is-info .navbar-end>a.navbar-item.is-active,html.theme--catppuccin-latte .navbar.is-info .navbar-end .navbar-link:focus,html.theme--catppuccin-latte .navbar.is-info .navbar-end .navbar-link:hover,html.theme--catppuccin-latte .navbar.is-info .navbar-end .navbar-link.is-active{background-color:#147d83;color:#fff}html.theme--catppuccin-latte .navbar.is-info .navbar-start .navbar-link::after,html.theme--catppuccin-latte .navbar.is-info .navbar-end .navbar-link::after{border-color:#fff}html.theme--catppuccin-latte .navbar.is-info .navbar-item.has-dropdown:focus .navbar-link,html.theme--catppuccin-latte .navbar.is-info .navbar-item.has-dropdown:hover .navbar-link,html.theme--catppuccin-latte .navbar.is-info .navbar-item.has-dropdown.is-active .navbar-link{background-color:#147d83;color:#fff}html.theme--catppuccin-latte .navbar.is-info .navbar-dropdown a.navbar-item.is-active{background-color:#179299;color:#fff}}html.theme--catppuccin-latte .navbar.is-success{background-color:#40a02b;color:#fff}html.theme--catppuccin-latte .navbar.is-success .navbar-brand>.navbar-item,html.theme--catppuccin-latte .navbar.is-success .navbar-brand .navbar-link{color:#fff}html.theme--catppuccin-latte .navbar.is-success .navbar-brand>a.navbar-item:focus,html.theme--catppuccin-latte .navbar.is-success .navbar-brand>a.navbar-item:hover,html.theme--catppuccin-latte .navbar.is-success .navbar-brand>a.navbar-item.is-active,html.theme--catppuccin-latte .navbar.is-success .navbar-brand .navbar-link:focus,html.theme--catppuccin-latte .navbar.is-success .navbar-brand .navbar-link:hover,html.theme--catppuccin-latte .navbar.is-success .navbar-brand .navbar-link.is-active{background-color:#388c26;color:#fff}html.theme--catppuccin-latte .navbar.is-success .navbar-brand .navbar-link::after{border-color:#fff}html.theme--catppuccin-latte .navbar.is-success .navbar-burger{color:#fff}@media screen and (min-width: 1056px){html.theme--catppuccin-latte .navbar.is-success .navbar-start>.navbar-item,html.theme--catppuccin-latte .navbar.is-success .navbar-start .navbar-link,html.theme--catppuccin-latte .navbar.is-success .navbar-end>.navbar-item,html.theme--catppuccin-latte .navbar.is-success .navbar-end .navbar-link{color:#fff}html.theme--catppuccin-latte .navbar.is-success .navbar-start>a.navbar-item:focus,html.theme--catppuccin-latte .navbar.is-success .navbar-start>a.navbar-item:hover,html.theme--catppuccin-latte .navbar.is-success .navbar-start>a.navbar-item.is-active,html.theme--catppuccin-latte .navbar.is-success .navbar-start .navbar-link:focus,html.theme--catppuccin-latte .navbar.is-success .navbar-start .navbar-link:hover,html.theme--catppuccin-latte .navbar.is-success .navbar-start .navbar-link.is-active,html.theme--catppuccin-latte .navbar.is-success .navbar-end>a.navbar-item:focus,html.theme--catppuccin-latte .navbar.is-success .navbar-end>a.navbar-item:hover,html.theme--catppuccin-latte .navbar.is-success .navbar-end>a.navbar-item.is-active,html.theme--catppuccin-latte .navbar.is-success .navbar-end .navbar-link:focus,html.theme--catppuccin-latte .navbar.is-success .navbar-end .navbar-link:hover,html.theme--catppuccin-latte .navbar.is-success .navbar-end .navbar-link.is-active{background-color:#388c26;color:#fff}html.theme--catppuccin-latte .navbar.is-success .navbar-start .navbar-link::after,html.theme--catppuccin-latte .navbar.is-success .navbar-end .navbar-link::after{border-color:#fff}html.theme--catppuccin-latte .navbar.is-success .navbar-item.has-dropdown:focus .navbar-link,html.theme--catppuccin-latte .navbar.is-success .navbar-item.has-dropdown:hover .navbar-link,html.theme--catppuccin-latte .navbar.is-success .navbar-item.has-dropdown.is-active .navbar-link{background-color:#388c26;color:#fff}html.theme--catppuccin-latte .navbar.is-success .navbar-dropdown a.navbar-item.is-active{background-color:#40a02b;color:#fff}}html.theme--catppuccin-latte .navbar.is-warning{background-color:#df8e1d;color:#fff}html.theme--catppuccin-latte .navbar.is-warning .navbar-brand>.navbar-item,html.theme--catppuccin-latte .navbar.is-warning .navbar-brand .navbar-link{color:#fff}html.theme--catppuccin-latte .navbar.is-warning .navbar-brand>a.navbar-item:focus,html.theme--catppuccin-latte .navbar.is-warning .navbar-brand>a.navbar-item:hover,html.theme--catppuccin-latte .navbar.is-warning .navbar-brand>a.navbar-item.is-active,html.theme--catppuccin-latte .navbar.is-warning .navbar-brand .navbar-link:focus,html.theme--catppuccin-latte .navbar.is-warning .navbar-brand .navbar-link:hover,html.theme--catppuccin-latte .navbar.is-warning .navbar-brand .navbar-link.is-active{background-color:#c8801a;color:#fff}html.theme--catppuccin-latte .navbar.is-warning .navbar-brand .navbar-link::after{border-color:#fff}html.theme--catppuccin-latte .navbar.is-warning .navbar-burger{color:#fff}@media screen and (min-width: 1056px){html.theme--catppuccin-latte .navbar.is-warning .navbar-start>.navbar-item,html.theme--catppuccin-latte .navbar.is-warning .navbar-start .navbar-link,html.theme--catppuccin-latte .navbar.is-warning .navbar-end>.navbar-item,html.theme--catppuccin-latte .navbar.is-warning .navbar-end .navbar-link{color:#fff}html.theme--catppuccin-latte .navbar.is-warning .navbar-start>a.navbar-item:focus,html.theme--catppuccin-latte .navbar.is-warning .navbar-start>a.navbar-item:hover,html.theme--catppuccin-latte .navbar.is-warning .navbar-start>a.navbar-item.is-active,html.theme--catppuccin-latte .navbar.is-warning .navbar-start .navbar-link:focus,html.theme--catppuccin-latte .navbar.is-warning .navbar-start .navbar-link:hover,html.theme--catppuccin-latte .navbar.is-warning .navbar-start .navbar-link.is-active,html.theme--catppuccin-latte .navbar.is-warning .navbar-end>a.navbar-item:focus,html.theme--catppuccin-latte .navbar.is-warning .navbar-end>a.navbar-item:hover,html.theme--catppuccin-latte .navbar.is-warning .navbar-end>a.navbar-item.is-active,html.theme--catppuccin-latte .navbar.is-warning .navbar-end .navbar-link:focus,html.theme--catppuccin-latte .navbar.is-warning .navbar-end .navbar-link:hover,html.theme--catppuccin-latte .navbar.is-warning .navbar-end .navbar-link.is-active{background-color:#c8801a;color:#fff}html.theme--catppuccin-latte .navbar.is-warning .navbar-start .navbar-link::after,html.theme--catppuccin-latte .navbar.is-warning .navbar-end .navbar-link::after{border-color:#fff}html.theme--catppuccin-latte .navbar.is-warning .navbar-item.has-dropdown:focus .navbar-link,html.theme--catppuccin-latte .navbar.is-warning .navbar-item.has-dropdown:hover .navbar-link,html.theme--catppuccin-latte .navbar.is-warning .navbar-item.has-dropdown.is-active .navbar-link{background-color:#c8801a;color:#fff}html.theme--catppuccin-latte .navbar.is-warning .navbar-dropdown a.navbar-item.is-active{background-color:#df8e1d;color:#fff}}html.theme--catppuccin-latte .navbar.is-danger{background-color:#d20f39;color:#fff}html.theme--catppuccin-latte .navbar.is-danger .navbar-brand>.navbar-item,html.theme--catppuccin-latte .navbar.is-danger .navbar-brand .navbar-link{color:#fff}html.theme--catppuccin-latte .navbar.is-danger .navbar-brand>a.navbar-item:focus,html.theme--catppuccin-latte .navbar.is-danger .navbar-brand>a.navbar-item:hover,html.theme--catppuccin-latte .navbar.is-danger .navbar-brand>a.navbar-item.is-active,html.theme--catppuccin-latte .navbar.is-danger .navbar-brand .navbar-link:focus,html.theme--catppuccin-latte .navbar.is-danger .navbar-brand .navbar-link:hover,html.theme--catppuccin-latte .navbar.is-danger .navbar-brand .navbar-link.is-active{background-color:#ba0d33;color:#fff}html.theme--catppuccin-latte .navbar.is-danger .navbar-brand .navbar-link::after{border-color:#fff}html.theme--catppuccin-latte .navbar.is-danger .navbar-burger{color:#fff}@media screen and (min-width: 1056px){html.theme--catppuccin-latte .navbar.is-danger .navbar-start>.navbar-item,html.theme--catppuccin-latte .navbar.is-danger .navbar-start .navbar-link,html.theme--catppuccin-latte .navbar.is-danger .navbar-end>.navbar-item,html.theme--catppuccin-latte .navbar.is-danger .navbar-end .navbar-link{color:#fff}html.theme--catppuccin-latte .navbar.is-danger .navbar-start>a.navbar-item:focus,html.theme--catppuccin-latte .navbar.is-danger .navbar-start>a.navbar-item:hover,html.theme--catppuccin-latte .navbar.is-danger .navbar-start>a.navbar-item.is-active,html.theme--catppuccin-latte .navbar.is-danger .navbar-start .navbar-link:focus,html.theme--catppuccin-latte .navbar.is-danger .navbar-start .navbar-link:hover,html.theme--catppuccin-latte .navbar.is-danger .navbar-start .navbar-link.is-active,html.theme--catppuccin-latte .navbar.is-danger .navbar-end>a.navbar-item:focus,html.theme--catppuccin-latte .navbar.is-danger .navbar-end>a.navbar-item:hover,html.theme--catppuccin-latte .navbar.is-danger .navbar-end>a.navbar-item.is-active,html.theme--catppuccin-latte .navbar.is-danger .navbar-end .navbar-link:focus,html.theme--catppuccin-latte .navbar.is-danger .navbar-end .navbar-link:hover,html.theme--catppuccin-latte .navbar.is-danger .navbar-end .navbar-link.is-active{background-color:#ba0d33;color:#fff}html.theme--catppuccin-latte .navbar.is-danger .navbar-start .navbar-link::after,html.theme--catppuccin-latte .navbar.is-danger .navbar-end .navbar-link::after{border-color:#fff}html.theme--catppuccin-latte .navbar.is-danger .navbar-item.has-dropdown:focus .navbar-link,html.theme--catppuccin-latte .navbar.is-danger .navbar-item.has-dropdown:hover .navbar-link,html.theme--catppuccin-latte .navbar.is-danger .navbar-item.has-dropdown.is-active .navbar-link{background-color:#ba0d33;color:#fff}html.theme--catppuccin-latte .navbar.is-danger .navbar-dropdown a.navbar-item.is-active{background-color:#d20f39;color:#fff}}html.theme--catppuccin-latte .navbar>.container{align-items:stretch;display:flex;min-height:4rem;width:100%}html.theme--catppuccin-latte .navbar.has-shadow{box-shadow:0 2px 0 0 #e6e9ef}html.theme--catppuccin-latte .navbar.is-fixed-bottom,html.theme--catppuccin-latte .navbar.is-fixed-top{left:0;position:fixed;right:0;z-index:30}html.theme--catppuccin-latte .navbar.is-fixed-bottom{bottom:0}html.theme--catppuccin-latte .navbar.is-fixed-bottom.has-shadow{box-shadow:0 -2px 0 0 #e6e9ef}html.theme--catppuccin-latte .navbar.is-fixed-top{top:0}html.theme--catppuccin-latte html.has-navbar-fixed-top,html.theme--catppuccin-latte body.has-navbar-fixed-top{padding-top:4rem}html.theme--catppuccin-latte html.has-navbar-fixed-bottom,html.theme--catppuccin-latte body.has-navbar-fixed-bottom{padding-bottom:4rem}html.theme--catppuccin-latte .navbar-brand,html.theme--catppuccin-latte .navbar-tabs{align-items:stretch;display:flex;flex-shrink:0;min-height:4rem}html.theme--catppuccin-latte .navbar-brand a.navbar-item:focus,html.theme--catppuccin-latte .navbar-brand a.navbar-item:hover{background-color:transparent}html.theme--catppuccin-latte .navbar-tabs{-webkit-overflow-scrolling:touch;max-width:100vw;overflow-x:auto;overflow-y:hidden}html.theme--catppuccin-latte .navbar-burger{color:#4c4f69;-moz-appearance:none;-webkit-appearance:none;appearance:none;background:none;border:none;cursor:pointer;display:block;height:4rem;position:relative;width:4rem;margin-left:auto}html.theme--catppuccin-latte .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--catppuccin-latte .navbar-burger span:nth-child(1){top:calc(50% - 6px)}html.theme--catppuccin-latte .navbar-burger span:nth-child(2){top:calc(50% - 1px)}html.theme--catppuccin-latte .navbar-burger span:nth-child(3){top:calc(50% + 4px)}html.theme--catppuccin-latte .navbar-burger:hover{background-color:rgba(0,0,0,0.05)}html.theme--catppuccin-latte .navbar-burger.is-active span:nth-child(1){transform:translateY(5px) rotate(45deg)}html.theme--catppuccin-latte .navbar-burger.is-active span:nth-child(2){opacity:0}html.theme--catppuccin-latte .navbar-burger.is-active span:nth-child(3){transform:translateY(-5px) rotate(-45deg)}html.theme--catppuccin-latte .navbar-menu{display:none}html.theme--catppuccin-latte .navbar-item,html.theme--catppuccin-latte .navbar-link{color:#4c4f69;display:block;line-height:1.5;padding:0.5rem 0.75rem;position:relative}html.theme--catppuccin-latte .navbar-item .icon:only-child,html.theme--catppuccin-latte .navbar-link .icon:only-child{margin-left:-0.25rem;margin-right:-0.25rem}html.theme--catppuccin-latte a.navbar-item,html.theme--catppuccin-latte .navbar-link{cursor:pointer}html.theme--catppuccin-latte a.navbar-item:focus,html.theme--catppuccin-latte a.navbar-item:focus-within,html.theme--catppuccin-latte a.navbar-item:hover,html.theme--catppuccin-latte a.navbar-item.is-active,html.theme--catppuccin-latte .navbar-link:focus,html.theme--catppuccin-latte .navbar-link:focus-within,html.theme--catppuccin-latte .navbar-link:hover,html.theme--catppuccin-latte .navbar-link.is-active{background-color:rgba(0,0,0,0);color:#1e66f5}html.theme--catppuccin-latte .navbar-item{flex-grow:0;flex-shrink:0}html.theme--catppuccin-latte .navbar-item img{max-height:1.75rem}html.theme--catppuccin-latte .navbar-item.has-dropdown{padding:0}html.theme--catppuccin-latte .navbar-item.is-expanded{flex-grow:1;flex-shrink:1}html.theme--catppuccin-latte .navbar-item.is-tab{border-bottom:1px solid transparent;min-height:4rem;padding-bottom:calc(0.5rem - 1px)}html.theme--catppuccin-latte .navbar-item.is-tab:focus,html.theme--catppuccin-latte .navbar-item.is-tab:hover{background-color:rgba(0,0,0,0);border-bottom-color:#1e66f5}html.theme--catppuccin-latte .navbar-item.is-tab.is-active{background-color:rgba(0,0,0,0);border-bottom-color:#1e66f5;border-bottom-style:solid;border-bottom-width:3px;color:#1e66f5;padding-bottom:calc(0.5rem - 3px)}html.theme--catppuccin-latte .navbar-content{flex-grow:1;flex-shrink:1}html.theme--catppuccin-latte .navbar-link:not(.is-arrowless){padding-right:2.5em}html.theme--catppuccin-latte .navbar-link:not(.is-arrowless)::after{border-color:#fff;margin-top:-0.375em;right:1.125em}html.theme--catppuccin-latte .navbar-dropdown{font-size:0.875rem;padding-bottom:0.5rem;padding-top:0.5rem}html.theme--catppuccin-latte .navbar-dropdown .navbar-item{padding-left:1.5rem;padding-right:1.5rem}html.theme--catppuccin-latte .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--catppuccin-latte .navbar>.container{display:block}html.theme--catppuccin-latte .navbar-brand .navbar-item,html.theme--catppuccin-latte .navbar-tabs .navbar-item{align-items:center;display:flex}html.theme--catppuccin-latte .navbar-link::after{display:none}html.theme--catppuccin-latte .navbar-menu{background-color:#1e66f5;box-shadow:0 8px 16px rgba(10,10,10,0.1);padding:0.5rem 0}html.theme--catppuccin-latte .navbar-menu.is-active{display:block}html.theme--catppuccin-latte .navbar.is-fixed-bottom-touch,html.theme--catppuccin-latte .navbar.is-fixed-top-touch{left:0;position:fixed;right:0;z-index:30}html.theme--catppuccin-latte .navbar.is-fixed-bottom-touch{bottom:0}html.theme--catppuccin-latte .navbar.is-fixed-bottom-touch.has-shadow{box-shadow:0 -2px 3px rgba(10,10,10,0.1)}html.theme--catppuccin-latte .navbar.is-fixed-top-touch{top:0}html.theme--catppuccin-latte .navbar.is-fixed-top .navbar-menu,html.theme--catppuccin-latte .navbar.is-fixed-top-touch .navbar-menu{-webkit-overflow-scrolling:touch;max-height:calc(100vh - 4rem);overflow:auto}html.theme--catppuccin-latte html.has-navbar-fixed-top-touch,html.theme--catppuccin-latte body.has-navbar-fixed-top-touch{padding-top:4rem}html.theme--catppuccin-latte html.has-navbar-fixed-bottom-touch,html.theme--catppuccin-latte body.has-navbar-fixed-bottom-touch{padding-bottom:4rem}}@media screen and (min-width: 1056px){html.theme--catppuccin-latte .navbar,html.theme--catppuccin-latte .navbar-menu,html.theme--catppuccin-latte .navbar-start,html.theme--catppuccin-latte .navbar-end{align-items:stretch;display:flex}html.theme--catppuccin-latte .navbar{min-height:4rem}html.theme--catppuccin-latte .navbar.is-spaced{padding:1rem 2rem}html.theme--catppuccin-latte .navbar.is-spaced .navbar-start,html.theme--catppuccin-latte .navbar.is-spaced .navbar-end{align-items:center}html.theme--catppuccin-latte .navbar.is-spaced a.navbar-item,html.theme--catppuccin-latte .navbar.is-spaced .navbar-link{border-radius:.4em}html.theme--catppuccin-latte .navbar.is-transparent a.navbar-item:focus,html.theme--catppuccin-latte .navbar.is-transparent a.navbar-item:hover,html.theme--catppuccin-latte .navbar.is-transparent a.navbar-item.is-active,html.theme--catppuccin-latte .navbar.is-transparent .navbar-link:focus,html.theme--catppuccin-latte .navbar.is-transparent .navbar-link:hover,html.theme--catppuccin-latte .navbar.is-transparent .navbar-link.is-active{background-color:transparent !important}html.theme--catppuccin-latte .navbar.is-transparent .navbar-item.has-dropdown.is-active .navbar-link,html.theme--catppuccin-latte .navbar.is-transparent .navbar-item.has-dropdown.is-hoverable:focus .navbar-link,html.theme--catppuccin-latte .navbar.is-transparent .navbar-item.has-dropdown.is-hoverable:focus-within .navbar-link,html.theme--catppuccin-latte .navbar.is-transparent .navbar-item.has-dropdown.is-hoverable:hover .navbar-link{background-color:transparent !important}html.theme--catppuccin-latte .navbar.is-transparent .navbar-dropdown a.navbar-item:focus,html.theme--catppuccin-latte .navbar.is-transparent .navbar-dropdown a.navbar-item:hover{background-color:rgba(0,0,0,0);color:#8c8fa1}html.theme--catppuccin-latte .navbar.is-transparent .navbar-dropdown a.navbar-item.is-active{background-color:rgba(0,0,0,0);color:#1e66f5}html.theme--catppuccin-latte .navbar-burger{display:none}html.theme--catppuccin-latte .navbar-item,html.theme--catppuccin-latte .navbar-link{align-items:center;display:flex}html.theme--catppuccin-latte .navbar-item.has-dropdown{align-items:stretch}html.theme--catppuccin-latte .navbar-item.has-dropdown-up .navbar-link::after{transform:rotate(135deg) translate(0.25em, -0.25em)}html.theme--catppuccin-latte .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--catppuccin-latte .navbar-item.is-active .navbar-dropdown,html.theme--catppuccin-latte .navbar-item.is-hoverable:focus .navbar-dropdown,html.theme--catppuccin-latte .navbar-item.is-hoverable:focus-within .navbar-dropdown,html.theme--catppuccin-latte .navbar-item.is-hoverable:hover .navbar-dropdown{display:block}.navbar.is-spaced html.theme--catppuccin-latte .navbar-item.is-active .navbar-dropdown,html.theme--catppuccin-latte .navbar-item.is-active .navbar-dropdown.is-boxed,.navbar.is-spaced html.theme--catppuccin-latte .navbar-item.is-hoverable:focus .navbar-dropdown,html.theme--catppuccin-latte .navbar-item.is-hoverable:focus .navbar-dropdown.is-boxed,.navbar.is-spaced html.theme--catppuccin-latte .navbar-item.is-hoverable:focus-within .navbar-dropdown,html.theme--catppuccin-latte .navbar-item.is-hoverable:focus-within .navbar-dropdown.is-boxed,.navbar.is-spaced html.theme--catppuccin-latte .navbar-item.is-hoverable:hover .navbar-dropdown,html.theme--catppuccin-latte .navbar-item.is-hoverable:hover .navbar-dropdown.is-boxed{opacity:1;pointer-events:auto;transform:translateY(0)}html.theme--catppuccin-latte .navbar-menu{flex-grow:1;flex-shrink:0}html.theme--catppuccin-latte .navbar-start{justify-content:flex-start;margin-right:auto}html.theme--catppuccin-latte .navbar-end{justify-content:flex-end;margin-left:auto}html.theme--catppuccin-latte .navbar-dropdown{background-color:#1e66f5;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--catppuccin-latte .navbar-dropdown .navbar-item{padding:0.375rem 1rem;white-space:nowrap}html.theme--catppuccin-latte .navbar-dropdown a.navbar-item{padding-right:3rem}html.theme--catppuccin-latte .navbar-dropdown a.navbar-item:focus,html.theme--catppuccin-latte .navbar-dropdown a.navbar-item:hover{background-color:rgba(0,0,0,0);color:#8c8fa1}html.theme--catppuccin-latte .navbar-dropdown a.navbar-item.is-active{background-color:rgba(0,0,0,0);color:#1e66f5}.navbar.is-spaced html.theme--catppuccin-latte .navbar-dropdown,html.theme--catppuccin-latte .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--catppuccin-latte .navbar-dropdown.is-right{left:auto;right:0}html.theme--catppuccin-latte .navbar-divider{display:block}html.theme--catppuccin-latte .navbar>.container .navbar-brand,html.theme--catppuccin-latte .container>.navbar .navbar-brand{margin-left:-.75rem}html.theme--catppuccin-latte .navbar>.container .navbar-menu,html.theme--catppuccin-latte .container>.navbar .navbar-menu{margin-right:-.75rem}html.theme--catppuccin-latte .navbar.is-fixed-bottom-desktop,html.theme--catppuccin-latte .navbar.is-fixed-top-desktop{left:0;position:fixed;right:0;z-index:30}html.theme--catppuccin-latte .navbar.is-fixed-bottom-desktop{bottom:0}html.theme--catppuccin-latte .navbar.is-fixed-bottom-desktop.has-shadow{box-shadow:0 -2px 3px rgba(10,10,10,0.1)}html.theme--catppuccin-latte .navbar.is-fixed-top-desktop{top:0}html.theme--catppuccin-latte html.has-navbar-fixed-top-desktop,html.theme--catppuccin-latte body.has-navbar-fixed-top-desktop{padding-top:4rem}html.theme--catppuccin-latte html.has-navbar-fixed-bottom-desktop,html.theme--catppuccin-latte body.has-navbar-fixed-bottom-desktop{padding-bottom:4rem}html.theme--catppuccin-latte html.has-spaced-navbar-fixed-top,html.theme--catppuccin-latte body.has-spaced-navbar-fixed-top{padding-top:6rem}html.theme--catppuccin-latte html.has-spaced-navbar-fixed-bottom,html.theme--catppuccin-latte body.has-spaced-navbar-fixed-bottom{padding-bottom:6rem}html.theme--catppuccin-latte a.navbar-item.is-active,html.theme--catppuccin-latte .navbar-link.is-active{color:#1e66f5}html.theme--catppuccin-latte a.navbar-item.is-active:not(:focus):not(:hover),html.theme--catppuccin-latte .navbar-link.is-active:not(:focus):not(:hover){background-color:rgba(0,0,0,0)}html.theme--catppuccin-latte .navbar-item.has-dropdown:focus .navbar-link,html.theme--catppuccin-latte .navbar-item.has-dropdown:hover .navbar-link,html.theme--catppuccin-latte .navbar-item.has-dropdown.is-active .navbar-link{background-color:rgba(0,0,0,0)}}html.theme--catppuccin-latte .hero.is-fullheight-with-navbar{min-height:calc(100vh - 4rem)}html.theme--catppuccin-latte .pagination{font-size:1rem;margin:-.25rem}html.theme--catppuccin-latte .pagination.is-small,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.pagination{font-size:.75rem}html.theme--catppuccin-latte .pagination.is-medium{font-size:1.25rem}html.theme--catppuccin-latte .pagination.is-large{font-size:1.5rem}html.theme--catppuccin-latte .pagination.is-rounded .pagination-previous,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.pagination .pagination-previous,html.theme--catppuccin-latte .pagination.is-rounded .pagination-next,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.pagination .pagination-next{padding-left:1em;padding-right:1em;border-radius:9999px}html.theme--catppuccin-latte .pagination.is-rounded .pagination-link,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.pagination .pagination-link{border-radius:9999px}html.theme--catppuccin-latte .pagination,html.theme--catppuccin-latte .pagination-list{align-items:center;display:flex;justify-content:center;text-align:center}html.theme--catppuccin-latte .pagination-previous,html.theme--catppuccin-latte .pagination-next,html.theme--catppuccin-latte .pagination-link,html.theme--catppuccin-latte .pagination-ellipsis{font-size:1em;justify-content:center;margin:.25rem;padding-left:.5em;padding-right:.5em;text-align:center}html.theme--catppuccin-latte .pagination-previous,html.theme--catppuccin-latte .pagination-next,html.theme--catppuccin-latte .pagination-link{border-color:#acb0be;color:#1e66f5;min-width:2.5em}html.theme--catppuccin-latte .pagination-previous:hover,html.theme--catppuccin-latte .pagination-next:hover,html.theme--catppuccin-latte .pagination-link:hover{border-color:#9ca0b0;color:#04a5e5}html.theme--catppuccin-latte .pagination-previous:focus,html.theme--catppuccin-latte .pagination-next:focus,html.theme--catppuccin-latte .pagination-link:focus{border-color:#9ca0b0}html.theme--catppuccin-latte .pagination-previous:active,html.theme--catppuccin-latte .pagination-next:active,html.theme--catppuccin-latte .pagination-link:active{box-shadow:inset 0 1px 2px rgba(10,10,10,0.2)}html.theme--catppuccin-latte .pagination-previous[disabled],html.theme--catppuccin-latte .pagination-previous.is-disabled,html.theme--catppuccin-latte .pagination-next[disabled],html.theme--catppuccin-latte .pagination-next.is-disabled,html.theme--catppuccin-latte .pagination-link[disabled],html.theme--catppuccin-latte .pagination-link.is-disabled{background-color:#acb0be;border-color:#acb0be;box-shadow:none;color:#616587;opacity:0.5}html.theme--catppuccin-latte .pagination-previous,html.theme--catppuccin-latte .pagination-next{padding-left:.75em;padding-right:.75em;white-space:nowrap}html.theme--catppuccin-latte .pagination-link.is-current{background-color:#1e66f5;border-color:#1e66f5;color:#fff}html.theme--catppuccin-latte .pagination-ellipsis{color:#9ca0b0;pointer-events:none}html.theme--catppuccin-latte .pagination-list{flex-wrap:wrap}html.theme--catppuccin-latte .pagination-list li{list-style:none}@media screen and (max-width: 768px){html.theme--catppuccin-latte .pagination{flex-wrap:wrap}html.theme--catppuccin-latte .pagination-previous,html.theme--catppuccin-latte .pagination-next{flex-grow:1;flex-shrink:1}html.theme--catppuccin-latte .pagination-list li{flex-grow:1;flex-shrink:1}}@media screen and (min-width: 769px),print{html.theme--catppuccin-latte .pagination-list{flex-grow:1;flex-shrink:1;justify-content:flex-start;order:1}html.theme--catppuccin-latte .pagination-previous,html.theme--catppuccin-latte .pagination-next,html.theme--catppuccin-latte .pagination-link,html.theme--catppuccin-latte .pagination-ellipsis{margin-bottom:0;margin-top:0}html.theme--catppuccin-latte .pagination-previous{order:2}html.theme--catppuccin-latte .pagination-next{order:3}html.theme--catppuccin-latte .pagination{justify-content:space-between;margin-bottom:0;margin-top:0}html.theme--catppuccin-latte .pagination.is-centered .pagination-previous{order:1}html.theme--catppuccin-latte .pagination.is-centered .pagination-list{justify-content:center;order:2}html.theme--catppuccin-latte .pagination.is-centered .pagination-next{order:3}html.theme--catppuccin-latte .pagination.is-right .pagination-previous{order:1}html.theme--catppuccin-latte .pagination.is-right .pagination-next{order:2}html.theme--catppuccin-latte .pagination.is-right .pagination-list{justify-content:flex-end;order:3}}html.theme--catppuccin-latte .panel{border-radius:8px;box-shadow:#171717;font-size:1rem}html.theme--catppuccin-latte .panel:not(:last-child){margin-bottom:1.5rem}html.theme--catppuccin-latte .panel.is-white .panel-heading{background-color:#fff;color:#0a0a0a}html.theme--catppuccin-latte .panel.is-white .panel-tabs a.is-active{border-bottom-color:#fff}html.theme--catppuccin-latte .panel.is-white .panel-block.is-active .panel-icon{color:#fff}html.theme--catppuccin-latte .panel.is-black .panel-heading{background-color:#0a0a0a;color:#fff}html.theme--catppuccin-latte .panel.is-black .panel-tabs a.is-active{border-bottom-color:#0a0a0a}html.theme--catppuccin-latte .panel.is-black .panel-block.is-active .panel-icon{color:#0a0a0a}html.theme--catppuccin-latte .panel.is-light .panel-heading{background-color:#f5f5f5;color:rgba(0,0,0,0.7)}html.theme--catppuccin-latte .panel.is-light .panel-tabs a.is-active{border-bottom-color:#f5f5f5}html.theme--catppuccin-latte .panel.is-light .panel-block.is-active .panel-icon{color:#f5f5f5}html.theme--catppuccin-latte .panel.is-dark .panel-heading,html.theme--catppuccin-latte .content kbd.panel .panel-heading{background-color:#ccd0da;color:rgba(0,0,0,0.7)}html.theme--catppuccin-latte .panel.is-dark .panel-tabs a.is-active,html.theme--catppuccin-latte .content kbd.panel .panel-tabs a.is-active{border-bottom-color:#ccd0da}html.theme--catppuccin-latte .panel.is-dark .panel-block.is-active .panel-icon,html.theme--catppuccin-latte .content kbd.panel .panel-block.is-active .panel-icon{color:#ccd0da}html.theme--catppuccin-latte .panel.is-primary .panel-heading,html.theme--catppuccin-latte .docstring>section>a.panel.docs-sourcelink .panel-heading{background-color:#1e66f5;color:#fff}html.theme--catppuccin-latte .panel.is-primary .panel-tabs a.is-active,html.theme--catppuccin-latte .docstring>section>a.panel.docs-sourcelink .panel-tabs a.is-active{border-bottom-color:#1e66f5}html.theme--catppuccin-latte .panel.is-primary .panel-block.is-active .panel-icon,html.theme--catppuccin-latte .docstring>section>a.panel.docs-sourcelink .panel-block.is-active .panel-icon{color:#1e66f5}html.theme--catppuccin-latte .panel.is-link .panel-heading{background-color:#1e66f5;color:#fff}html.theme--catppuccin-latte .panel.is-link .panel-tabs a.is-active{border-bottom-color:#1e66f5}html.theme--catppuccin-latte .panel.is-link .panel-block.is-active .panel-icon{color:#1e66f5}html.theme--catppuccin-latte .panel.is-info .panel-heading{background-color:#179299;color:#fff}html.theme--catppuccin-latte .panel.is-info .panel-tabs a.is-active{border-bottom-color:#179299}html.theme--catppuccin-latte .panel.is-info .panel-block.is-active .panel-icon{color:#179299}html.theme--catppuccin-latte .panel.is-success .panel-heading{background-color:#40a02b;color:#fff}html.theme--catppuccin-latte .panel.is-success .panel-tabs a.is-active{border-bottom-color:#40a02b}html.theme--catppuccin-latte .panel.is-success .panel-block.is-active .panel-icon{color:#40a02b}html.theme--catppuccin-latte .panel.is-warning .panel-heading{background-color:#df8e1d;color:#fff}html.theme--catppuccin-latte .panel.is-warning .panel-tabs a.is-active{border-bottom-color:#df8e1d}html.theme--catppuccin-latte .panel.is-warning .panel-block.is-active .panel-icon{color:#df8e1d}html.theme--catppuccin-latte .panel.is-danger .panel-heading{background-color:#d20f39;color:#fff}html.theme--catppuccin-latte .panel.is-danger .panel-tabs a.is-active{border-bottom-color:#d20f39}html.theme--catppuccin-latte .panel.is-danger .panel-block.is-active .panel-icon{color:#d20f39}html.theme--catppuccin-latte .panel-tabs:not(:last-child),html.theme--catppuccin-latte .panel-block:not(:last-child){border-bottom:1px solid #ededed}html.theme--catppuccin-latte .panel-heading{background-color:#bcc0cc;border-radius:8px 8px 0 0;color:#41445a;font-size:1.25em;font-weight:700;line-height:1.25;padding:0.75em 1em}html.theme--catppuccin-latte .panel-tabs{align-items:flex-end;display:flex;font-size:.875em;justify-content:center}html.theme--catppuccin-latte .panel-tabs a{border-bottom:1px solid #acb0be;margin-bottom:-1px;padding:0.5em}html.theme--catppuccin-latte .panel-tabs a.is-active{border-bottom-color:#bcc0cc;color:#0b57ef}html.theme--catppuccin-latte .panel-list a{color:#4c4f69}html.theme--catppuccin-latte .panel-list a:hover{color:#1e66f5}html.theme--catppuccin-latte .panel-block{align-items:center;color:#41445a;display:flex;justify-content:flex-start;padding:0.5em 0.75em}html.theme--catppuccin-latte .panel-block input[type="checkbox"]{margin-right:.75em}html.theme--catppuccin-latte .panel-block>.control{flex-grow:1;flex-shrink:1;width:100%}html.theme--catppuccin-latte .panel-block.is-wrapped{flex-wrap:wrap}html.theme--catppuccin-latte .panel-block.is-active{border-left-color:#1e66f5;color:#0b57ef}html.theme--catppuccin-latte .panel-block.is-active .panel-icon{color:#1e66f5}html.theme--catppuccin-latte .panel-block:last-child{border-bottom-left-radius:8px;border-bottom-right-radius:8px}html.theme--catppuccin-latte a.panel-block,html.theme--catppuccin-latte label.panel-block{cursor:pointer}html.theme--catppuccin-latte a.panel-block:hover,html.theme--catppuccin-latte label.panel-block:hover{background-color:#e6e9ef}html.theme--catppuccin-latte .panel-icon{display:inline-block;font-size:14px;height:1em;line-height:1em;text-align:center;vertical-align:top;width:1em;color:#616587;margin-right:.75em}html.theme--catppuccin-latte .panel-icon .fa{font-size:inherit;line-height:inherit}html.theme--catppuccin-latte .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}html.theme--catppuccin-latte .tabs a{align-items:center;border-bottom-color:#acb0be;border-bottom-style:solid;border-bottom-width:1px;color:#4c4f69;display:flex;justify-content:center;margin-bottom:-1px;padding:0.5em 1em;vertical-align:top}html.theme--catppuccin-latte .tabs a:hover{border-bottom-color:#41445a;color:#41445a}html.theme--catppuccin-latte .tabs li{display:block}html.theme--catppuccin-latte .tabs li.is-active a{border-bottom-color:#1e66f5;color:#1e66f5}html.theme--catppuccin-latte .tabs ul{align-items:center;border-bottom-color:#acb0be;border-bottom-style:solid;border-bottom-width:1px;display:flex;flex-grow:1;flex-shrink:0;justify-content:flex-start}html.theme--catppuccin-latte .tabs ul.is-left{padding-right:0.75em}html.theme--catppuccin-latte .tabs ul.is-center{flex:none;justify-content:center;padding-left:0.75em;padding-right:0.75em}html.theme--catppuccin-latte .tabs ul.is-right{justify-content:flex-end;padding-left:0.75em}html.theme--catppuccin-latte .tabs .icon:first-child{margin-right:.5em}html.theme--catppuccin-latte .tabs .icon:last-child{margin-left:.5em}html.theme--catppuccin-latte .tabs.is-centered ul{justify-content:center}html.theme--catppuccin-latte .tabs.is-right ul{justify-content:flex-end}html.theme--catppuccin-latte .tabs.is-boxed a{border:1px solid transparent;border-radius:.4em .4em 0 0}html.theme--catppuccin-latte .tabs.is-boxed a:hover{background-color:#e6e9ef;border-bottom-color:#acb0be}html.theme--catppuccin-latte .tabs.is-boxed li.is-active a{background-color:#fff;border-color:#acb0be;border-bottom-color:rgba(0,0,0,0) !important}html.theme--catppuccin-latte .tabs.is-fullwidth li{flex-grow:1;flex-shrink:0}html.theme--catppuccin-latte .tabs.is-toggle a{border-color:#acb0be;border-style:solid;border-width:1px;margin-bottom:0;position:relative}html.theme--catppuccin-latte .tabs.is-toggle a:hover{background-color:#e6e9ef;border-color:#9ca0b0;z-index:2}html.theme--catppuccin-latte .tabs.is-toggle li+li{margin-left:-1px}html.theme--catppuccin-latte .tabs.is-toggle li:first-child a{border-top-left-radius:.4em;border-bottom-left-radius:.4em}html.theme--catppuccin-latte .tabs.is-toggle li:last-child a{border-top-right-radius:.4em;border-bottom-right-radius:.4em}html.theme--catppuccin-latte .tabs.is-toggle li.is-active a{background-color:#1e66f5;border-color:#1e66f5;color:#fff;z-index:1}html.theme--catppuccin-latte .tabs.is-toggle ul{border-bottom:none}html.theme--catppuccin-latte .tabs.is-toggle.is-toggle-rounded li:first-child a{border-bottom-left-radius:9999px;border-top-left-radius:9999px;padding-left:1.25em}html.theme--catppuccin-latte .tabs.is-toggle.is-toggle-rounded li:last-child a{border-bottom-right-radius:9999px;border-top-right-radius:9999px;padding-right:1.25em}html.theme--catppuccin-latte .tabs.is-small,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.tabs{font-size:.75rem}html.theme--catppuccin-latte .tabs.is-medium{font-size:1.25rem}html.theme--catppuccin-latte .tabs.is-large{font-size:1.5rem}html.theme--catppuccin-latte .column{display:block;flex-basis:0;flex-grow:1;flex-shrink:1;padding:.75rem}.columns.is-mobile>html.theme--catppuccin-latte .column.is-narrow{flex:none;width:unset}.columns.is-mobile>html.theme--catppuccin-latte .column.is-full{flex:none;width:100%}.columns.is-mobile>html.theme--catppuccin-latte .column.is-three-quarters{flex:none;width:75%}.columns.is-mobile>html.theme--catppuccin-latte .column.is-two-thirds{flex:none;width:66.6666%}.columns.is-mobile>html.theme--catppuccin-latte .column.is-half{flex:none;width:50%}.columns.is-mobile>html.theme--catppuccin-latte .column.is-one-third{flex:none;width:33.3333%}.columns.is-mobile>html.theme--catppuccin-latte .column.is-one-quarter{flex:none;width:25%}.columns.is-mobile>html.theme--catppuccin-latte .column.is-one-fifth{flex:none;width:20%}.columns.is-mobile>html.theme--catppuccin-latte .column.is-two-fifths{flex:none;width:40%}.columns.is-mobile>html.theme--catppuccin-latte .column.is-three-fifths{flex:none;width:60%}.columns.is-mobile>html.theme--catppuccin-latte .column.is-four-fifths{flex:none;width:80%}.columns.is-mobile>html.theme--catppuccin-latte .column.is-offset-three-quarters{margin-left:75%}.columns.is-mobile>html.theme--catppuccin-latte .column.is-offset-two-thirds{margin-left:66.6666%}.columns.is-mobile>html.theme--catppuccin-latte .column.is-offset-half{margin-left:50%}.columns.is-mobile>html.theme--catppuccin-latte .column.is-offset-one-third{margin-left:33.3333%}.columns.is-mobile>html.theme--catppuccin-latte .column.is-offset-one-quarter{margin-left:25%}.columns.is-mobile>html.theme--catppuccin-latte .column.is-offset-one-fifth{margin-left:20%}.columns.is-mobile>html.theme--catppuccin-latte .column.is-offset-two-fifths{margin-left:40%}.columns.is-mobile>html.theme--catppuccin-latte .column.is-offset-three-fifths{margin-left:60%}.columns.is-mobile>html.theme--catppuccin-latte .column.is-offset-four-fifths{margin-left:80%}.columns.is-mobile>html.theme--catppuccin-latte .column.is-0{flex:none;width:0%}.columns.is-mobile>html.theme--catppuccin-latte .column.is-offset-0{margin-left:0%}.columns.is-mobile>html.theme--catppuccin-latte .column.is-1{flex:none;width:8.33333337%}.columns.is-mobile>html.theme--catppuccin-latte .column.is-offset-1{margin-left:8.33333337%}.columns.is-mobile>html.theme--catppuccin-latte .column.is-2{flex:none;width:16.66666674%}.columns.is-mobile>html.theme--catppuccin-latte .column.is-offset-2{margin-left:16.66666674%}.columns.is-mobile>html.theme--catppuccin-latte .column.is-3{flex:none;width:25%}.columns.is-mobile>html.theme--catppuccin-latte .column.is-offset-3{margin-left:25%}.columns.is-mobile>html.theme--catppuccin-latte .column.is-4{flex:none;width:33.33333337%}.columns.is-mobile>html.theme--catppuccin-latte .column.is-offset-4{margin-left:33.33333337%}.columns.is-mobile>html.theme--catppuccin-latte .column.is-5{flex:none;width:41.66666674%}.columns.is-mobile>html.theme--catppuccin-latte .column.is-offset-5{margin-left:41.66666674%}.columns.is-mobile>html.theme--catppuccin-latte .column.is-6{flex:none;width:50%}.columns.is-mobile>html.theme--catppuccin-latte .column.is-offset-6{margin-left:50%}.columns.is-mobile>html.theme--catppuccin-latte .column.is-7{flex:none;width:58.33333337%}.columns.is-mobile>html.theme--catppuccin-latte .column.is-offset-7{margin-left:58.33333337%}.columns.is-mobile>html.theme--catppuccin-latte .column.is-8{flex:none;width:66.66666674%}.columns.is-mobile>html.theme--catppuccin-latte .column.is-offset-8{margin-left:66.66666674%}.columns.is-mobile>html.theme--catppuccin-latte .column.is-9{flex:none;width:75%}.columns.is-mobile>html.theme--catppuccin-latte .column.is-offset-9{margin-left:75%}.columns.is-mobile>html.theme--catppuccin-latte .column.is-10{flex:none;width:83.33333337%}.columns.is-mobile>html.theme--catppuccin-latte .column.is-offset-10{margin-left:83.33333337%}.columns.is-mobile>html.theme--catppuccin-latte .column.is-11{flex:none;width:91.66666674%}.columns.is-mobile>html.theme--catppuccin-latte .column.is-offset-11{margin-left:91.66666674%}.columns.is-mobile>html.theme--catppuccin-latte .column.is-12{flex:none;width:100%}.columns.is-mobile>html.theme--catppuccin-latte .column.is-offset-12{margin-left:100%}@media screen and (max-width: 768px){html.theme--catppuccin-latte .column.is-narrow-mobile{flex:none;width:unset}html.theme--catppuccin-latte .column.is-full-mobile{flex:none;width:100%}html.theme--catppuccin-latte .column.is-three-quarters-mobile{flex:none;width:75%}html.theme--catppuccin-latte .column.is-two-thirds-mobile{flex:none;width:66.6666%}html.theme--catppuccin-latte .column.is-half-mobile{flex:none;width:50%}html.theme--catppuccin-latte .column.is-one-third-mobile{flex:none;width:33.3333%}html.theme--catppuccin-latte .column.is-one-quarter-mobile{flex:none;width:25%}html.theme--catppuccin-latte .column.is-one-fifth-mobile{flex:none;width:20%}html.theme--catppuccin-latte .column.is-two-fifths-mobile{flex:none;width:40%}html.theme--catppuccin-latte .column.is-three-fifths-mobile{flex:none;width:60%}html.theme--catppuccin-latte .column.is-four-fifths-mobile{flex:none;width:80%}html.theme--catppuccin-latte .column.is-offset-three-quarters-mobile{margin-left:75%}html.theme--catppuccin-latte .column.is-offset-two-thirds-mobile{margin-left:66.6666%}html.theme--catppuccin-latte .column.is-offset-half-mobile{margin-left:50%}html.theme--catppuccin-latte .column.is-offset-one-third-mobile{margin-left:33.3333%}html.theme--catppuccin-latte .column.is-offset-one-quarter-mobile{margin-left:25%}html.theme--catppuccin-latte .column.is-offset-one-fifth-mobile{margin-left:20%}html.theme--catppuccin-latte .column.is-offset-two-fifths-mobile{margin-left:40%}html.theme--catppuccin-latte .column.is-offset-three-fifths-mobile{margin-left:60%}html.theme--catppuccin-latte .column.is-offset-four-fifths-mobile{margin-left:80%}html.theme--catppuccin-latte .column.is-0-mobile{flex:none;width:0%}html.theme--catppuccin-latte .column.is-offset-0-mobile{margin-left:0%}html.theme--catppuccin-latte .column.is-1-mobile{flex:none;width:8.33333337%}html.theme--catppuccin-latte .column.is-offset-1-mobile{margin-left:8.33333337%}html.theme--catppuccin-latte .column.is-2-mobile{flex:none;width:16.66666674%}html.theme--catppuccin-latte .column.is-offset-2-mobile{margin-left:16.66666674%}html.theme--catppuccin-latte .column.is-3-mobile{flex:none;width:25%}html.theme--catppuccin-latte .column.is-offset-3-mobile{margin-left:25%}html.theme--catppuccin-latte .column.is-4-mobile{flex:none;width:33.33333337%}html.theme--catppuccin-latte .column.is-offset-4-mobile{margin-left:33.33333337%}html.theme--catppuccin-latte .column.is-5-mobile{flex:none;width:41.66666674%}html.theme--catppuccin-latte .column.is-offset-5-mobile{margin-left:41.66666674%}html.theme--catppuccin-latte .column.is-6-mobile{flex:none;width:50%}html.theme--catppuccin-latte .column.is-offset-6-mobile{margin-left:50%}html.theme--catppuccin-latte .column.is-7-mobile{flex:none;width:58.33333337%}html.theme--catppuccin-latte .column.is-offset-7-mobile{margin-left:58.33333337%}html.theme--catppuccin-latte .column.is-8-mobile{flex:none;width:66.66666674%}html.theme--catppuccin-latte .column.is-offset-8-mobile{margin-left:66.66666674%}html.theme--catppuccin-latte .column.is-9-mobile{flex:none;width:75%}html.theme--catppuccin-latte .column.is-offset-9-mobile{margin-left:75%}html.theme--catppuccin-latte .column.is-10-mobile{flex:none;width:83.33333337%}html.theme--catppuccin-latte .column.is-offset-10-mobile{margin-left:83.33333337%}html.theme--catppuccin-latte .column.is-11-mobile{flex:none;width:91.66666674%}html.theme--catppuccin-latte .column.is-offset-11-mobile{margin-left:91.66666674%}html.theme--catppuccin-latte .column.is-12-mobile{flex:none;width:100%}html.theme--catppuccin-latte .column.is-offset-12-mobile{margin-left:100%}}@media screen and (min-width: 769px),print{html.theme--catppuccin-latte .column.is-narrow,html.theme--catppuccin-latte .column.is-narrow-tablet{flex:none;width:unset}html.theme--catppuccin-latte .column.is-full,html.theme--catppuccin-latte .column.is-full-tablet{flex:none;width:100%}html.theme--catppuccin-latte .column.is-three-quarters,html.theme--catppuccin-latte .column.is-three-quarters-tablet{flex:none;width:75%}html.theme--catppuccin-latte .column.is-two-thirds,html.theme--catppuccin-latte .column.is-two-thirds-tablet{flex:none;width:66.6666%}html.theme--catppuccin-latte .column.is-half,html.theme--catppuccin-latte .column.is-half-tablet{flex:none;width:50%}html.theme--catppuccin-latte .column.is-one-third,html.theme--catppuccin-latte .column.is-one-third-tablet{flex:none;width:33.3333%}html.theme--catppuccin-latte .column.is-one-quarter,html.theme--catppuccin-latte .column.is-one-quarter-tablet{flex:none;width:25%}html.theme--catppuccin-latte .column.is-one-fifth,html.theme--catppuccin-latte .column.is-one-fifth-tablet{flex:none;width:20%}html.theme--catppuccin-latte .column.is-two-fifths,html.theme--catppuccin-latte .column.is-two-fifths-tablet{flex:none;width:40%}html.theme--catppuccin-latte .column.is-three-fifths,html.theme--catppuccin-latte .column.is-three-fifths-tablet{flex:none;width:60%}html.theme--catppuccin-latte .column.is-four-fifths,html.theme--catppuccin-latte .column.is-four-fifths-tablet{flex:none;width:80%}html.theme--catppuccin-latte .column.is-offset-three-quarters,html.theme--catppuccin-latte .column.is-offset-three-quarters-tablet{margin-left:75%}html.theme--catppuccin-latte .column.is-offset-two-thirds,html.theme--catppuccin-latte .column.is-offset-two-thirds-tablet{margin-left:66.6666%}html.theme--catppuccin-latte .column.is-offset-half,html.theme--catppuccin-latte .column.is-offset-half-tablet{margin-left:50%}html.theme--catppuccin-latte .column.is-offset-one-third,html.theme--catppuccin-latte .column.is-offset-one-third-tablet{margin-left:33.3333%}html.theme--catppuccin-latte .column.is-offset-one-quarter,html.theme--catppuccin-latte .column.is-offset-one-quarter-tablet{margin-left:25%}html.theme--catppuccin-latte .column.is-offset-one-fifth,html.theme--catppuccin-latte .column.is-offset-one-fifth-tablet{margin-left:20%}html.theme--catppuccin-latte .column.is-offset-two-fifths,html.theme--catppuccin-latte .column.is-offset-two-fifths-tablet{margin-left:40%}html.theme--catppuccin-latte .column.is-offset-three-fifths,html.theme--catppuccin-latte .column.is-offset-three-fifths-tablet{margin-left:60%}html.theme--catppuccin-latte .column.is-offset-four-fifths,html.theme--catppuccin-latte .column.is-offset-four-fifths-tablet{margin-left:80%}html.theme--catppuccin-latte .column.is-0,html.theme--catppuccin-latte .column.is-0-tablet{flex:none;width:0%}html.theme--catppuccin-latte .column.is-offset-0,html.theme--catppuccin-latte .column.is-offset-0-tablet{margin-left:0%}html.theme--catppuccin-latte .column.is-1,html.theme--catppuccin-latte .column.is-1-tablet{flex:none;width:8.33333337%}html.theme--catppuccin-latte .column.is-offset-1,html.theme--catppuccin-latte .column.is-offset-1-tablet{margin-left:8.33333337%}html.theme--catppuccin-latte .column.is-2,html.theme--catppuccin-latte .column.is-2-tablet{flex:none;width:16.66666674%}html.theme--catppuccin-latte .column.is-offset-2,html.theme--catppuccin-latte .column.is-offset-2-tablet{margin-left:16.66666674%}html.theme--catppuccin-latte .column.is-3,html.theme--catppuccin-latte .column.is-3-tablet{flex:none;width:25%}html.theme--catppuccin-latte .column.is-offset-3,html.theme--catppuccin-latte .column.is-offset-3-tablet{margin-left:25%}html.theme--catppuccin-latte .column.is-4,html.theme--catppuccin-latte .column.is-4-tablet{flex:none;width:33.33333337%}html.theme--catppuccin-latte .column.is-offset-4,html.theme--catppuccin-latte .column.is-offset-4-tablet{margin-left:33.33333337%}html.theme--catppuccin-latte .column.is-5,html.theme--catppuccin-latte .column.is-5-tablet{flex:none;width:41.66666674%}html.theme--catppuccin-latte .column.is-offset-5,html.theme--catppuccin-latte .column.is-offset-5-tablet{margin-left:41.66666674%}html.theme--catppuccin-latte .column.is-6,html.theme--catppuccin-latte .column.is-6-tablet{flex:none;width:50%}html.theme--catppuccin-latte .column.is-offset-6,html.theme--catppuccin-latte .column.is-offset-6-tablet{margin-left:50%}html.theme--catppuccin-latte .column.is-7,html.theme--catppuccin-latte .column.is-7-tablet{flex:none;width:58.33333337%}html.theme--catppuccin-latte .column.is-offset-7,html.theme--catppuccin-latte .column.is-offset-7-tablet{margin-left:58.33333337%}html.theme--catppuccin-latte .column.is-8,html.theme--catppuccin-latte .column.is-8-tablet{flex:none;width:66.66666674%}html.theme--catppuccin-latte .column.is-offset-8,html.theme--catppuccin-latte .column.is-offset-8-tablet{margin-left:66.66666674%}html.theme--catppuccin-latte .column.is-9,html.theme--catppuccin-latte .column.is-9-tablet{flex:none;width:75%}html.theme--catppuccin-latte .column.is-offset-9,html.theme--catppuccin-latte .column.is-offset-9-tablet{margin-left:75%}html.theme--catppuccin-latte .column.is-10,html.theme--catppuccin-latte .column.is-10-tablet{flex:none;width:83.33333337%}html.theme--catppuccin-latte .column.is-offset-10,html.theme--catppuccin-latte .column.is-offset-10-tablet{margin-left:83.33333337%}html.theme--catppuccin-latte .column.is-11,html.theme--catppuccin-latte .column.is-11-tablet{flex:none;width:91.66666674%}html.theme--catppuccin-latte .column.is-offset-11,html.theme--catppuccin-latte .column.is-offset-11-tablet{margin-left:91.66666674%}html.theme--catppuccin-latte .column.is-12,html.theme--catppuccin-latte .column.is-12-tablet{flex:none;width:100%}html.theme--catppuccin-latte .column.is-offset-12,html.theme--catppuccin-latte .column.is-offset-12-tablet{margin-left:100%}}@media screen and (max-width: 1055px){html.theme--catppuccin-latte .column.is-narrow-touch{flex:none;width:unset}html.theme--catppuccin-latte .column.is-full-touch{flex:none;width:100%}html.theme--catppuccin-latte .column.is-three-quarters-touch{flex:none;width:75%}html.theme--catppuccin-latte .column.is-two-thirds-touch{flex:none;width:66.6666%}html.theme--catppuccin-latte .column.is-half-touch{flex:none;width:50%}html.theme--catppuccin-latte .column.is-one-third-touch{flex:none;width:33.3333%}html.theme--catppuccin-latte .column.is-one-quarter-touch{flex:none;width:25%}html.theme--catppuccin-latte .column.is-one-fifth-touch{flex:none;width:20%}html.theme--catppuccin-latte .column.is-two-fifths-touch{flex:none;width:40%}html.theme--catppuccin-latte .column.is-three-fifths-touch{flex:none;width:60%}html.theme--catppuccin-latte .column.is-four-fifths-touch{flex:none;width:80%}html.theme--catppuccin-latte .column.is-offset-three-quarters-touch{margin-left:75%}html.theme--catppuccin-latte .column.is-offset-two-thirds-touch{margin-left:66.6666%}html.theme--catppuccin-latte .column.is-offset-half-touch{margin-left:50%}html.theme--catppuccin-latte .column.is-offset-one-third-touch{margin-left:33.3333%}html.theme--catppuccin-latte .column.is-offset-one-quarter-touch{margin-left:25%}html.theme--catppuccin-latte .column.is-offset-one-fifth-touch{margin-left:20%}html.theme--catppuccin-latte .column.is-offset-two-fifths-touch{margin-left:40%}html.theme--catppuccin-latte .column.is-offset-three-fifths-touch{margin-left:60%}html.theme--catppuccin-latte .column.is-offset-four-fifths-touch{margin-left:80%}html.theme--catppuccin-latte .column.is-0-touch{flex:none;width:0%}html.theme--catppuccin-latte .column.is-offset-0-touch{margin-left:0%}html.theme--catppuccin-latte .column.is-1-touch{flex:none;width:8.33333337%}html.theme--catppuccin-latte .column.is-offset-1-touch{margin-left:8.33333337%}html.theme--catppuccin-latte .column.is-2-touch{flex:none;width:16.66666674%}html.theme--catppuccin-latte .column.is-offset-2-touch{margin-left:16.66666674%}html.theme--catppuccin-latte .column.is-3-touch{flex:none;width:25%}html.theme--catppuccin-latte .column.is-offset-3-touch{margin-left:25%}html.theme--catppuccin-latte .column.is-4-touch{flex:none;width:33.33333337%}html.theme--catppuccin-latte .column.is-offset-4-touch{margin-left:33.33333337%}html.theme--catppuccin-latte .column.is-5-touch{flex:none;width:41.66666674%}html.theme--catppuccin-latte .column.is-offset-5-touch{margin-left:41.66666674%}html.theme--catppuccin-latte .column.is-6-touch{flex:none;width:50%}html.theme--catppuccin-latte .column.is-offset-6-touch{margin-left:50%}html.theme--catppuccin-latte .column.is-7-touch{flex:none;width:58.33333337%}html.theme--catppuccin-latte .column.is-offset-7-touch{margin-left:58.33333337%}html.theme--catppuccin-latte .column.is-8-touch{flex:none;width:66.66666674%}html.theme--catppuccin-latte .column.is-offset-8-touch{margin-left:66.66666674%}html.theme--catppuccin-latte .column.is-9-touch{flex:none;width:75%}html.theme--catppuccin-latte .column.is-offset-9-touch{margin-left:75%}html.theme--catppuccin-latte .column.is-10-touch{flex:none;width:83.33333337%}html.theme--catppuccin-latte .column.is-offset-10-touch{margin-left:83.33333337%}html.theme--catppuccin-latte .column.is-11-touch{flex:none;width:91.66666674%}html.theme--catppuccin-latte .column.is-offset-11-touch{margin-left:91.66666674%}html.theme--catppuccin-latte .column.is-12-touch{flex:none;width:100%}html.theme--catppuccin-latte .column.is-offset-12-touch{margin-left:100%}}@media screen and (min-width: 1056px){html.theme--catppuccin-latte .column.is-narrow-desktop{flex:none;width:unset}html.theme--catppuccin-latte .column.is-full-desktop{flex:none;width:100%}html.theme--catppuccin-latte .column.is-three-quarters-desktop{flex:none;width:75%}html.theme--catppuccin-latte .column.is-two-thirds-desktop{flex:none;width:66.6666%}html.theme--catppuccin-latte .column.is-half-desktop{flex:none;width:50%}html.theme--catppuccin-latte .column.is-one-third-desktop{flex:none;width:33.3333%}html.theme--catppuccin-latte .column.is-one-quarter-desktop{flex:none;width:25%}html.theme--catppuccin-latte .column.is-one-fifth-desktop{flex:none;width:20%}html.theme--catppuccin-latte .column.is-two-fifths-desktop{flex:none;width:40%}html.theme--catppuccin-latte .column.is-three-fifths-desktop{flex:none;width:60%}html.theme--catppuccin-latte .column.is-four-fifths-desktop{flex:none;width:80%}html.theme--catppuccin-latte .column.is-offset-three-quarters-desktop{margin-left:75%}html.theme--catppuccin-latte .column.is-offset-two-thirds-desktop{margin-left:66.6666%}html.theme--catppuccin-latte .column.is-offset-half-desktop{margin-left:50%}html.theme--catppuccin-latte .column.is-offset-one-third-desktop{margin-left:33.3333%}html.theme--catppuccin-latte .column.is-offset-one-quarter-desktop{margin-left:25%}html.theme--catppuccin-latte .column.is-offset-one-fifth-desktop{margin-left:20%}html.theme--catppuccin-latte .column.is-offset-two-fifths-desktop{margin-left:40%}html.theme--catppuccin-latte .column.is-offset-three-fifths-desktop{margin-left:60%}html.theme--catppuccin-latte .column.is-offset-four-fifths-desktop{margin-left:80%}html.theme--catppuccin-latte .column.is-0-desktop{flex:none;width:0%}html.theme--catppuccin-latte .column.is-offset-0-desktop{margin-left:0%}html.theme--catppuccin-latte .column.is-1-desktop{flex:none;width:8.33333337%}html.theme--catppuccin-latte .column.is-offset-1-desktop{margin-left:8.33333337%}html.theme--catppuccin-latte .column.is-2-desktop{flex:none;width:16.66666674%}html.theme--catppuccin-latte .column.is-offset-2-desktop{margin-left:16.66666674%}html.theme--catppuccin-latte .column.is-3-desktop{flex:none;width:25%}html.theme--catppuccin-latte .column.is-offset-3-desktop{margin-left:25%}html.theme--catppuccin-latte .column.is-4-desktop{flex:none;width:33.33333337%}html.theme--catppuccin-latte .column.is-offset-4-desktop{margin-left:33.33333337%}html.theme--catppuccin-latte .column.is-5-desktop{flex:none;width:41.66666674%}html.theme--catppuccin-latte .column.is-offset-5-desktop{margin-left:41.66666674%}html.theme--catppuccin-latte .column.is-6-desktop{flex:none;width:50%}html.theme--catppuccin-latte .column.is-offset-6-desktop{margin-left:50%}html.theme--catppuccin-latte .column.is-7-desktop{flex:none;width:58.33333337%}html.theme--catppuccin-latte .column.is-offset-7-desktop{margin-left:58.33333337%}html.theme--catppuccin-latte .column.is-8-desktop{flex:none;width:66.66666674%}html.theme--catppuccin-latte .column.is-offset-8-desktop{margin-left:66.66666674%}html.theme--catppuccin-latte .column.is-9-desktop{flex:none;width:75%}html.theme--catppuccin-latte .column.is-offset-9-desktop{margin-left:75%}html.theme--catppuccin-latte .column.is-10-desktop{flex:none;width:83.33333337%}html.theme--catppuccin-latte .column.is-offset-10-desktop{margin-left:83.33333337%}html.theme--catppuccin-latte .column.is-11-desktop{flex:none;width:91.66666674%}html.theme--catppuccin-latte .column.is-offset-11-desktop{margin-left:91.66666674%}html.theme--catppuccin-latte .column.is-12-desktop{flex:none;width:100%}html.theme--catppuccin-latte .column.is-offset-12-desktop{margin-left:100%}}@media screen and (min-width: 1216px){html.theme--catppuccin-latte .column.is-narrow-widescreen{flex:none;width:unset}html.theme--catppuccin-latte .column.is-full-widescreen{flex:none;width:100%}html.theme--catppuccin-latte .column.is-three-quarters-widescreen{flex:none;width:75%}html.theme--catppuccin-latte .column.is-two-thirds-widescreen{flex:none;width:66.6666%}html.theme--catppuccin-latte .column.is-half-widescreen{flex:none;width:50%}html.theme--catppuccin-latte .column.is-one-third-widescreen{flex:none;width:33.3333%}html.theme--catppuccin-latte .column.is-one-quarter-widescreen{flex:none;width:25%}html.theme--catppuccin-latte .column.is-one-fifth-widescreen{flex:none;width:20%}html.theme--catppuccin-latte .column.is-two-fifths-widescreen{flex:none;width:40%}html.theme--catppuccin-latte .column.is-three-fifths-widescreen{flex:none;width:60%}html.theme--catppuccin-latte .column.is-four-fifths-widescreen{flex:none;width:80%}html.theme--catppuccin-latte .column.is-offset-three-quarters-widescreen{margin-left:75%}html.theme--catppuccin-latte .column.is-offset-two-thirds-widescreen{margin-left:66.6666%}html.theme--catppuccin-latte .column.is-offset-half-widescreen{margin-left:50%}html.theme--catppuccin-latte .column.is-offset-one-third-widescreen{margin-left:33.3333%}html.theme--catppuccin-latte .column.is-offset-one-quarter-widescreen{margin-left:25%}html.theme--catppuccin-latte .column.is-offset-one-fifth-widescreen{margin-left:20%}html.theme--catppuccin-latte .column.is-offset-two-fifths-widescreen{margin-left:40%}html.theme--catppuccin-latte .column.is-offset-three-fifths-widescreen{margin-left:60%}html.theme--catppuccin-latte .column.is-offset-four-fifths-widescreen{margin-left:80%}html.theme--catppuccin-latte .column.is-0-widescreen{flex:none;width:0%}html.theme--catppuccin-latte .column.is-offset-0-widescreen{margin-left:0%}html.theme--catppuccin-latte .column.is-1-widescreen{flex:none;width:8.33333337%}html.theme--catppuccin-latte .column.is-offset-1-widescreen{margin-left:8.33333337%}html.theme--catppuccin-latte .column.is-2-widescreen{flex:none;width:16.66666674%}html.theme--catppuccin-latte .column.is-offset-2-widescreen{margin-left:16.66666674%}html.theme--catppuccin-latte .column.is-3-widescreen{flex:none;width:25%}html.theme--catppuccin-latte .column.is-offset-3-widescreen{margin-left:25%}html.theme--catppuccin-latte .column.is-4-widescreen{flex:none;width:33.33333337%}html.theme--catppuccin-latte .column.is-offset-4-widescreen{margin-left:33.33333337%}html.theme--catppuccin-latte .column.is-5-widescreen{flex:none;width:41.66666674%}html.theme--catppuccin-latte .column.is-offset-5-widescreen{margin-left:41.66666674%}html.theme--catppuccin-latte .column.is-6-widescreen{flex:none;width:50%}html.theme--catppuccin-latte .column.is-offset-6-widescreen{margin-left:50%}html.theme--catppuccin-latte .column.is-7-widescreen{flex:none;width:58.33333337%}html.theme--catppuccin-latte .column.is-offset-7-widescreen{margin-left:58.33333337%}html.theme--catppuccin-latte .column.is-8-widescreen{flex:none;width:66.66666674%}html.theme--catppuccin-latte .column.is-offset-8-widescreen{margin-left:66.66666674%}html.theme--catppuccin-latte .column.is-9-widescreen{flex:none;width:75%}html.theme--catppuccin-latte .column.is-offset-9-widescreen{margin-left:75%}html.theme--catppuccin-latte .column.is-10-widescreen{flex:none;width:83.33333337%}html.theme--catppuccin-latte .column.is-offset-10-widescreen{margin-left:83.33333337%}html.theme--catppuccin-latte .column.is-11-widescreen{flex:none;width:91.66666674%}html.theme--catppuccin-latte .column.is-offset-11-widescreen{margin-left:91.66666674%}html.theme--catppuccin-latte .column.is-12-widescreen{flex:none;width:100%}html.theme--catppuccin-latte .column.is-offset-12-widescreen{margin-left:100%}}@media screen and (min-width: 1408px){html.theme--catppuccin-latte .column.is-narrow-fullhd{flex:none;width:unset}html.theme--catppuccin-latte .column.is-full-fullhd{flex:none;width:100%}html.theme--catppuccin-latte .column.is-three-quarters-fullhd{flex:none;width:75%}html.theme--catppuccin-latte .column.is-two-thirds-fullhd{flex:none;width:66.6666%}html.theme--catppuccin-latte .column.is-half-fullhd{flex:none;width:50%}html.theme--catppuccin-latte .column.is-one-third-fullhd{flex:none;width:33.3333%}html.theme--catppuccin-latte .column.is-one-quarter-fullhd{flex:none;width:25%}html.theme--catppuccin-latte .column.is-one-fifth-fullhd{flex:none;width:20%}html.theme--catppuccin-latte .column.is-two-fifths-fullhd{flex:none;width:40%}html.theme--catppuccin-latte .column.is-three-fifths-fullhd{flex:none;width:60%}html.theme--catppuccin-latte .column.is-four-fifths-fullhd{flex:none;width:80%}html.theme--catppuccin-latte .column.is-offset-three-quarters-fullhd{margin-left:75%}html.theme--catppuccin-latte .column.is-offset-two-thirds-fullhd{margin-left:66.6666%}html.theme--catppuccin-latte .column.is-offset-half-fullhd{margin-left:50%}html.theme--catppuccin-latte .column.is-offset-one-third-fullhd{margin-left:33.3333%}html.theme--catppuccin-latte .column.is-offset-one-quarter-fullhd{margin-left:25%}html.theme--catppuccin-latte .column.is-offset-one-fifth-fullhd{margin-left:20%}html.theme--catppuccin-latte .column.is-offset-two-fifths-fullhd{margin-left:40%}html.theme--catppuccin-latte .column.is-offset-three-fifths-fullhd{margin-left:60%}html.theme--catppuccin-latte .column.is-offset-four-fifths-fullhd{margin-left:80%}html.theme--catppuccin-latte .column.is-0-fullhd{flex:none;width:0%}html.theme--catppuccin-latte .column.is-offset-0-fullhd{margin-left:0%}html.theme--catppuccin-latte .column.is-1-fullhd{flex:none;width:8.33333337%}html.theme--catppuccin-latte .column.is-offset-1-fullhd{margin-left:8.33333337%}html.theme--catppuccin-latte .column.is-2-fullhd{flex:none;width:16.66666674%}html.theme--catppuccin-latte .column.is-offset-2-fullhd{margin-left:16.66666674%}html.theme--catppuccin-latte .column.is-3-fullhd{flex:none;width:25%}html.theme--catppuccin-latte .column.is-offset-3-fullhd{margin-left:25%}html.theme--catppuccin-latte .column.is-4-fullhd{flex:none;width:33.33333337%}html.theme--catppuccin-latte .column.is-offset-4-fullhd{margin-left:33.33333337%}html.theme--catppuccin-latte .column.is-5-fullhd{flex:none;width:41.66666674%}html.theme--catppuccin-latte .column.is-offset-5-fullhd{margin-left:41.66666674%}html.theme--catppuccin-latte .column.is-6-fullhd{flex:none;width:50%}html.theme--catppuccin-latte .column.is-offset-6-fullhd{margin-left:50%}html.theme--catppuccin-latte .column.is-7-fullhd{flex:none;width:58.33333337%}html.theme--catppuccin-latte .column.is-offset-7-fullhd{margin-left:58.33333337%}html.theme--catppuccin-latte .column.is-8-fullhd{flex:none;width:66.66666674%}html.theme--catppuccin-latte .column.is-offset-8-fullhd{margin-left:66.66666674%}html.theme--catppuccin-latte .column.is-9-fullhd{flex:none;width:75%}html.theme--catppuccin-latte .column.is-offset-9-fullhd{margin-left:75%}html.theme--catppuccin-latte .column.is-10-fullhd{flex:none;width:83.33333337%}html.theme--catppuccin-latte .column.is-offset-10-fullhd{margin-left:83.33333337%}html.theme--catppuccin-latte .column.is-11-fullhd{flex:none;width:91.66666674%}html.theme--catppuccin-latte .column.is-offset-11-fullhd{margin-left:91.66666674%}html.theme--catppuccin-latte .column.is-12-fullhd{flex:none;width:100%}html.theme--catppuccin-latte .column.is-offset-12-fullhd{margin-left:100%}}html.theme--catppuccin-latte .columns{margin-left:-.75rem;margin-right:-.75rem;margin-top:-.75rem}html.theme--catppuccin-latte .columns:last-child{margin-bottom:-.75rem}html.theme--catppuccin-latte .columns:not(:last-child){margin-bottom:calc(1.5rem - .75rem)}html.theme--catppuccin-latte .columns.is-centered{justify-content:center}html.theme--catppuccin-latte .columns.is-gapless{margin-left:0;margin-right:0;margin-top:0}html.theme--catppuccin-latte .columns.is-gapless>.column{margin:0;padding:0 !important}html.theme--catppuccin-latte .columns.is-gapless:not(:last-child){margin-bottom:1.5rem}html.theme--catppuccin-latte .columns.is-gapless:last-child{margin-bottom:0}html.theme--catppuccin-latte .columns.is-mobile{display:flex}html.theme--catppuccin-latte .columns.is-multiline{flex-wrap:wrap}html.theme--catppuccin-latte .columns.is-vcentered{align-items:center}@media screen and (min-width: 769px),print{html.theme--catppuccin-latte .columns:not(.is-desktop){display:flex}}@media screen and (min-width: 1056px){html.theme--catppuccin-latte .columns.is-desktop{display:flex}}html.theme--catppuccin-latte .columns.is-variable{--columnGap: 0.75rem;margin-left:calc(-1 * var(--columnGap));margin-right:calc(-1 * var(--columnGap))}html.theme--catppuccin-latte .columns.is-variable>.column{padding-left:var(--columnGap);padding-right:var(--columnGap)}html.theme--catppuccin-latte .columns.is-variable.is-0{--columnGap: 0rem}@media screen and (max-width: 768px){html.theme--catppuccin-latte .columns.is-variable.is-0-mobile{--columnGap: 0rem}}@media screen and (min-width: 769px),print{html.theme--catppuccin-latte .columns.is-variable.is-0-tablet{--columnGap: 0rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--catppuccin-latte .columns.is-variable.is-0-tablet-only{--columnGap: 0rem}}@media screen and (max-width: 1055px){html.theme--catppuccin-latte .columns.is-variable.is-0-touch{--columnGap: 0rem}}@media screen and (min-width: 1056px){html.theme--catppuccin-latte .columns.is-variable.is-0-desktop{--columnGap: 0rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){html.theme--catppuccin-latte .columns.is-variable.is-0-desktop-only{--columnGap: 0rem}}@media screen and (min-width: 1216px){html.theme--catppuccin-latte .columns.is-variable.is-0-widescreen{--columnGap: 0rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){html.theme--catppuccin-latte .columns.is-variable.is-0-widescreen-only{--columnGap: 0rem}}@media screen and (min-width: 1408px){html.theme--catppuccin-latte .columns.is-variable.is-0-fullhd{--columnGap: 0rem}}html.theme--catppuccin-latte .columns.is-variable.is-1{--columnGap: .25rem}@media screen and (max-width: 768px){html.theme--catppuccin-latte .columns.is-variable.is-1-mobile{--columnGap: .25rem}}@media screen and (min-width: 769px),print{html.theme--catppuccin-latte .columns.is-variable.is-1-tablet{--columnGap: .25rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--catppuccin-latte .columns.is-variable.is-1-tablet-only{--columnGap: .25rem}}@media screen and (max-width: 1055px){html.theme--catppuccin-latte .columns.is-variable.is-1-touch{--columnGap: .25rem}}@media screen and (min-width: 1056px){html.theme--catppuccin-latte .columns.is-variable.is-1-desktop{--columnGap: .25rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){html.theme--catppuccin-latte .columns.is-variable.is-1-desktop-only{--columnGap: .25rem}}@media screen and (min-width: 1216px){html.theme--catppuccin-latte .columns.is-variable.is-1-widescreen{--columnGap: .25rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){html.theme--catppuccin-latte .columns.is-variable.is-1-widescreen-only{--columnGap: .25rem}}@media screen and (min-width: 1408px){html.theme--catppuccin-latte .columns.is-variable.is-1-fullhd{--columnGap: .25rem}}html.theme--catppuccin-latte .columns.is-variable.is-2{--columnGap: .5rem}@media screen and (max-width: 768px){html.theme--catppuccin-latte .columns.is-variable.is-2-mobile{--columnGap: .5rem}}@media screen and (min-width: 769px),print{html.theme--catppuccin-latte .columns.is-variable.is-2-tablet{--columnGap: .5rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--catppuccin-latte .columns.is-variable.is-2-tablet-only{--columnGap: .5rem}}@media screen and (max-width: 1055px){html.theme--catppuccin-latte .columns.is-variable.is-2-touch{--columnGap: .5rem}}@media screen and (min-width: 1056px){html.theme--catppuccin-latte .columns.is-variable.is-2-desktop{--columnGap: .5rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){html.theme--catppuccin-latte .columns.is-variable.is-2-desktop-only{--columnGap: .5rem}}@media screen and (min-width: 1216px){html.theme--catppuccin-latte .columns.is-variable.is-2-widescreen{--columnGap: .5rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){html.theme--catppuccin-latte .columns.is-variable.is-2-widescreen-only{--columnGap: .5rem}}@media screen and (min-width: 1408px){html.theme--catppuccin-latte .columns.is-variable.is-2-fullhd{--columnGap: .5rem}}html.theme--catppuccin-latte .columns.is-variable.is-3{--columnGap: .75rem}@media screen and (max-width: 768px){html.theme--catppuccin-latte .columns.is-variable.is-3-mobile{--columnGap: .75rem}}@media screen and (min-width: 769px),print{html.theme--catppuccin-latte .columns.is-variable.is-3-tablet{--columnGap: .75rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--catppuccin-latte .columns.is-variable.is-3-tablet-only{--columnGap: .75rem}}@media screen and (max-width: 1055px){html.theme--catppuccin-latte .columns.is-variable.is-3-touch{--columnGap: .75rem}}@media screen and (min-width: 1056px){html.theme--catppuccin-latte .columns.is-variable.is-3-desktop{--columnGap: .75rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){html.theme--catppuccin-latte .columns.is-variable.is-3-desktop-only{--columnGap: .75rem}}@media screen and (min-width: 1216px){html.theme--catppuccin-latte .columns.is-variable.is-3-widescreen{--columnGap: .75rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){html.theme--catppuccin-latte .columns.is-variable.is-3-widescreen-only{--columnGap: .75rem}}@media screen and (min-width: 1408px){html.theme--catppuccin-latte .columns.is-variable.is-3-fullhd{--columnGap: .75rem}}html.theme--catppuccin-latte .columns.is-variable.is-4{--columnGap: 1rem}@media screen and (max-width: 768px){html.theme--catppuccin-latte .columns.is-variable.is-4-mobile{--columnGap: 1rem}}@media screen and (min-width: 769px),print{html.theme--catppuccin-latte .columns.is-variable.is-4-tablet{--columnGap: 1rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--catppuccin-latte .columns.is-variable.is-4-tablet-only{--columnGap: 1rem}}@media screen and (max-width: 1055px){html.theme--catppuccin-latte .columns.is-variable.is-4-touch{--columnGap: 1rem}}@media screen and (min-width: 1056px){html.theme--catppuccin-latte .columns.is-variable.is-4-desktop{--columnGap: 1rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){html.theme--catppuccin-latte .columns.is-variable.is-4-desktop-only{--columnGap: 1rem}}@media screen and (min-width: 1216px){html.theme--catppuccin-latte .columns.is-variable.is-4-widescreen{--columnGap: 1rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){html.theme--catppuccin-latte .columns.is-variable.is-4-widescreen-only{--columnGap: 1rem}}@media screen and (min-width: 1408px){html.theme--catppuccin-latte .columns.is-variable.is-4-fullhd{--columnGap: 1rem}}html.theme--catppuccin-latte .columns.is-variable.is-5{--columnGap: 1.25rem}@media screen and (max-width: 768px){html.theme--catppuccin-latte .columns.is-variable.is-5-mobile{--columnGap: 1.25rem}}@media screen and (min-width: 769px),print{html.theme--catppuccin-latte .columns.is-variable.is-5-tablet{--columnGap: 1.25rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--catppuccin-latte .columns.is-variable.is-5-tablet-only{--columnGap: 1.25rem}}@media screen and (max-width: 1055px){html.theme--catppuccin-latte .columns.is-variable.is-5-touch{--columnGap: 1.25rem}}@media screen and (min-width: 1056px){html.theme--catppuccin-latte .columns.is-variable.is-5-desktop{--columnGap: 1.25rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){html.theme--catppuccin-latte .columns.is-variable.is-5-desktop-only{--columnGap: 1.25rem}}@media screen and (min-width: 1216px){html.theme--catppuccin-latte .columns.is-variable.is-5-widescreen{--columnGap: 1.25rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){html.theme--catppuccin-latte .columns.is-variable.is-5-widescreen-only{--columnGap: 1.25rem}}@media screen and (min-width: 1408px){html.theme--catppuccin-latte .columns.is-variable.is-5-fullhd{--columnGap: 1.25rem}}html.theme--catppuccin-latte .columns.is-variable.is-6{--columnGap: 1.5rem}@media screen and (max-width: 768px){html.theme--catppuccin-latte .columns.is-variable.is-6-mobile{--columnGap: 1.5rem}}@media screen and (min-width: 769px),print{html.theme--catppuccin-latte .columns.is-variable.is-6-tablet{--columnGap: 1.5rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--catppuccin-latte .columns.is-variable.is-6-tablet-only{--columnGap: 1.5rem}}@media screen and (max-width: 1055px){html.theme--catppuccin-latte .columns.is-variable.is-6-touch{--columnGap: 1.5rem}}@media screen and (min-width: 1056px){html.theme--catppuccin-latte .columns.is-variable.is-6-desktop{--columnGap: 1.5rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){html.theme--catppuccin-latte .columns.is-variable.is-6-desktop-only{--columnGap: 1.5rem}}@media screen and (min-width: 1216px){html.theme--catppuccin-latte .columns.is-variable.is-6-widescreen{--columnGap: 1.5rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){html.theme--catppuccin-latte .columns.is-variable.is-6-widescreen-only{--columnGap: 1.5rem}}@media screen and (min-width: 1408px){html.theme--catppuccin-latte .columns.is-variable.is-6-fullhd{--columnGap: 1.5rem}}html.theme--catppuccin-latte .columns.is-variable.is-7{--columnGap: 1.75rem}@media screen and (max-width: 768px){html.theme--catppuccin-latte .columns.is-variable.is-7-mobile{--columnGap: 1.75rem}}@media screen and (min-width: 769px),print{html.theme--catppuccin-latte .columns.is-variable.is-7-tablet{--columnGap: 1.75rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--catppuccin-latte .columns.is-variable.is-7-tablet-only{--columnGap: 1.75rem}}@media screen and (max-width: 1055px){html.theme--catppuccin-latte .columns.is-variable.is-7-touch{--columnGap: 1.75rem}}@media screen and (min-width: 1056px){html.theme--catppuccin-latte .columns.is-variable.is-7-desktop{--columnGap: 1.75rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){html.theme--catppuccin-latte .columns.is-variable.is-7-desktop-only{--columnGap: 1.75rem}}@media screen and (min-width: 1216px){html.theme--catppuccin-latte .columns.is-variable.is-7-widescreen{--columnGap: 1.75rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){html.theme--catppuccin-latte .columns.is-variable.is-7-widescreen-only{--columnGap: 1.75rem}}@media screen and (min-width: 1408px){html.theme--catppuccin-latte .columns.is-variable.is-7-fullhd{--columnGap: 1.75rem}}html.theme--catppuccin-latte .columns.is-variable.is-8{--columnGap: 2rem}@media screen and (max-width: 768px){html.theme--catppuccin-latte .columns.is-variable.is-8-mobile{--columnGap: 2rem}}@media screen and (min-width: 769px),print{html.theme--catppuccin-latte .columns.is-variable.is-8-tablet{--columnGap: 2rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--catppuccin-latte .columns.is-variable.is-8-tablet-only{--columnGap: 2rem}}@media screen and (max-width: 1055px){html.theme--catppuccin-latte .columns.is-variable.is-8-touch{--columnGap: 2rem}}@media screen and (min-width: 1056px){html.theme--catppuccin-latte .columns.is-variable.is-8-desktop{--columnGap: 2rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){html.theme--catppuccin-latte .columns.is-variable.is-8-desktop-only{--columnGap: 2rem}}@media screen and (min-width: 1216px){html.theme--catppuccin-latte .columns.is-variable.is-8-widescreen{--columnGap: 2rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){html.theme--catppuccin-latte .columns.is-variable.is-8-widescreen-only{--columnGap: 2rem}}@media screen and (min-width: 1408px){html.theme--catppuccin-latte .columns.is-variable.is-8-fullhd{--columnGap: 2rem}}html.theme--catppuccin-latte .tile{align-items:stretch;display:block;flex-basis:0;flex-grow:1;flex-shrink:1;min-height:min-content}html.theme--catppuccin-latte .tile.is-ancestor{margin-left:-.75rem;margin-right:-.75rem;margin-top:-.75rem}html.theme--catppuccin-latte .tile.is-ancestor:last-child{margin-bottom:-.75rem}html.theme--catppuccin-latte .tile.is-ancestor:not(:last-child){margin-bottom:.75rem}html.theme--catppuccin-latte .tile.is-child{margin:0 !important}html.theme--catppuccin-latte .tile.is-parent{padding:.75rem}html.theme--catppuccin-latte .tile.is-vertical{flex-direction:column}html.theme--catppuccin-latte .tile.is-vertical>.tile.is-child:not(:last-child){margin-bottom:1.5rem !important}@media screen and (min-width: 769px),print{html.theme--catppuccin-latte .tile:not(.is-child){display:flex}html.theme--catppuccin-latte .tile.is-1{flex:none;width:8.33333337%}html.theme--catppuccin-latte .tile.is-2{flex:none;width:16.66666674%}html.theme--catppuccin-latte .tile.is-3{flex:none;width:25%}html.theme--catppuccin-latte .tile.is-4{flex:none;width:33.33333337%}html.theme--catppuccin-latte .tile.is-5{flex:none;width:41.66666674%}html.theme--catppuccin-latte .tile.is-6{flex:none;width:50%}html.theme--catppuccin-latte .tile.is-7{flex:none;width:58.33333337%}html.theme--catppuccin-latte .tile.is-8{flex:none;width:66.66666674%}html.theme--catppuccin-latte .tile.is-9{flex:none;width:75%}html.theme--catppuccin-latte .tile.is-10{flex:none;width:83.33333337%}html.theme--catppuccin-latte .tile.is-11{flex:none;width:91.66666674%}html.theme--catppuccin-latte .tile.is-12{flex:none;width:100%}}html.theme--catppuccin-latte .hero{align-items:stretch;display:flex;flex-direction:column;justify-content:space-between}html.theme--catppuccin-latte .hero .navbar{background:none}html.theme--catppuccin-latte .hero .tabs ul{border-bottom:none}html.theme--catppuccin-latte .hero.is-white{background-color:#fff;color:#0a0a0a}html.theme--catppuccin-latte .hero.is-white a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--catppuccin-latte .hero.is-white strong{color:inherit}html.theme--catppuccin-latte .hero.is-white .title{color:#0a0a0a}html.theme--catppuccin-latte .hero.is-white .subtitle{color:rgba(10,10,10,0.9)}html.theme--catppuccin-latte .hero.is-white .subtitle a:not(.button),html.theme--catppuccin-latte .hero.is-white .subtitle strong{color:#0a0a0a}@media screen and (max-width: 1055px){html.theme--catppuccin-latte .hero.is-white .navbar-menu{background-color:#fff}}html.theme--catppuccin-latte .hero.is-white .navbar-item,html.theme--catppuccin-latte .hero.is-white .navbar-link{color:rgba(10,10,10,0.7)}html.theme--catppuccin-latte .hero.is-white a.navbar-item:hover,html.theme--catppuccin-latte .hero.is-white a.navbar-item.is-active,html.theme--catppuccin-latte .hero.is-white .navbar-link:hover,html.theme--catppuccin-latte .hero.is-white .navbar-link.is-active{background-color:#f2f2f2;color:#0a0a0a}html.theme--catppuccin-latte .hero.is-white .tabs a{color:#0a0a0a;opacity:0.9}html.theme--catppuccin-latte .hero.is-white .tabs a:hover{opacity:1}html.theme--catppuccin-latte .hero.is-white .tabs li.is-active a{color:#fff !important;opacity:1}html.theme--catppuccin-latte .hero.is-white .tabs.is-boxed a,html.theme--catppuccin-latte .hero.is-white .tabs.is-toggle a{color:#0a0a0a}html.theme--catppuccin-latte .hero.is-white .tabs.is-boxed a:hover,html.theme--catppuccin-latte .hero.is-white .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--catppuccin-latte .hero.is-white .tabs.is-boxed li.is-active a,html.theme--catppuccin-latte .hero.is-white .tabs.is-boxed li.is-active a:hover,html.theme--catppuccin-latte .hero.is-white .tabs.is-toggle li.is-active a,html.theme--catppuccin-latte .hero.is-white .tabs.is-toggle li.is-active a:hover{background-color:#0a0a0a;border-color:#0a0a0a;color:#fff}html.theme--catppuccin-latte .hero.is-white.is-bold{background-image:linear-gradient(141deg, #e8e3e4 0%, #fff 71%, #fff 100%)}@media screen and (max-width: 768px){html.theme--catppuccin-latte .hero.is-white.is-bold .navbar-menu{background-image:linear-gradient(141deg, #e8e3e4 0%, #fff 71%, #fff 100%)}}html.theme--catppuccin-latte .hero.is-black{background-color:#0a0a0a;color:#fff}html.theme--catppuccin-latte .hero.is-black a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--catppuccin-latte .hero.is-black strong{color:inherit}html.theme--catppuccin-latte .hero.is-black .title{color:#fff}html.theme--catppuccin-latte .hero.is-black .subtitle{color:rgba(255,255,255,0.9)}html.theme--catppuccin-latte .hero.is-black .subtitle a:not(.button),html.theme--catppuccin-latte .hero.is-black .subtitle strong{color:#fff}@media screen and (max-width: 1055px){html.theme--catppuccin-latte .hero.is-black .navbar-menu{background-color:#0a0a0a}}html.theme--catppuccin-latte .hero.is-black .navbar-item,html.theme--catppuccin-latte .hero.is-black .navbar-link{color:rgba(255,255,255,0.7)}html.theme--catppuccin-latte .hero.is-black a.navbar-item:hover,html.theme--catppuccin-latte .hero.is-black a.navbar-item.is-active,html.theme--catppuccin-latte .hero.is-black .navbar-link:hover,html.theme--catppuccin-latte .hero.is-black .navbar-link.is-active{background-color:#000;color:#fff}html.theme--catppuccin-latte .hero.is-black .tabs a{color:#fff;opacity:0.9}html.theme--catppuccin-latte .hero.is-black .tabs a:hover{opacity:1}html.theme--catppuccin-latte .hero.is-black .tabs li.is-active a{color:#0a0a0a !important;opacity:1}html.theme--catppuccin-latte .hero.is-black .tabs.is-boxed a,html.theme--catppuccin-latte .hero.is-black .tabs.is-toggle a{color:#fff}html.theme--catppuccin-latte .hero.is-black .tabs.is-boxed a:hover,html.theme--catppuccin-latte .hero.is-black .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--catppuccin-latte .hero.is-black .tabs.is-boxed li.is-active a,html.theme--catppuccin-latte .hero.is-black .tabs.is-boxed li.is-active a:hover,html.theme--catppuccin-latte .hero.is-black .tabs.is-toggle li.is-active a,html.theme--catppuccin-latte .hero.is-black .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#0a0a0a}html.theme--catppuccin-latte .hero.is-black.is-bold{background-image:linear-gradient(141deg, #000 0%, #0a0a0a 71%, #181616 100%)}@media screen and (max-width: 768px){html.theme--catppuccin-latte .hero.is-black.is-bold .navbar-menu{background-image:linear-gradient(141deg, #000 0%, #0a0a0a 71%, #181616 100%)}}html.theme--catppuccin-latte .hero.is-light{background-color:#f5f5f5;color:rgba(0,0,0,0.7)}html.theme--catppuccin-latte .hero.is-light a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--catppuccin-latte .hero.is-light strong{color:inherit}html.theme--catppuccin-latte .hero.is-light .title{color:rgba(0,0,0,0.7)}html.theme--catppuccin-latte .hero.is-light .subtitle{color:rgba(0,0,0,0.9)}html.theme--catppuccin-latte .hero.is-light .subtitle a:not(.button),html.theme--catppuccin-latte .hero.is-light .subtitle strong{color:rgba(0,0,0,0.7)}@media screen and (max-width: 1055px){html.theme--catppuccin-latte .hero.is-light .navbar-menu{background-color:#f5f5f5}}html.theme--catppuccin-latte .hero.is-light .navbar-item,html.theme--catppuccin-latte .hero.is-light .navbar-link{color:rgba(0,0,0,0.7)}html.theme--catppuccin-latte .hero.is-light a.navbar-item:hover,html.theme--catppuccin-latte .hero.is-light a.navbar-item.is-active,html.theme--catppuccin-latte .hero.is-light .navbar-link:hover,html.theme--catppuccin-latte .hero.is-light .navbar-link.is-active{background-color:#e8e8e8;color:rgba(0,0,0,0.7)}html.theme--catppuccin-latte .hero.is-light .tabs a{color:rgba(0,0,0,0.7);opacity:0.9}html.theme--catppuccin-latte .hero.is-light .tabs a:hover{opacity:1}html.theme--catppuccin-latte .hero.is-light .tabs li.is-active a{color:#f5f5f5 !important;opacity:1}html.theme--catppuccin-latte .hero.is-light .tabs.is-boxed a,html.theme--catppuccin-latte .hero.is-light .tabs.is-toggle a{color:rgba(0,0,0,0.7)}html.theme--catppuccin-latte .hero.is-light .tabs.is-boxed a:hover,html.theme--catppuccin-latte .hero.is-light .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--catppuccin-latte .hero.is-light .tabs.is-boxed li.is-active a,html.theme--catppuccin-latte .hero.is-light .tabs.is-boxed li.is-active a:hover,html.theme--catppuccin-latte .hero.is-light .tabs.is-toggle li.is-active a,html.theme--catppuccin-latte .hero.is-light .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:#f5f5f5}html.theme--catppuccin-latte .hero.is-light.is-bold{background-image:linear-gradient(141deg, #dfd8d9 0%, #f5f5f5 71%, #fff 100%)}@media screen and (max-width: 768px){html.theme--catppuccin-latte .hero.is-light.is-bold .navbar-menu{background-image:linear-gradient(141deg, #dfd8d9 0%, #f5f5f5 71%, #fff 100%)}}html.theme--catppuccin-latte .hero.is-dark,html.theme--catppuccin-latte .content kbd.hero{background-color:#ccd0da;color:rgba(0,0,0,0.7)}html.theme--catppuccin-latte .hero.is-dark a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--catppuccin-latte .content kbd.hero a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--catppuccin-latte .hero.is-dark strong,html.theme--catppuccin-latte .content kbd.hero strong{color:inherit}html.theme--catppuccin-latte .hero.is-dark .title,html.theme--catppuccin-latte .content kbd.hero .title{color:rgba(0,0,0,0.7)}html.theme--catppuccin-latte .hero.is-dark .subtitle,html.theme--catppuccin-latte .content kbd.hero .subtitle{color:rgba(0,0,0,0.9)}html.theme--catppuccin-latte .hero.is-dark .subtitle a:not(.button),html.theme--catppuccin-latte .content kbd.hero .subtitle a:not(.button),html.theme--catppuccin-latte .hero.is-dark .subtitle strong,html.theme--catppuccin-latte .content kbd.hero .subtitle strong{color:rgba(0,0,0,0.7)}@media screen and (max-width: 1055px){html.theme--catppuccin-latte .hero.is-dark .navbar-menu,html.theme--catppuccin-latte .content kbd.hero .navbar-menu{background-color:#ccd0da}}html.theme--catppuccin-latte .hero.is-dark .navbar-item,html.theme--catppuccin-latte .content kbd.hero .navbar-item,html.theme--catppuccin-latte .hero.is-dark .navbar-link,html.theme--catppuccin-latte .content kbd.hero .navbar-link{color:rgba(0,0,0,0.7)}html.theme--catppuccin-latte .hero.is-dark a.navbar-item:hover,html.theme--catppuccin-latte .content kbd.hero a.navbar-item:hover,html.theme--catppuccin-latte .hero.is-dark a.navbar-item.is-active,html.theme--catppuccin-latte .content kbd.hero a.navbar-item.is-active,html.theme--catppuccin-latte .hero.is-dark .navbar-link:hover,html.theme--catppuccin-latte .content kbd.hero .navbar-link:hover,html.theme--catppuccin-latte .hero.is-dark .navbar-link.is-active,html.theme--catppuccin-latte .content kbd.hero .navbar-link.is-active{background-color:#bdc2cf;color:rgba(0,0,0,0.7)}html.theme--catppuccin-latte .hero.is-dark .tabs a,html.theme--catppuccin-latte .content kbd.hero .tabs a{color:rgba(0,0,0,0.7);opacity:0.9}html.theme--catppuccin-latte .hero.is-dark .tabs a:hover,html.theme--catppuccin-latte .content kbd.hero .tabs a:hover{opacity:1}html.theme--catppuccin-latte .hero.is-dark .tabs li.is-active a,html.theme--catppuccin-latte .content kbd.hero .tabs li.is-active a{color:#ccd0da !important;opacity:1}html.theme--catppuccin-latte .hero.is-dark .tabs.is-boxed a,html.theme--catppuccin-latte .content kbd.hero .tabs.is-boxed a,html.theme--catppuccin-latte .hero.is-dark .tabs.is-toggle a,html.theme--catppuccin-latte .content kbd.hero .tabs.is-toggle a{color:rgba(0,0,0,0.7)}html.theme--catppuccin-latte .hero.is-dark .tabs.is-boxed a:hover,html.theme--catppuccin-latte .content kbd.hero .tabs.is-boxed a:hover,html.theme--catppuccin-latte .hero.is-dark .tabs.is-toggle a:hover,html.theme--catppuccin-latte .content kbd.hero .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--catppuccin-latte .hero.is-dark .tabs.is-boxed li.is-active a,html.theme--catppuccin-latte .content kbd.hero .tabs.is-boxed li.is-active a,html.theme--catppuccin-latte .hero.is-dark .tabs.is-boxed li.is-active a:hover,html.theme--catppuccin-latte .hero.is-dark .tabs.is-toggle li.is-active a,html.theme--catppuccin-latte .content kbd.hero .tabs.is-toggle li.is-active a,html.theme--catppuccin-latte .hero.is-dark .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:#ccd0da}html.theme--catppuccin-latte .hero.is-dark.is-bold,html.theme--catppuccin-latte .content kbd.hero.is-bold{background-image:linear-gradient(141deg, #a7b8cc 0%, #ccd0da 71%, #d9dbe6 100%)}@media screen and (max-width: 768px){html.theme--catppuccin-latte .hero.is-dark.is-bold .navbar-menu,html.theme--catppuccin-latte .content kbd.hero.is-bold .navbar-menu{background-image:linear-gradient(141deg, #a7b8cc 0%, #ccd0da 71%, #d9dbe6 100%)}}html.theme--catppuccin-latte .hero.is-primary,html.theme--catppuccin-latte .docstring>section>a.hero.docs-sourcelink{background-color:#1e66f5;color:#fff}html.theme--catppuccin-latte .hero.is-primary a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--catppuccin-latte .docstring>section>a.hero.docs-sourcelink a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--catppuccin-latte .hero.is-primary strong,html.theme--catppuccin-latte .docstring>section>a.hero.docs-sourcelink strong{color:inherit}html.theme--catppuccin-latte .hero.is-primary .title,html.theme--catppuccin-latte .docstring>section>a.hero.docs-sourcelink .title{color:#fff}html.theme--catppuccin-latte .hero.is-primary .subtitle,html.theme--catppuccin-latte .docstring>section>a.hero.docs-sourcelink .subtitle{color:rgba(255,255,255,0.9)}html.theme--catppuccin-latte .hero.is-primary .subtitle a:not(.button),html.theme--catppuccin-latte .docstring>section>a.hero.docs-sourcelink .subtitle a:not(.button),html.theme--catppuccin-latte .hero.is-primary .subtitle strong,html.theme--catppuccin-latte .docstring>section>a.hero.docs-sourcelink .subtitle strong{color:#fff}@media screen and (max-width: 1055px){html.theme--catppuccin-latte .hero.is-primary .navbar-menu,html.theme--catppuccin-latte .docstring>section>a.hero.docs-sourcelink .navbar-menu{background-color:#1e66f5}}html.theme--catppuccin-latte .hero.is-primary .navbar-item,html.theme--catppuccin-latte .docstring>section>a.hero.docs-sourcelink .navbar-item,html.theme--catppuccin-latte .hero.is-primary .navbar-link,html.theme--catppuccin-latte .docstring>section>a.hero.docs-sourcelink .navbar-link{color:rgba(255,255,255,0.7)}html.theme--catppuccin-latte .hero.is-primary a.navbar-item:hover,html.theme--catppuccin-latte .docstring>section>a.hero.docs-sourcelink a.navbar-item:hover,html.theme--catppuccin-latte .hero.is-primary a.navbar-item.is-active,html.theme--catppuccin-latte .docstring>section>a.hero.docs-sourcelink a.navbar-item.is-active,html.theme--catppuccin-latte .hero.is-primary .navbar-link:hover,html.theme--catppuccin-latte .docstring>section>a.hero.docs-sourcelink .navbar-link:hover,html.theme--catppuccin-latte .hero.is-primary .navbar-link.is-active,html.theme--catppuccin-latte .docstring>section>a.hero.docs-sourcelink .navbar-link.is-active{background-color:#0b57ef;color:#fff}html.theme--catppuccin-latte .hero.is-primary .tabs a,html.theme--catppuccin-latte .docstring>section>a.hero.docs-sourcelink .tabs a{color:#fff;opacity:0.9}html.theme--catppuccin-latte .hero.is-primary .tabs a:hover,html.theme--catppuccin-latte .docstring>section>a.hero.docs-sourcelink .tabs a:hover{opacity:1}html.theme--catppuccin-latte .hero.is-primary .tabs li.is-active a,html.theme--catppuccin-latte .docstring>section>a.hero.docs-sourcelink .tabs li.is-active a{color:#1e66f5 !important;opacity:1}html.theme--catppuccin-latte .hero.is-primary .tabs.is-boxed a,html.theme--catppuccin-latte .docstring>section>a.hero.docs-sourcelink .tabs.is-boxed a,html.theme--catppuccin-latte .hero.is-primary .tabs.is-toggle a,html.theme--catppuccin-latte .docstring>section>a.hero.docs-sourcelink .tabs.is-toggle a{color:#fff}html.theme--catppuccin-latte .hero.is-primary .tabs.is-boxed a:hover,html.theme--catppuccin-latte .docstring>section>a.hero.docs-sourcelink .tabs.is-boxed a:hover,html.theme--catppuccin-latte .hero.is-primary .tabs.is-toggle a:hover,html.theme--catppuccin-latte .docstring>section>a.hero.docs-sourcelink .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--catppuccin-latte .hero.is-primary .tabs.is-boxed li.is-active a,html.theme--catppuccin-latte .docstring>section>a.hero.docs-sourcelink .tabs.is-boxed li.is-active a,html.theme--catppuccin-latte .hero.is-primary .tabs.is-boxed li.is-active a:hover,html.theme--catppuccin-latte .hero.is-primary .tabs.is-toggle li.is-active a,html.theme--catppuccin-latte .docstring>section>a.hero.docs-sourcelink .tabs.is-toggle li.is-active a,html.theme--catppuccin-latte .hero.is-primary .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#1e66f5}html.theme--catppuccin-latte .hero.is-primary.is-bold,html.theme--catppuccin-latte .docstring>section>a.hero.is-bold.docs-sourcelink{background-image:linear-gradient(141deg, #0070e0 0%, #1e66f5 71%, #3153fb 100%)}@media screen and (max-width: 768px){html.theme--catppuccin-latte .hero.is-primary.is-bold .navbar-menu,html.theme--catppuccin-latte .docstring>section>a.hero.is-bold.docs-sourcelink .navbar-menu{background-image:linear-gradient(141deg, #0070e0 0%, #1e66f5 71%, #3153fb 100%)}}html.theme--catppuccin-latte .hero.is-link{background-color:#1e66f5;color:#fff}html.theme--catppuccin-latte .hero.is-link a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--catppuccin-latte .hero.is-link strong{color:inherit}html.theme--catppuccin-latte .hero.is-link .title{color:#fff}html.theme--catppuccin-latte .hero.is-link .subtitle{color:rgba(255,255,255,0.9)}html.theme--catppuccin-latte .hero.is-link .subtitle a:not(.button),html.theme--catppuccin-latte .hero.is-link .subtitle strong{color:#fff}@media screen and (max-width: 1055px){html.theme--catppuccin-latte .hero.is-link .navbar-menu{background-color:#1e66f5}}html.theme--catppuccin-latte .hero.is-link .navbar-item,html.theme--catppuccin-latte .hero.is-link .navbar-link{color:rgba(255,255,255,0.7)}html.theme--catppuccin-latte .hero.is-link a.navbar-item:hover,html.theme--catppuccin-latte .hero.is-link a.navbar-item.is-active,html.theme--catppuccin-latte .hero.is-link .navbar-link:hover,html.theme--catppuccin-latte .hero.is-link .navbar-link.is-active{background-color:#0b57ef;color:#fff}html.theme--catppuccin-latte .hero.is-link .tabs a{color:#fff;opacity:0.9}html.theme--catppuccin-latte .hero.is-link .tabs a:hover{opacity:1}html.theme--catppuccin-latte .hero.is-link .tabs li.is-active a{color:#1e66f5 !important;opacity:1}html.theme--catppuccin-latte .hero.is-link .tabs.is-boxed a,html.theme--catppuccin-latte .hero.is-link .tabs.is-toggle a{color:#fff}html.theme--catppuccin-latte .hero.is-link .tabs.is-boxed a:hover,html.theme--catppuccin-latte .hero.is-link .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--catppuccin-latte .hero.is-link .tabs.is-boxed li.is-active a,html.theme--catppuccin-latte .hero.is-link .tabs.is-boxed li.is-active a:hover,html.theme--catppuccin-latte .hero.is-link .tabs.is-toggle li.is-active a,html.theme--catppuccin-latte .hero.is-link .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#1e66f5}html.theme--catppuccin-latte .hero.is-link.is-bold{background-image:linear-gradient(141deg, #0070e0 0%, #1e66f5 71%, #3153fb 100%)}@media screen and (max-width: 768px){html.theme--catppuccin-latte .hero.is-link.is-bold .navbar-menu{background-image:linear-gradient(141deg, #0070e0 0%, #1e66f5 71%, #3153fb 100%)}}html.theme--catppuccin-latte .hero.is-info{background-color:#179299;color:#fff}html.theme--catppuccin-latte .hero.is-info a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--catppuccin-latte .hero.is-info strong{color:inherit}html.theme--catppuccin-latte .hero.is-info .title{color:#fff}html.theme--catppuccin-latte .hero.is-info .subtitle{color:rgba(255,255,255,0.9)}html.theme--catppuccin-latte .hero.is-info .subtitle a:not(.button),html.theme--catppuccin-latte .hero.is-info .subtitle strong{color:#fff}@media screen and (max-width: 1055px){html.theme--catppuccin-latte .hero.is-info .navbar-menu{background-color:#179299}}html.theme--catppuccin-latte .hero.is-info .navbar-item,html.theme--catppuccin-latte .hero.is-info .navbar-link{color:rgba(255,255,255,0.7)}html.theme--catppuccin-latte .hero.is-info a.navbar-item:hover,html.theme--catppuccin-latte .hero.is-info a.navbar-item.is-active,html.theme--catppuccin-latte .hero.is-info .navbar-link:hover,html.theme--catppuccin-latte .hero.is-info .navbar-link.is-active{background-color:#147d83;color:#fff}html.theme--catppuccin-latte .hero.is-info .tabs a{color:#fff;opacity:0.9}html.theme--catppuccin-latte .hero.is-info .tabs a:hover{opacity:1}html.theme--catppuccin-latte .hero.is-info .tabs li.is-active a{color:#179299 !important;opacity:1}html.theme--catppuccin-latte .hero.is-info .tabs.is-boxed a,html.theme--catppuccin-latte .hero.is-info .tabs.is-toggle a{color:#fff}html.theme--catppuccin-latte .hero.is-info .tabs.is-boxed a:hover,html.theme--catppuccin-latte .hero.is-info .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--catppuccin-latte .hero.is-info .tabs.is-boxed li.is-active a,html.theme--catppuccin-latte .hero.is-info .tabs.is-boxed li.is-active a:hover,html.theme--catppuccin-latte .hero.is-info .tabs.is-toggle li.is-active a,html.theme--catppuccin-latte .hero.is-info .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#179299}html.theme--catppuccin-latte .hero.is-info.is-bold{background-image:linear-gradient(141deg, #0a7367 0%, #179299 71%, #1591b4 100%)}@media screen and (max-width: 768px){html.theme--catppuccin-latte .hero.is-info.is-bold .navbar-menu{background-image:linear-gradient(141deg, #0a7367 0%, #179299 71%, #1591b4 100%)}}html.theme--catppuccin-latte .hero.is-success{background-color:#40a02b;color:#fff}html.theme--catppuccin-latte .hero.is-success a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--catppuccin-latte .hero.is-success strong{color:inherit}html.theme--catppuccin-latte .hero.is-success .title{color:#fff}html.theme--catppuccin-latte .hero.is-success .subtitle{color:rgba(255,255,255,0.9)}html.theme--catppuccin-latte .hero.is-success .subtitle a:not(.button),html.theme--catppuccin-latte .hero.is-success .subtitle strong{color:#fff}@media screen and (max-width: 1055px){html.theme--catppuccin-latte .hero.is-success .navbar-menu{background-color:#40a02b}}html.theme--catppuccin-latte .hero.is-success .navbar-item,html.theme--catppuccin-latte .hero.is-success .navbar-link{color:rgba(255,255,255,0.7)}html.theme--catppuccin-latte .hero.is-success a.navbar-item:hover,html.theme--catppuccin-latte .hero.is-success a.navbar-item.is-active,html.theme--catppuccin-latte .hero.is-success .navbar-link:hover,html.theme--catppuccin-latte .hero.is-success .navbar-link.is-active{background-color:#388c26;color:#fff}html.theme--catppuccin-latte .hero.is-success .tabs a{color:#fff;opacity:0.9}html.theme--catppuccin-latte .hero.is-success .tabs a:hover{opacity:1}html.theme--catppuccin-latte .hero.is-success .tabs li.is-active a{color:#40a02b !important;opacity:1}html.theme--catppuccin-latte .hero.is-success .tabs.is-boxed a,html.theme--catppuccin-latte .hero.is-success .tabs.is-toggle a{color:#fff}html.theme--catppuccin-latte .hero.is-success .tabs.is-boxed a:hover,html.theme--catppuccin-latte .hero.is-success .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--catppuccin-latte .hero.is-success .tabs.is-boxed li.is-active a,html.theme--catppuccin-latte .hero.is-success .tabs.is-boxed li.is-active a:hover,html.theme--catppuccin-latte .hero.is-success .tabs.is-toggle li.is-active a,html.theme--catppuccin-latte .hero.is-success .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#40a02b}html.theme--catppuccin-latte .hero.is-success.is-bold{background-image:linear-gradient(141deg, #3c7f19 0%, #40a02b 71%, #2dba2b 100%)}@media screen and (max-width: 768px){html.theme--catppuccin-latte .hero.is-success.is-bold .navbar-menu{background-image:linear-gradient(141deg, #3c7f19 0%, #40a02b 71%, #2dba2b 100%)}}html.theme--catppuccin-latte .hero.is-warning{background-color:#df8e1d;color:#fff}html.theme--catppuccin-latte .hero.is-warning a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--catppuccin-latte .hero.is-warning strong{color:inherit}html.theme--catppuccin-latte .hero.is-warning .title{color:#fff}html.theme--catppuccin-latte .hero.is-warning .subtitle{color:rgba(255,255,255,0.9)}html.theme--catppuccin-latte .hero.is-warning .subtitle a:not(.button),html.theme--catppuccin-latte .hero.is-warning .subtitle strong{color:#fff}@media screen and (max-width: 1055px){html.theme--catppuccin-latte .hero.is-warning .navbar-menu{background-color:#df8e1d}}html.theme--catppuccin-latte .hero.is-warning .navbar-item,html.theme--catppuccin-latte .hero.is-warning .navbar-link{color:rgba(255,255,255,0.7)}html.theme--catppuccin-latte .hero.is-warning a.navbar-item:hover,html.theme--catppuccin-latte .hero.is-warning a.navbar-item.is-active,html.theme--catppuccin-latte .hero.is-warning .navbar-link:hover,html.theme--catppuccin-latte .hero.is-warning .navbar-link.is-active{background-color:#c8801a;color:#fff}html.theme--catppuccin-latte .hero.is-warning .tabs a{color:#fff;opacity:0.9}html.theme--catppuccin-latte .hero.is-warning .tabs a:hover{opacity:1}html.theme--catppuccin-latte .hero.is-warning .tabs li.is-active a{color:#df8e1d !important;opacity:1}html.theme--catppuccin-latte .hero.is-warning .tabs.is-boxed a,html.theme--catppuccin-latte .hero.is-warning .tabs.is-toggle a{color:#fff}html.theme--catppuccin-latte .hero.is-warning .tabs.is-boxed a:hover,html.theme--catppuccin-latte .hero.is-warning .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--catppuccin-latte .hero.is-warning .tabs.is-boxed li.is-active a,html.theme--catppuccin-latte .hero.is-warning .tabs.is-boxed li.is-active a:hover,html.theme--catppuccin-latte .hero.is-warning .tabs.is-toggle li.is-active a,html.theme--catppuccin-latte .hero.is-warning .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#df8e1d}html.theme--catppuccin-latte .hero.is-warning.is-bold{background-image:linear-gradient(141deg, #bc560d 0%, #df8e1d 71%, #eaba2b 100%)}@media screen and (max-width: 768px){html.theme--catppuccin-latte .hero.is-warning.is-bold .navbar-menu{background-image:linear-gradient(141deg, #bc560d 0%, #df8e1d 71%, #eaba2b 100%)}}html.theme--catppuccin-latte .hero.is-danger{background-color:#d20f39;color:#fff}html.theme--catppuccin-latte .hero.is-danger a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--catppuccin-latte .hero.is-danger strong{color:inherit}html.theme--catppuccin-latte .hero.is-danger .title{color:#fff}html.theme--catppuccin-latte .hero.is-danger .subtitle{color:rgba(255,255,255,0.9)}html.theme--catppuccin-latte .hero.is-danger .subtitle a:not(.button),html.theme--catppuccin-latte .hero.is-danger .subtitle strong{color:#fff}@media screen and (max-width: 1055px){html.theme--catppuccin-latte .hero.is-danger .navbar-menu{background-color:#d20f39}}html.theme--catppuccin-latte .hero.is-danger .navbar-item,html.theme--catppuccin-latte .hero.is-danger .navbar-link{color:rgba(255,255,255,0.7)}html.theme--catppuccin-latte .hero.is-danger a.navbar-item:hover,html.theme--catppuccin-latte .hero.is-danger a.navbar-item.is-active,html.theme--catppuccin-latte .hero.is-danger .navbar-link:hover,html.theme--catppuccin-latte .hero.is-danger .navbar-link.is-active{background-color:#ba0d33;color:#fff}html.theme--catppuccin-latte .hero.is-danger .tabs a{color:#fff;opacity:0.9}html.theme--catppuccin-latte .hero.is-danger .tabs a:hover{opacity:1}html.theme--catppuccin-latte .hero.is-danger .tabs li.is-active a{color:#d20f39 !important;opacity:1}html.theme--catppuccin-latte .hero.is-danger .tabs.is-boxed a,html.theme--catppuccin-latte .hero.is-danger .tabs.is-toggle a{color:#fff}html.theme--catppuccin-latte .hero.is-danger .tabs.is-boxed a:hover,html.theme--catppuccin-latte .hero.is-danger .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--catppuccin-latte .hero.is-danger .tabs.is-boxed li.is-active a,html.theme--catppuccin-latte .hero.is-danger .tabs.is-boxed li.is-active a:hover,html.theme--catppuccin-latte .hero.is-danger .tabs.is-toggle li.is-active a,html.theme--catppuccin-latte .hero.is-danger .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#d20f39}html.theme--catppuccin-latte .hero.is-danger.is-bold{background-image:linear-gradient(141deg, #ab0343 0%, #d20f39 71%, #f00a16 100%)}@media screen and (max-width: 768px){html.theme--catppuccin-latte .hero.is-danger.is-bold .navbar-menu{background-image:linear-gradient(141deg, #ab0343 0%, #d20f39 71%, #f00a16 100%)}}html.theme--catppuccin-latte .hero.is-small .hero-body,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.hero .hero-body{padding:1.5rem}@media screen and (min-width: 769px),print{html.theme--catppuccin-latte .hero.is-medium .hero-body{padding:9rem 4.5rem}}@media screen and (min-width: 769px),print{html.theme--catppuccin-latte .hero.is-large .hero-body{padding:18rem 6rem}}html.theme--catppuccin-latte .hero.is-halfheight .hero-body,html.theme--catppuccin-latte .hero.is-fullheight .hero-body,html.theme--catppuccin-latte .hero.is-fullheight-with-navbar .hero-body{align-items:center;display:flex}html.theme--catppuccin-latte .hero.is-halfheight .hero-body>.container,html.theme--catppuccin-latte .hero.is-fullheight .hero-body>.container,html.theme--catppuccin-latte .hero.is-fullheight-with-navbar .hero-body>.container{flex-grow:1;flex-shrink:1}html.theme--catppuccin-latte .hero.is-halfheight{min-height:50vh}html.theme--catppuccin-latte .hero.is-fullheight{min-height:100vh}html.theme--catppuccin-latte .hero-video{overflow:hidden}html.theme--catppuccin-latte .hero-video video{left:50%;min-height:100%;min-width:100%;position:absolute;top:50%;transform:translate3d(-50%, -50%, 0)}html.theme--catppuccin-latte .hero-video.is-transparent{opacity:0.3}@media screen and (max-width: 768px){html.theme--catppuccin-latte .hero-video{display:none}}html.theme--catppuccin-latte .hero-buttons{margin-top:1.5rem}@media screen and (max-width: 768px){html.theme--catppuccin-latte .hero-buttons .button{display:flex}html.theme--catppuccin-latte .hero-buttons .button:not(:last-child){margin-bottom:0.75rem}}@media screen and (min-width: 769px),print{html.theme--catppuccin-latte .hero-buttons{display:flex;justify-content:center}html.theme--catppuccin-latte .hero-buttons .button:not(:last-child){margin-right:1.5rem}}html.theme--catppuccin-latte .hero-head,html.theme--catppuccin-latte .hero-foot{flex-grow:0;flex-shrink:0}html.theme--catppuccin-latte .hero-body{flex-grow:1;flex-shrink:0;padding:3rem 1.5rem}@media screen and (min-width: 769px),print{html.theme--catppuccin-latte .hero-body{padding:3rem 3rem}}html.theme--catppuccin-latte .section{padding:3rem 1.5rem}@media screen and (min-width: 1056px){html.theme--catppuccin-latte .section{padding:3rem 3rem}html.theme--catppuccin-latte .section.is-medium{padding:9rem 4.5rem}html.theme--catppuccin-latte .section.is-large{padding:18rem 6rem}}html.theme--catppuccin-latte .footer{background-color:#e6e9ef;padding:3rem 1.5rem 6rem}html.theme--catppuccin-latte h1 .docs-heading-anchor,html.theme--catppuccin-latte h1 .docs-heading-anchor:hover,html.theme--catppuccin-latte h1 .docs-heading-anchor:visited,html.theme--catppuccin-latte h2 .docs-heading-anchor,html.theme--catppuccin-latte h2 .docs-heading-anchor:hover,html.theme--catppuccin-latte h2 .docs-heading-anchor:visited,html.theme--catppuccin-latte h3 .docs-heading-anchor,html.theme--catppuccin-latte h3 .docs-heading-anchor:hover,html.theme--catppuccin-latte h3 .docs-heading-anchor:visited,html.theme--catppuccin-latte h4 .docs-heading-anchor,html.theme--catppuccin-latte h4 .docs-heading-anchor:hover,html.theme--catppuccin-latte h4 .docs-heading-anchor:visited,html.theme--catppuccin-latte h5 .docs-heading-anchor,html.theme--catppuccin-latte h5 .docs-heading-anchor:hover,html.theme--catppuccin-latte h5 .docs-heading-anchor:visited,html.theme--catppuccin-latte h6 .docs-heading-anchor,html.theme--catppuccin-latte h6 .docs-heading-anchor:hover,html.theme--catppuccin-latte h6 .docs-heading-anchor:visited{color:#4c4f69}html.theme--catppuccin-latte h1 .docs-heading-anchor-permalink,html.theme--catppuccin-latte h2 .docs-heading-anchor-permalink,html.theme--catppuccin-latte h3 .docs-heading-anchor-permalink,html.theme--catppuccin-latte h4 .docs-heading-anchor-permalink,html.theme--catppuccin-latte h5 .docs-heading-anchor-permalink,html.theme--catppuccin-latte h6 .docs-heading-anchor-permalink{visibility:hidden;vertical-align:middle;margin-left:0.5em;font-size:0.7rem}html.theme--catppuccin-latte h1 .docs-heading-anchor-permalink::before,html.theme--catppuccin-latte h2 .docs-heading-anchor-permalink::before,html.theme--catppuccin-latte h3 .docs-heading-anchor-permalink::before,html.theme--catppuccin-latte h4 .docs-heading-anchor-permalink::before,html.theme--catppuccin-latte h5 .docs-heading-anchor-permalink::before,html.theme--catppuccin-latte h6 .docs-heading-anchor-permalink::before{font-family:"Font Awesome 6 Free";font-weight:900;content:"\f0c1"}html.theme--catppuccin-latte h1:hover .docs-heading-anchor-permalink,html.theme--catppuccin-latte h2:hover .docs-heading-anchor-permalink,html.theme--catppuccin-latte h3:hover .docs-heading-anchor-permalink,html.theme--catppuccin-latte h4:hover .docs-heading-anchor-permalink,html.theme--catppuccin-latte h5:hover .docs-heading-anchor-permalink,html.theme--catppuccin-latte h6:hover .docs-heading-anchor-permalink{visibility:visible}html.theme--catppuccin-latte .docs-dark-only{display:none !important}html.theme--catppuccin-latte pre{position:relative;overflow:hidden}html.theme--catppuccin-latte pre code,html.theme--catppuccin-latte pre code.hljs{padding:0 .75rem !important;overflow:auto;display:block}html.theme--catppuccin-latte pre code:first-of-type,html.theme--catppuccin-latte pre code.hljs:first-of-type{padding-top:0.5rem !important}html.theme--catppuccin-latte pre code:last-of-type,html.theme--catppuccin-latte pre code.hljs:last-of-type{padding-bottom:0.5rem !important}html.theme--catppuccin-latte 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 6 Free";color:#4c4f69;cursor:pointer;text-align:center}html.theme--catppuccin-latte pre .copy-button:focus,html.theme--catppuccin-latte pre .copy-button:hover{opacity:1;background:rgba(76,79,105,0.1);color:#1e66f5}html.theme--catppuccin-latte pre .copy-button.success{color:#40a02b;opacity:1}html.theme--catppuccin-latte pre .copy-button.error{color:#d20f39;opacity:1}html.theme--catppuccin-latte pre:hover .copy-button{opacity:1}html.theme--catppuccin-latte .admonition{background-color:#e6e9ef;border-style:solid;border-width:2px;border-color:#5c5f77;border-radius:4px;font-size:1rem}html.theme--catppuccin-latte .admonition strong{color:currentColor}html.theme--catppuccin-latte .admonition.is-small,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.admonition{font-size:.75rem}html.theme--catppuccin-latte .admonition.is-medium{font-size:1.25rem}html.theme--catppuccin-latte .admonition.is-large{font-size:1.5rem}html.theme--catppuccin-latte .admonition.is-default{background-color:#e6e9ef;border-color:#5c5f77}html.theme--catppuccin-latte .admonition.is-default>.admonition-header{background-color:rgba(0,0,0,0);color:#5c5f77}html.theme--catppuccin-latte .admonition.is-default>.admonition-body{color:#4c4f69}html.theme--catppuccin-latte .admonition.is-info{background-color:#e6e9ef;border-color:#179299}html.theme--catppuccin-latte .admonition.is-info>.admonition-header{background-color:rgba(0,0,0,0);color:#179299}html.theme--catppuccin-latte .admonition.is-info>.admonition-body{color:#4c4f69}html.theme--catppuccin-latte .admonition.is-success{background-color:#e6e9ef;border-color:#40a02b}html.theme--catppuccin-latte .admonition.is-success>.admonition-header{background-color:rgba(0,0,0,0);color:#40a02b}html.theme--catppuccin-latte .admonition.is-success>.admonition-body{color:#4c4f69}html.theme--catppuccin-latte .admonition.is-warning{background-color:#e6e9ef;border-color:#df8e1d}html.theme--catppuccin-latte .admonition.is-warning>.admonition-header{background-color:rgba(0,0,0,0);color:#df8e1d}html.theme--catppuccin-latte .admonition.is-warning>.admonition-body{color:#4c4f69}html.theme--catppuccin-latte .admonition.is-danger{background-color:#e6e9ef;border-color:#d20f39}html.theme--catppuccin-latte .admonition.is-danger>.admonition-header{background-color:rgba(0,0,0,0);color:#d20f39}html.theme--catppuccin-latte .admonition.is-danger>.admonition-body{color:#4c4f69}html.theme--catppuccin-latte .admonition.is-compat{background-color:#e6e9ef;border-color:#04a5e5}html.theme--catppuccin-latte .admonition.is-compat>.admonition-header{background-color:rgba(0,0,0,0);color:#04a5e5}html.theme--catppuccin-latte .admonition.is-compat>.admonition-body{color:#4c4f69}html.theme--catppuccin-latte .admonition.is-todo{background-color:#e6e9ef;border-color:#8839ef}html.theme--catppuccin-latte .admonition.is-todo>.admonition-header{background-color:rgba(0,0,0,0);color:#8839ef}html.theme--catppuccin-latte .admonition.is-todo>.admonition-body{color:#4c4f69}html.theme--catppuccin-latte .admonition-header{color:#5c5f77;background-color:rgba(0,0,0,0);align-items:center;font-weight:700;justify-content:space-between;line-height:1.25;padding:0.5rem .75rem;position:relative}html.theme--catppuccin-latte .admonition-header:before{font-family:"Font Awesome 6 Free";font-weight:900;margin-right:.75rem;content:"\f06a"}html.theme--catppuccin-latte details.admonition.is-details>.admonition-header{list-style:none}html.theme--catppuccin-latte details.admonition.is-details>.admonition-header:before{font-family:"Font Awesome 6 Free";font-weight:900;content:"\f055"}html.theme--catppuccin-latte details.admonition.is-details[open]>.admonition-header:before{font-family:"Font Awesome 6 Free";font-weight:900;content:"\f056"}html.theme--catppuccin-latte .admonition-body{color:#4c4f69;padding:0.5rem .75rem}html.theme--catppuccin-latte .admonition-body pre{background-color:#e6e9ef}html.theme--catppuccin-latte .admonition-body code{background-color:#e6e9ef}html.theme--catppuccin-latte .docstring{margin-bottom:1em;background-color:rgba(0,0,0,0);border:2px solid #acb0be;border-radius:4px;box-shadow:none;max-width:100%}html.theme--catppuccin-latte .docstring>header{cursor:pointer;display:flex;flex-grow:1;align-items:stretch;padding:0.5rem .75rem;background-color:#e6e9ef;box-shadow:0 0.125em 0.25em rgba(10,10,10,0.1);box-shadow:none;border-bottom:1px solid #acb0be;overflow:auto}html.theme--catppuccin-latte .docstring>header code{background-color:transparent}html.theme--catppuccin-latte .docstring>header .docstring-article-toggle-button{min-width:1.1rem;padding:0.2rem 0.2rem 0.2rem 0}html.theme--catppuccin-latte .docstring>header .docstring-binding{margin-right:0.3em}html.theme--catppuccin-latte .docstring>header .docstring-category{margin-left:0.3em}html.theme--catppuccin-latte .docstring>section{position:relative;padding:.75rem .75rem;border-bottom:1px solid #acb0be}html.theme--catppuccin-latte .docstring>section:last-child{border-bottom:none}html.theme--catppuccin-latte .docstring>section>a.docs-sourcelink{transition:opacity 0.3s;opacity:0;position:absolute;right:.375rem;bottom:.375rem}html.theme--catppuccin-latte .docstring>section>a.docs-sourcelink:focus{opacity:1 !important}html.theme--catppuccin-latte .docstring:hover>section>a.docs-sourcelink{opacity:0.2}html.theme--catppuccin-latte .docstring:focus-within>section>a.docs-sourcelink{opacity:0.2}html.theme--catppuccin-latte .docstring>section:hover a.docs-sourcelink{opacity:1}html.theme--catppuccin-latte .documenter-example-output{background-color:#eff1f5}html.theme--catppuccin-latte .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:#e6e9ef;color:#4c4f69;border-bottom:3px solid rgba(0,0,0,0);padding:10px 35px;text-align:center;font-size:15px}html.theme--catppuccin-latte .outdated-warning-overlay .outdated-warning-closer{position:absolute;top:calc(50% - 10px);right:18px;cursor:pointer;width:12px}html.theme--catppuccin-latte .outdated-warning-overlay a{color:#1e66f5}html.theme--catppuccin-latte .outdated-warning-overlay a:hover{color:#04a5e5}html.theme--catppuccin-latte .content pre{border:2px solid #acb0be;border-radius:4px}html.theme--catppuccin-latte .content code{font-weight:inherit}html.theme--catppuccin-latte .content a code{color:#1e66f5}html.theme--catppuccin-latte .content a:hover code{color:#04a5e5}html.theme--catppuccin-latte .content h1 code,html.theme--catppuccin-latte .content h2 code,html.theme--catppuccin-latte .content h3 code,html.theme--catppuccin-latte .content h4 code,html.theme--catppuccin-latte .content h5 code,html.theme--catppuccin-latte .content h6 code{color:#4c4f69}html.theme--catppuccin-latte .content table{display:block;width:initial;max-width:100%;overflow-x:auto}html.theme--catppuccin-latte .content blockquote>ul:first-child,html.theme--catppuccin-latte .content blockquote>ol:first-child,html.theme--catppuccin-latte .content .admonition-body>ul:first-child,html.theme--catppuccin-latte .content .admonition-body>ol:first-child{margin-top:0}html.theme--catppuccin-latte pre,html.theme--catppuccin-latte code{font-variant-ligatures:no-contextual}html.theme--catppuccin-latte .breadcrumb a.is-disabled{cursor:default;pointer-events:none}html.theme--catppuccin-latte .breadcrumb a.is-disabled,html.theme--catppuccin-latte .breadcrumb a.is-disabled:hover{color:#41445a}html.theme--catppuccin-latte .hljs{background:initial !important}html.theme--catppuccin-latte .katex .katex-mathml{top:0;right:0}html.theme--catppuccin-latte .katex-display,html.theme--catppuccin-latte mjx-container,html.theme--catppuccin-latte .MathJax_Display{margin:0.5em 0 !important}html.theme--catppuccin-latte html{-moz-osx-font-smoothing:auto;-webkit-font-smoothing:auto}html.theme--catppuccin-latte li.no-marker{list-style:none}html.theme--catppuccin-latte #documenter .docs-main>article{overflow-wrap:break-word}html.theme--catppuccin-latte #documenter .docs-main>article .math-container{overflow-x:auto;overflow-y:hidden}@media screen and (min-width: 1056px){html.theme--catppuccin-latte #documenter .docs-main{max-width:52rem;margin-left:20rem;padding-right:1rem}}@media screen and (max-width: 1055px){html.theme--catppuccin-latte #documenter .docs-main{width:100%}html.theme--catppuccin-latte #documenter .docs-main>article{max-width:52rem;margin-left:auto;margin-right:auto;margin-bottom:1rem;padding:0 1rem}html.theme--catppuccin-latte #documenter .docs-main>header,html.theme--catppuccin-latte #documenter .docs-main>nav{max-width:100%;width:100%;margin:0}}html.theme--catppuccin-latte #documenter .docs-main header.docs-navbar{background-color:#eff1f5;border-bottom:1px solid #acb0be;z-index:2;min-height:4rem;margin-bottom:1rem;display:flex}html.theme--catppuccin-latte #documenter .docs-main header.docs-navbar .breadcrumb{flex-grow:1;overflow-x:hidden}html.theme--catppuccin-latte #documenter .docs-main header.docs-navbar .docs-sidebar-button{display:block;font-size:1.5rem;padding-bottom:0.1rem;margin-right:1rem}html.theme--catppuccin-latte #documenter .docs-main header.docs-navbar .docs-right{display:flex;white-space:nowrap;gap:1rem;align-items:center}html.theme--catppuccin-latte #documenter .docs-main header.docs-navbar .docs-right .docs-icon,html.theme--catppuccin-latte #documenter .docs-main header.docs-navbar .docs-right .docs-label{display:inline-block}html.theme--catppuccin-latte #documenter .docs-main header.docs-navbar .docs-right .docs-label{padding:0;margin-left:0.3em}@media screen and (max-width: 1055px){html.theme--catppuccin-latte #documenter .docs-main header.docs-navbar .docs-right .docs-navbar-link{margin-left:0.4rem;margin-right:0.4rem}}html.theme--catppuccin-latte #documenter .docs-main header.docs-navbar>*{margin:auto 0}@media screen and (max-width: 1055px){html.theme--catppuccin-latte #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--catppuccin-latte #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--catppuccin-latte #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--catppuccin-latte #documenter .docs-main section.footnotes{border-top:1px solid #acb0be}html.theme--catppuccin-latte #documenter .docs-main section.footnotes li .tag:first-child,html.theme--catppuccin-latte #documenter .docs-main section.footnotes li .docstring>section>a.docs-sourcelink:first-child,html.theme--catppuccin-latte #documenter .docs-main section.footnotes li .content kbd:first-child,html.theme--catppuccin-latte .content #documenter .docs-main section.footnotes li kbd:first-child{margin-right:1em;margin-bottom:0.4em}html.theme--catppuccin-latte #documenter .docs-main .docs-footer{display:flex;flex-wrap:wrap;margin-left:0;margin-right:0;border-top:1px solid #acb0be;padding-top:1rem;padding-bottom:1rem}@media screen and (max-width: 1055px){html.theme--catppuccin-latte #documenter .docs-main .docs-footer{padding-left:1rem;padding-right:1rem}}html.theme--catppuccin-latte #documenter .docs-main .docs-footer .docs-footer-nextpage,html.theme--catppuccin-latte #documenter .docs-main .docs-footer .docs-footer-prevpage{flex-grow:1}html.theme--catppuccin-latte #documenter .docs-main .docs-footer .docs-footer-nextpage{text-align:right}html.theme--catppuccin-latte #documenter .docs-main .docs-footer .flexbox-break{flex-basis:100%;height:0}html.theme--catppuccin-latte #documenter .docs-main .docs-footer .footer-message{font-size:0.8em;margin:0.5em auto 0 auto;text-align:center}html.theme--catppuccin-latte #documenter .docs-sidebar{display:flex;flex-direction:column;color:#4c4f69;background-color:#e6e9ef;border-right:1px solid #acb0be;padding:0;flex:0 0 18rem;z-index:5;font-size:1rem;position:fixed;left:-18rem;width:18rem;height:100%;transition:left 0.3s}html.theme--catppuccin-latte #documenter .docs-sidebar.visible{left:0;box-shadow:.4rem 0rem .8rem #171717}@media screen and (min-width: 1056px){html.theme--catppuccin-latte #documenter .docs-sidebar.visible{box-shadow:none}}@media screen and (min-width: 1056px){html.theme--catppuccin-latte #documenter .docs-sidebar{left:0;top:0}}html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo{margin-top:1rem;padding:0 1rem}html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img{max-height:6rem;margin:auto}html.theme--catppuccin-latte #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--catppuccin-latte #documenter .docs-sidebar .docs-package-name .docs-autofit{max-width:16.2rem}html.theme--catppuccin-latte #documenter .docs-sidebar .docs-package-name a,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-package-name a:hover{color:#4c4f69}html.theme--catppuccin-latte #documenter .docs-sidebar .docs-version-selector{border-top:1px solid #acb0be;display:none;padding:0.5rem}html.theme--catppuccin-latte #documenter .docs-sidebar .docs-version-selector.visible{display:flex}html.theme--catppuccin-latte #documenter .docs-sidebar ul.docs-menu{flex-grow:1;user-select:none;border-top:1px solid #acb0be;padding-bottom:1.5rem}html.theme--catppuccin-latte #documenter .docs-sidebar ul.docs-menu>li>.tocitem{font-weight:bold}html.theme--catppuccin-latte #documenter .docs-sidebar ul.docs-menu>li li{font-size:.95rem;margin-left:1em;border-left:1px solid #acb0be}html.theme--catppuccin-latte #documenter .docs-sidebar ul.docs-menu input.collapse-toggle{display:none}html.theme--catppuccin-latte #documenter .docs-sidebar ul.docs-menu ul.collapsed{display:none}html.theme--catppuccin-latte #documenter .docs-sidebar ul.docs-menu input:checked~ul.collapsed{display:block}html.theme--catppuccin-latte #documenter .docs-sidebar ul.docs-menu label.tocitem{display:flex}html.theme--catppuccin-latte #documenter .docs-sidebar ul.docs-menu label.tocitem .docs-label{flex-grow:2}html.theme--catppuccin-latte #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}html.theme--catppuccin-latte #documenter .docs-sidebar ul.docs-menu label.tocitem .docs-chevron::before{font-family:"Font Awesome 6 Free";font-weight:900;content:"\f054"}html.theme--catppuccin-latte #documenter .docs-sidebar ul.docs-menu input:checked~label.tocitem .docs-chevron::before{content:"\f078"}html.theme--catppuccin-latte #documenter .docs-sidebar ul.docs-menu .tocitem{display:block;padding:0.5rem 0.5rem}html.theme--catppuccin-latte #documenter .docs-sidebar ul.docs-menu .tocitem,html.theme--catppuccin-latte #documenter .docs-sidebar ul.docs-menu .tocitem:hover{color:#4c4f69;background:#e6e9ef}html.theme--catppuccin-latte #documenter .docs-sidebar ul.docs-menu a.tocitem:hover,html.theme--catppuccin-latte #documenter .docs-sidebar ul.docs-menu label.tocitem:hover{color:#4c4f69;background-color:#f2f4f7}html.theme--catppuccin-latte #documenter .docs-sidebar ul.docs-menu li.is-active{border-top:1px solid #acb0be;border-bottom:1px solid #acb0be;background-color:#dce0e8}html.theme--catppuccin-latte #documenter .docs-sidebar ul.docs-menu li.is-active .tocitem,html.theme--catppuccin-latte #documenter .docs-sidebar ul.docs-menu li.is-active .tocitem:hover{background-color:#dce0e8;color:#4c4f69}html.theme--catppuccin-latte #documenter .docs-sidebar ul.docs-menu li.is-active ul.internal .tocitem:hover{background-color:#f2f4f7;color:#4c4f69}html.theme--catppuccin-latte #documenter .docs-sidebar ul.docs-menu>li.is-active:first-child{border-top:none}html.theme--catppuccin-latte #documenter .docs-sidebar ul.docs-menu ul.internal{margin:0 0.5rem 0.5rem;border-top:1px solid #acb0be}html.theme--catppuccin-latte #documenter .docs-sidebar ul.docs-menu ul.internal li{font-size:.85rem;border-left:none;margin-left:0;margin-top:0.5rem}html.theme--catppuccin-latte #documenter .docs-sidebar ul.docs-menu ul.internal .tocitem{width:100%;padding:0}html.theme--catppuccin-latte #documenter .docs-sidebar ul.docs-menu ul.internal .tocitem::before{content:"⚬";margin-right:0.4em}html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search{margin:auto;margin-top:0.5rem;margin-bottom:0.5rem}html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input{width:14.4rem}html.theme--catppuccin-latte #documenter .docs-sidebar #documenter-search-query{color:#868c98;width:14.4rem;box-shadow:inset 0 1px 2px rgba(10,10,10,0.1)}@media screen and (min-width: 1056px){html.theme--catppuccin-latte #documenter .docs-sidebar ul.docs-menu{overflow-y:auto;-webkit-overflow-scroll:touch}html.theme--catppuccin-latte #documenter .docs-sidebar ul.docs-menu::-webkit-scrollbar{width:.3rem;background:none}html.theme--catppuccin-latte #documenter .docs-sidebar ul.docs-menu::-webkit-scrollbar-thumb{border-radius:5px 0px 0px 5px;background:#fff}html.theme--catppuccin-latte #documenter .docs-sidebar ul.docs-menu::-webkit-scrollbar-thumb:hover{background:#fff}}@media screen and (max-width: 1055px){html.theme--catppuccin-latte #documenter .docs-sidebar{overflow-y:auto;-webkit-overflow-scroll:touch}html.theme--catppuccin-latte #documenter .docs-sidebar::-webkit-scrollbar{width:.3rem;background:none}html.theme--catppuccin-latte #documenter .docs-sidebar::-webkit-scrollbar-thumb{border-radius:5px 0px 0px 5px;background:#fff}html.theme--catppuccin-latte #documenter .docs-sidebar::-webkit-scrollbar-thumb:hover{background:#fff}}html.theme--catppuccin-latte kbd.search-modal-key-hints{border-radius:0.25rem;border:1px solid rgba(245,245,245,0.6);box-shadow:0 2px 0 1px rgba(245,245,245,0.6);cursor:default;font-size:0.9rem;line-height:1.5;min-width:0.75rem;text-align:center;padding:0.1rem 0.3rem;position:relative;top:-1px}html.theme--catppuccin-latte .search-min-width-50{min-width:50%}html.theme--catppuccin-latte .search-min-height-100{min-height:100%}html.theme--catppuccin-latte .search-modal-card-body{max-height:calc(100vh - 15rem)}html.theme--catppuccin-latte .search-result-link{border-radius:0.7em;transition:all 300ms}html.theme--catppuccin-latte .search-result-link:hover,html.theme--catppuccin-latte .search-result-link:focus{background-color:rgba(0,128,128,0.1)}html.theme--catppuccin-latte .search-result-link .property-search-result-badge,html.theme--catppuccin-latte .search-result-link .search-filter{transition:all 300ms}html.theme--catppuccin-latte .property-search-result-badge,html.theme--catppuccin-latte .search-filter{padding:0.15em 0.5em;font-size:0.8em;font-style:italic;text-transform:none !important;line-height:1.5;color:#f5f5f5;background-color:rgba(51,65,85,0.501961);border-radius:0.6rem}html.theme--catppuccin-latte .search-result-link:hover .property-search-result-badge,html.theme--catppuccin-latte .search-result-link:hover .search-filter,html.theme--catppuccin-latte .search-result-link:focus .property-search-result-badge,html.theme--catppuccin-latte .search-result-link:focus .search-filter{color:#333;background-color:#f1f5f9}html.theme--catppuccin-latte .search-filter{color:#333;background-color:#f5f5f5;transition:all 300ms}html.theme--catppuccin-latte .search-filter:hover,html.theme--catppuccin-latte .search-filter:focus{color:#333}html.theme--catppuccin-latte .search-filter-selected{color:#ccd0da;background-color:#7287fd}html.theme--catppuccin-latte .search-filter-selected:hover,html.theme--catppuccin-latte .search-filter-selected:focus{color:#ccd0da}html.theme--catppuccin-latte .search-result-highlight{background-color:#ffdd57;color:black}html.theme--catppuccin-latte .search-divider{border-bottom:1px solid #acb0be}html.theme--catppuccin-latte .search-result-title{width:85%;color:#f5f5f5}html.theme--catppuccin-latte .search-result-code-title{font-size:0.875rem;font-family:"JuliaMono","SFMono-Regular","Menlo","Consolas","Liberation Mono","DejaVu Sans Mono",monospace}html.theme--catppuccin-latte #search-modal .modal-card-body::-webkit-scrollbar,html.theme--catppuccin-latte #search-modal .filter-tabs::-webkit-scrollbar{height:10px;width:10px;background-color:transparent}html.theme--catppuccin-latte #search-modal .modal-card-body::-webkit-scrollbar-thumb,html.theme--catppuccin-latte #search-modal .filter-tabs::-webkit-scrollbar-thumb{background-color:gray;border-radius:1rem}html.theme--catppuccin-latte #search-modal .modal-card-body::-webkit-scrollbar-track,html.theme--catppuccin-latte #search-modal .filter-tabs::-webkit-scrollbar-track{-webkit-box-shadow:inset 0 0 6px rgba(0,0,0,0.6);background-color:transparent}html.theme--catppuccin-latte .w-100{width:100%}html.theme--catppuccin-latte .gap-2{gap:0.5rem}html.theme--catppuccin-latte .gap-4{gap:1rem}html.theme--catppuccin-latte .gap-8{gap:2rem}html.theme--catppuccin-latte{background-color:#eff1f5;font-size:16px;min-width:300px;overflow-x:auto;overflow-y:scroll;text-rendering:optimizeLegibility;text-size-adjust:100%}html.theme--catppuccin-latte a{transition:all 200ms ease}html.theme--catppuccin-latte .label{color:#4c4f69}html.theme--catppuccin-latte .button,html.theme--catppuccin-latte .control.has-icons-left .icon,html.theme--catppuccin-latte .control.has-icons-right .icon,html.theme--catppuccin-latte .input,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input,html.theme--catppuccin-latte .pagination-ellipsis,html.theme--catppuccin-latte .pagination-link,html.theme--catppuccin-latte .pagination-next,html.theme--catppuccin-latte .pagination-previous,html.theme--catppuccin-latte .select,html.theme--catppuccin-latte .select select,html.theme--catppuccin-latte .textarea{height:2.5em;color:#4c4f69}html.theme--catppuccin-latte .input,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input,html.theme--catppuccin-latte .textarea{transition:all 200ms ease;box-shadow:none;border-width:1px;padding-left:1em;padding-right:1em;color:#4c4f69}html.theme--catppuccin-latte .select:after,html.theme--catppuccin-latte .select select{border-width:1px}html.theme--catppuccin-latte .menu-list a{transition:all 300ms ease}html.theme--catppuccin-latte .modal-card-foot,html.theme--catppuccin-latte .modal-card-head{border-color:#acb0be}html.theme--catppuccin-latte .navbar{border-radius:.4em}html.theme--catppuccin-latte .navbar.is-transparent{background:none}html.theme--catppuccin-latte .navbar.is-primary .navbar-dropdown a.navbar-item.is-active,html.theme--catppuccin-latte .docstring>section>a.navbar.docs-sourcelink .navbar-dropdown a.navbar-item.is-active{background-color:#1e66f5}@media screen and (max-width: 1055px){html.theme--catppuccin-latte .navbar .navbar-menu{background-color:#1e66f5;border-radius:0 0 .4em .4em}}html.theme--catppuccin-latte .docstring>section>a.docs-sourcelink:not(body){color:#ccd0da}html.theme--catppuccin-latte .tag.is-link:not(body),html.theme--catppuccin-latte .docstring>section>a.is-link.docs-sourcelink:not(body),html.theme--catppuccin-latte .content kbd.is-link:not(body){color:#ccd0da}html.theme--catppuccin-latte .ansi span.sgr1{font-weight:bolder}html.theme--catppuccin-latte .ansi span.sgr2{font-weight:lighter}html.theme--catppuccin-latte .ansi span.sgr3{font-style:italic}html.theme--catppuccin-latte .ansi span.sgr4{text-decoration:underline}html.theme--catppuccin-latte .ansi span.sgr7{color:#eff1f5;background-color:#4c4f69}html.theme--catppuccin-latte .ansi span.sgr8{color:transparent}html.theme--catppuccin-latte .ansi span.sgr8 span{color:transparent}html.theme--catppuccin-latte .ansi span.sgr9{text-decoration:line-through}html.theme--catppuccin-latte .ansi span.sgr30{color:#5c5f77}html.theme--catppuccin-latte .ansi span.sgr31{color:#d20f39}html.theme--catppuccin-latte .ansi span.sgr32{color:#40a02b}html.theme--catppuccin-latte .ansi span.sgr33{color:#df8e1d}html.theme--catppuccin-latte .ansi span.sgr34{color:#1e66f5}html.theme--catppuccin-latte .ansi span.sgr35{color:#ea76cb}html.theme--catppuccin-latte .ansi span.sgr36{color:#179299}html.theme--catppuccin-latte .ansi span.sgr37{color:#acb0be}html.theme--catppuccin-latte .ansi span.sgr40{background-color:#5c5f77}html.theme--catppuccin-latte .ansi span.sgr41{background-color:#d20f39}html.theme--catppuccin-latte .ansi span.sgr42{background-color:#40a02b}html.theme--catppuccin-latte .ansi span.sgr43{background-color:#df8e1d}html.theme--catppuccin-latte .ansi span.sgr44{background-color:#1e66f5}html.theme--catppuccin-latte .ansi span.sgr45{background-color:#ea76cb}html.theme--catppuccin-latte .ansi span.sgr46{background-color:#179299}html.theme--catppuccin-latte .ansi span.sgr47{background-color:#acb0be}html.theme--catppuccin-latte .ansi span.sgr90{color:#6c6f85}html.theme--catppuccin-latte .ansi span.sgr91{color:#d20f39}html.theme--catppuccin-latte .ansi span.sgr92{color:#40a02b}html.theme--catppuccin-latte .ansi span.sgr93{color:#df8e1d}html.theme--catppuccin-latte .ansi span.sgr94{color:#1e66f5}html.theme--catppuccin-latte .ansi span.sgr95{color:#ea76cb}html.theme--catppuccin-latte .ansi span.sgr96{color:#179299}html.theme--catppuccin-latte .ansi span.sgr97{color:#bcc0cc}html.theme--catppuccin-latte .ansi span.sgr100{background-color:#6c6f85}html.theme--catppuccin-latte .ansi span.sgr101{background-color:#d20f39}html.theme--catppuccin-latte .ansi span.sgr102{background-color:#40a02b}html.theme--catppuccin-latte .ansi span.sgr103{background-color:#df8e1d}html.theme--catppuccin-latte .ansi span.sgr104{background-color:#1e66f5}html.theme--catppuccin-latte .ansi span.sgr105{background-color:#ea76cb}html.theme--catppuccin-latte .ansi span.sgr106{background-color:#179299}html.theme--catppuccin-latte .ansi span.sgr107{background-color:#bcc0cc}html.theme--catppuccin-latte code.language-julia-repl>span.hljs-meta{color:#40a02b;font-weight:bolder}html.theme--catppuccin-latte code .hljs{color:#4c4f69;background:#eff1f5}html.theme--catppuccin-latte code .hljs-keyword{color:#8839ef}html.theme--catppuccin-latte code .hljs-built_in{color:#d20f39}html.theme--catppuccin-latte code .hljs-type{color:#df8e1d}html.theme--catppuccin-latte code .hljs-literal{color:#fe640b}html.theme--catppuccin-latte code .hljs-number{color:#fe640b}html.theme--catppuccin-latte code .hljs-operator{color:#179299}html.theme--catppuccin-latte code .hljs-punctuation{color:#5c5f77}html.theme--catppuccin-latte code .hljs-property{color:#179299}html.theme--catppuccin-latte code .hljs-regexp{color:#ea76cb}html.theme--catppuccin-latte code .hljs-string{color:#40a02b}html.theme--catppuccin-latte code .hljs-char.escape_{color:#40a02b}html.theme--catppuccin-latte code .hljs-subst{color:#6c6f85}html.theme--catppuccin-latte code .hljs-symbol{color:#dd7878}html.theme--catppuccin-latte code .hljs-variable{color:#8839ef}html.theme--catppuccin-latte code .hljs-variable.language_{color:#8839ef}html.theme--catppuccin-latte code .hljs-variable.constant_{color:#fe640b}html.theme--catppuccin-latte code .hljs-title{color:#1e66f5}html.theme--catppuccin-latte code .hljs-title.class_{color:#df8e1d}html.theme--catppuccin-latte code .hljs-title.function_{color:#1e66f5}html.theme--catppuccin-latte code .hljs-params{color:#4c4f69}html.theme--catppuccin-latte code .hljs-comment{color:#acb0be}html.theme--catppuccin-latte code .hljs-doctag{color:#d20f39}html.theme--catppuccin-latte code .hljs-meta{color:#fe640b}html.theme--catppuccin-latte code .hljs-section{color:#1e66f5}html.theme--catppuccin-latte code .hljs-tag{color:#6c6f85}html.theme--catppuccin-latte code .hljs-name{color:#8839ef}html.theme--catppuccin-latte code .hljs-attr{color:#1e66f5}html.theme--catppuccin-latte code .hljs-attribute{color:#40a02b}html.theme--catppuccin-latte code .hljs-bullet{color:#179299}html.theme--catppuccin-latte code .hljs-code{color:#40a02b}html.theme--catppuccin-latte code .hljs-emphasis{color:#d20f39;font-style:italic}html.theme--catppuccin-latte code .hljs-strong{color:#d20f39;font-weight:bold}html.theme--catppuccin-latte code .hljs-formula{color:#179299}html.theme--catppuccin-latte code .hljs-link{color:#209fb5;font-style:italic}html.theme--catppuccin-latte code .hljs-quote{color:#40a02b;font-style:italic}html.theme--catppuccin-latte code .hljs-selector-tag{color:#df8e1d}html.theme--catppuccin-latte code .hljs-selector-id{color:#1e66f5}html.theme--catppuccin-latte code .hljs-selector-class{color:#179299}html.theme--catppuccin-latte code .hljs-selector-attr{color:#8839ef}html.theme--catppuccin-latte code .hljs-selector-pseudo{color:#179299}html.theme--catppuccin-latte code .hljs-template-tag{color:#dd7878}html.theme--catppuccin-latte code .hljs-template-variable{color:#dd7878}html.theme--catppuccin-latte code .hljs-addition{color:#40a02b;background:rgba(166,227,161,0.15)}html.theme--catppuccin-latte code .hljs-deletion{color:#d20f39;background:rgba(243,139,168,0.15)}html.theme--catppuccin-latte .search-result-link{border-radius:0.7em;transition:all 300ms}html.theme--catppuccin-latte .search-result-link:hover,html.theme--catppuccin-latte .search-result-link:focus{background-color:#ccd0da}html.theme--catppuccin-latte .search-result-link .property-search-result-badge,html.theme--catppuccin-latte .search-result-link .search-filter{transition:all 300ms}html.theme--catppuccin-latte .search-result-link:hover .property-search-result-badge,html.theme--catppuccin-latte .search-result-link:hover .search-filter,html.theme--catppuccin-latte .search-result-link:focus .property-search-result-badge,html.theme--catppuccin-latte .search-result-link:focus .search-filter{color:#ccd0da !important;background-color:#7287fd !important}html.theme--catppuccin-latte .search-result-title{color:#4c4f69}html.theme--catppuccin-latte .search-result-highlight{background-color:#d20f39;color:#e6e9ef}html.theme--catppuccin-latte .search-divider{border-bottom:1px solid #5e6d6f50}html.theme--catppuccin-latte .w-100{width:100%}html.theme--catppuccin-latte .gap-2{gap:0.5rem}html.theme--catppuccin-latte .gap-4{gap:1rem} diff --git a/previews/PR4245/assets/themes/catppuccin-macchiato.css b/previews/PR4245/assets/themes/catppuccin-macchiato.css deleted file mode 100644 index a9cf9c573f08..000000000000 --- a/previews/PR4245/assets/themes/catppuccin-macchiato.css +++ /dev/null @@ -1 +0,0 @@ -html.theme--catppuccin-macchiato .pagination-previous,html.theme--catppuccin-macchiato .pagination-next,html.theme--catppuccin-macchiato .pagination-link,html.theme--catppuccin-macchiato .pagination-ellipsis,html.theme--catppuccin-macchiato .file-cta,html.theme--catppuccin-macchiato .file-name,html.theme--catppuccin-macchiato .select select,html.theme--catppuccin-macchiato .textarea,html.theme--catppuccin-macchiato .input,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input,html.theme--catppuccin-macchiato .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:1rem;height:2.5em;justify-content:flex-start;line-height:1.5;padding-bottom:calc(0.5em - 1px);padding-left:calc(0.75em - 1px);padding-right:calc(0.75em - 1px);padding-top:calc(0.5em - 1px);position:relative;vertical-align:top}html.theme--catppuccin-macchiato .pagination-previous:focus,html.theme--catppuccin-macchiato .pagination-next:focus,html.theme--catppuccin-macchiato .pagination-link:focus,html.theme--catppuccin-macchiato .pagination-ellipsis:focus,html.theme--catppuccin-macchiato .file-cta:focus,html.theme--catppuccin-macchiato .file-name:focus,html.theme--catppuccin-macchiato .select select:focus,html.theme--catppuccin-macchiato .textarea:focus,html.theme--catppuccin-macchiato .input:focus,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input:focus,html.theme--catppuccin-macchiato .button:focus,html.theme--catppuccin-macchiato .is-focused.pagination-previous,html.theme--catppuccin-macchiato .is-focused.pagination-next,html.theme--catppuccin-macchiato .is-focused.pagination-link,html.theme--catppuccin-macchiato .is-focused.pagination-ellipsis,html.theme--catppuccin-macchiato .is-focused.file-cta,html.theme--catppuccin-macchiato .is-focused.file-name,html.theme--catppuccin-macchiato .select select.is-focused,html.theme--catppuccin-macchiato .is-focused.textarea,html.theme--catppuccin-macchiato .is-focused.input,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--catppuccin-macchiato .is-focused.button,html.theme--catppuccin-macchiato .pagination-previous:active,html.theme--catppuccin-macchiato .pagination-next:active,html.theme--catppuccin-macchiato .pagination-link:active,html.theme--catppuccin-macchiato .pagination-ellipsis:active,html.theme--catppuccin-macchiato .file-cta:active,html.theme--catppuccin-macchiato .file-name:active,html.theme--catppuccin-macchiato .select select:active,html.theme--catppuccin-macchiato .textarea:active,html.theme--catppuccin-macchiato .input:active,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input:active,html.theme--catppuccin-macchiato .button:active,html.theme--catppuccin-macchiato .is-active.pagination-previous,html.theme--catppuccin-macchiato .is-active.pagination-next,html.theme--catppuccin-macchiato .is-active.pagination-link,html.theme--catppuccin-macchiato .is-active.pagination-ellipsis,html.theme--catppuccin-macchiato .is-active.file-cta,html.theme--catppuccin-macchiato .is-active.file-name,html.theme--catppuccin-macchiato .select select.is-active,html.theme--catppuccin-macchiato .is-active.textarea,html.theme--catppuccin-macchiato .is-active.input,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-active,html.theme--catppuccin-macchiato .is-active.button{outline:none}html.theme--catppuccin-macchiato .pagination-previous[disabled],html.theme--catppuccin-macchiato .pagination-next[disabled],html.theme--catppuccin-macchiato .pagination-link[disabled],html.theme--catppuccin-macchiato .pagination-ellipsis[disabled],html.theme--catppuccin-macchiato .file-cta[disabled],html.theme--catppuccin-macchiato .file-name[disabled],html.theme--catppuccin-macchiato .select select[disabled],html.theme--catppuccin-macchiato .textarea[disabled],html.theme--catppuccin-macchiato .input[disabled],html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input[disabled],html.theme--catppuccin-macchiato .button[disabled],fieldset[disabled] html.theme--catppuccin-macchiato .pagination-previous,html.theme--catppuccin-macchiato fieldset[disabled] .pagination-previous,fieldset[disabled] html.theme--catppuccin-macchiato .pagination-next,html.theme--catppuccin-macchiato fieldset[disabled] .pagination-next,fieldset[disabled] html.theme--catppuccin-macchiato .pagination-link,html.theme--catppuccin-macchiato fieldset[disabled] .pagination-link,fieldset[disabled] html.theme--catppuccin-macchiato .pagination-ellipsis,html.theme--catppuccin-macchiato fieldset[disabled] .pagination-ellipsis,fieldset[disabled] html.theme--catppuccin-macchiato .file-cta,html.theme--catppuccin-macchiato fieldset[disabled] .file-cta,fieldset[disabled] html.theme--catppuccin-macchiato .file-name,html.theme--catppuccin-macchiato fieldset[disabled] .file-name,fieldset[disabled] html.theme--catppuccin-macchiato .select select,fieldset[disabled] html.theme--catppuccin-macchiato .textarea,fieldset[disabled] html.theme--catppuccin-macchiato .input,fieldset[disabled] html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input,html.theme--catppuccin-macchiato fieldset[disabled] .select select,html.theme--catppuccin-macchiato .select fieldset[disabled] select,html.theme--catppuccin-macchiato fieldset[disabled] .textarea,html.theme--catppuccin-macchiato fieldset[disabled] .input,html.theme--catppuccin-macchiato fieldset[disabled] #documenter .docs-sidebar form.docs-search>input,html.theme--catppuccin-macchiato #documenter .docs-sidebar fieldset[disabled] form.docs-search>input,fieldset[disabled] html.theme--catppuccin-macchiato .button,html.theme--catppuccin-macchiato fieldset[disabled] .button{cursor:not-allowed}html.theme--catppuccin-macchiato .tabs,html.theme--catppuccin-macchiato .pagination-previous,html.theme--catppuccin-macchiato .pagination-next,html.theme--catppuccin-macchiato .pagination-link,html.theme--catppuccin-macchiato .pagination-ellipsis,html.theme--catppuccin-macchiato .breadcrumb,html.theme--catppuccin-macchiato .file,html.theme--catppuccin-macchiato .button,.is-unselectable{-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}html.theme--catppuccin-macchiato .navbar-link:not(.is-arrowless)::after,html.theme--catppuccin-macchiato .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--catppuccin-macchiato .admonition:not(:last-child),html.theme--catppuccin-macchiato .tabs:not(:last-child),html.theme--catppuccin-macchiato .pagination:not(:last-child),html.theme--catppuccin-macchiato .message:not(:last-child),html.theme--catppuccin-macchiato .level:not(:last-child),html.theme--catppuccin-macchiato .breadcrumb:not(:last-child),html.theme--catppuccin-macchiato .block:not(:last-child),html.theme--catppuccin-macchiato .title:not(:last-child),html.theme--catppuccin-macchiato .subtitle:not(:last-child),html.theme--catppuccin-macchiato .table-container:not(:last-child),html.theme--catppuccin-macchiato .table:not(:last-child),html.theme--catppuccin-macchiato .progress:not(:last-child),html.theme--catppuccin-macchiato .notification:not(:last-child),html.theme--catppuccin-macchiato .content:not(:last-child),html.theme--catppuccin-macchiato .box:not(:last-child){margin-bottom:1.5rem}html.theme--catppuccin-macchiato .modal-close,html.theme--catppuccin-macchiato .delete{-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-moz-appearance:none;-webkit-appearance:none;background-color:rgba(10,10,10,0.2);border:none;border-radius:9999px;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--catppuccin-macchiato .modal-close::before,html.theme--catppuccin-macchiato .delete::before,html.theme--catppuccin-macchiato .modal-close::after,html.theme--catppuccin-macchiato .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--catppuccin-macchiato .modal-close::before,html.theme--catppuccin-macchiato .delete::before{height:2px;width:50%}html.theme--catppuccin-macchiato .modal-close::after,html.theme--catppuccin-macchiato .delete::after{height:50%;width:2px}html.theme--catppuccin-macchiato .modal-close:hover,html.theme--catppuccin-macchiato .delete:hover,html.theme--catppuccin-macchiato .modal-close:focus,html.theme--catppuccin-macchiato .delete:focus{background-color:rgba(10,10,10,0.3)}html.theme--catppuccin-macchiato .modal-close:active,html.theme--catppuccin-macchiato .delete:active{background-color:rgba(10,10,10,0.4)}html.theme--catppuccin-macchiato .is-small.modal-close,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.modal-close,html.theme--catppuccin-macchiato .is-small.delete,html.theme--catppuccin-macchiato #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--catppuccin-macchiato .is-medium.modal-close,html.theme--catppuccin-macchiato .is-medium.delete{height:24px;max-height:24px;max-width:24px;min-height:24px;min-width:24px;width:24px}html.theme--catppuccin-macchiato .is-large.modal-close,html.theme--catppuccin-macchiato .is-large.delete{height:32px;max-height:32px;max-width:32px;min-height:32px;min-width:32px;width:32px}html.theme--catppuccin-macchiato .control.is-loading::after,html.theme--catppuccin-macchiato .select.is-loading::after,html.theme--catppuccin-macchiato .loader,html.theme--catppuccin-macchiato .button.is-loading::after{animation:spinAround 500ms infinite linear;border:2px solid #8087a2;border-radius:9999px;border-right-color:transparent;border-top-color:transparent;content:"";display:block;height:1em;position:relative;width:1em}html.theme--catppuccin-macchiato .hero-video,html.theme--catppuccin-macchiato .modal-background,html.theme--catppuccin-macchiato .modal,html.theme--catppuccin-macchiato .image.is-square img,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-square img,html.theme--catppuccin-macchiato .image.is-square .has-ratio,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-square .has-ratio,html.theme--catppuccin-macchiato .image.is-1by1 img,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-1by1 img,html.theme--catppuccin-macchiato .image.is-1by1 .has-ratio,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-1by1 .has-ratio,html.theme--catppuccin-macchiato .image.is-5by4 img,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-5by4 img,html.theme--catppuccin-macchiato .image.is-5by4 .has-ratio,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-5by4 .has-ratio,html.theme--catppuccin-macchiato .image.is-4by3 img,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-4by3 img,html.theme--catppuccin-macchiato .image.is-4by3 .has-ratio,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-4by3 .has-ratio,html.theme--catppuccin-macchiato .image.is-3by2 img,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-3by2 img,html.theme--catppuccin-macchiato .image.is-3by2 .has-ratio,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-3by2 .has-ratio,html.theme--catppuccin-macchiato .image.is-5by3 img,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-5by3 img,html.theme--catppuccin-macchiato .image.is-5by3 .has-ratio,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-5by3 .has-ratio,html.theme--catppuccin-macchiato .image.is-16by9 img,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-16by9 img,html.theme--catppuccin-macchiato .image.is-16by9 .has-ratio,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-16by9 .has-ratio,html.theme--catppuccin-macchiato .image.is-2by1 img,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-2by1 img,html.theme--catppuccin-macchiato .image.is-2by1 .has-ratio,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-2by1 .has-ratio,html.theme--catppuccin-macchiato .image.is-3by1 img,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-3by1 img,html.theme--catppuccin-macchiato .image.is-3by1 .has-ratio,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-3by1 .has-ratio,html.theme--catppuccin-macchiato .image.is-4by5 img,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-4by5 img,html.theme--catppuccin-macchiato .image.is-4by5 .has-ratio,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-4by5 .has-ratio,html.theme--catppuccin-macchiato .image.is-3by4 img,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-3by4 img,html.theme--catppuccin-macchiato .image.is-3by4 .has-ratio,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-3by4 .has-ratio,html.theme--catppuccin-macchiato .image.is-2by3 img,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-2by3 img,html.theme--catppuccin-macchiato .image.is-2by3 .has-ratio,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-2by3 .has-ratio,html.theme--catppuccin-macchiato .image.is-3by5 img,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-3by5 img,html.theme--catppuccin-macchiato .image.is-3by5 .has-ratio,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-3by5 .has-ratio,html.theme--catppuccin-macchiato .image.is-9by16 img,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-9by16 img,html.theme--catppuccin-macchiato .image.is-9by16 .has-ratio,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-9by16 .has-ratio,html.theme--catppuccin-macchiato .image.is-1by2 img,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-1by2 img,html.theme--catppuccin-macchiato .image.is-1by2 .has-ratio,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-1by2 .has-ratio,html.theme--catppuccin-macchiato .image.is-1by3 img,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-1by3 img,html.theme--catppuccin-macchiato .image.is-1by3 .has-ratio,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-1by3 .has-ratio,.is-overlay{bottom:0;left:0;position:absolute;right:0;top:0}html.theme--catppuccin-macchiato .navbar-burger{-moz-appearance:none;-webkit-appearance:none;appearance:none;background:none;border:none;color:currentColor;font-family:inherit;font-size:1em;margin:0;padding:0}/*! minireset.css v0.0.6 | 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,video{height:auto;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:inherit}.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:#363a4f !important}a.has-text-dark:hover,a.has-text-dark:focus{color:#212431 !important}.has-background-dark{background-color:#363a4f !important}.has-text-primary{color:#8aadf4 !important}a.has-text-primary:hover,a.has-text-primary:focus{color:#5b8cf0 !important}.has-background-primary{background-color:#8aadf4 !important}.has-text-primary-light{color:#ecf2fd !important}a.has-text-primary-light:hover,a.has-text-primary-light:focus{color:#bed1f9 !important}.has-background-primary-light{background-color:#ecf2fd !important}.has-text-primary-dark{color:#0e3b95 !important}a.has-text-primary-dark:hover,a.has-text-primary-dark:focus{color:#124dc4 !important}.has-background-primary-dark{background-color:#0e3b95 !important}.has-text-link{color:#8aadf4 !important}a.has-text-link:hover,a.has-text-link:focus{color:#5b8cf0 !important}.has-background-link{background-color:#8aadf4 !important}.has-text-link-light{color:#ecf2fd !important}a.has-text-link-light:hover,a.has-text-link-light:focus{color:#bed1f9 !important}.has-background-link-light{background-color:#ecf2fd !important}.has-text-link-dark{color:#0e3b95 !important}a.has-text-link-dark:hover,a.has-text-link-dark:focus{color:#124dc4 !important}.has-background-link-dark{background-color:#0e3b95 !important}.has-text-info{color:#8bd5ca !important}a.has-text-info:hover,a.has-text-info:focus{color:#66c7b9 !important}.has-background-info{background-color:#8bd5ca !important}.has-text-info-light{color:#f0faf8 !important}a.has-text-info-light:hover,a.has-text-info-light:focus{color:#cbece7 !important}.has-background-info-light{background-color:#f0faf8 !important}.has-text-info-dark{color:#276d62 !important}a.has-text-info-dark:hover,a.has-text-info-dark:focus{color:#359284 !important}.has-background-info-dark{background-color:#276d62 !important}.has-text-success{color:#a6da95 !important}a.has-text-success:hover,a.has-text-success:focus{color:#86cd6f !important}.has-background-success{background-color:#a6da95 !important}.has-text-success-light{color:#f2faf0 !important}a.has-text-success-light:hover,a.has-text-success-light:focus{color:#d3edca !important}.has-background-success-light{background-color:#f2faf0 !important}.has-text-success-dark{color:#386e26 !important}a.has-text-success-dark:hover,a.has-text-success-dark:focus{color:#4b9333 !important}.has-background-success-dark{background-color:#386e26 !important}.has-text-warning{color:#eed49f !important}a.has-text-warning:hover,a.has-text-warning:focus{color:#e6c174 !important}.has-background-warning{background-color:#eed49f !important}.has-text-warning-light{color:#fcf7ee !important}a.has-text-warning-light:hover,a.has-text-warning-light:focus{color:#f4e4c2 !important}.has-background-warning-light{background-color:#fcf7ee !important}.has-text-warning-dark{color:#7e5c16 !important}a.has-text-warning-dark:hover,a.has-text-warning-dark:focus{color:#a97b1e !important}.has-background-warning-dark{background-color:#7e5c16 !important}.has-text-danger{color:#ed8796 !important}a.has-text-danger:hover,a.has-text-danger:focus{color:#e65b6f !important}.has-background-danger{background-color:#ed8796 !important}.has-text-danger-light{color:#fcedef !important}a.has-text-danger-light:hover,a.has-text-danger-light:focus{color:#f6c1c9 !important}.has-background-danger-light{background-color:#fcedef !important}.has-text-danger-dark{color:#971729 !important}a.has-text-danger-dark:hover,a.has-text-danger-dark:focus{color:#c31d36 !important}.has-background-danger-dark{background-color:#971729 !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:#363a4f !important}.has-background-grey-darker{background-color:#363a4f !important}.has-text-grey-dark{color:#494d64 !important}.has-background-grey-dark{background-color:#494d64 !important}.has-text-grey{color:#5b6078 !important}.has-background-grey{background-color:#5b6078 !important}.has-text-grey-light{color:#6e738d !important}.has-background-grey-light{background-color:#6e738d !important}.has-text-grey-lighter{color:#8087a2 !important}.has-background-grey-lighter{background-color:#8087a2 !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}.is-flex-direction-row{flex-direction:row !important}.is-flex-direction-row-reverse{flex-direction:row-reverse !important}.is-flex-direction-column{flex-direction:column !important}.is-flex-direction-column-reverse{flex-direction:column-reverse !important}.is-flex-wrap-nowrap{flex-wrap:nowrap !important}.is-flex-wrap-wrap{flex-wrap:wrap !important}.is-flex-wrap-wrap-reverse{flex-wrap:wrap-reverse !important}.is-justify-content-flex-start{justify-content:flex-start !important}.is-justify-content-flex-end{justify-content:flex-end !important}.is-justify-content-center{justify-content:center !important}.is-justify-content-space-between{justify-content:space-between !important}.is-justify-content-space-around{justify-content:space-around !important}.is-justify-content-space-evenly{justify-content:space-evenly !important}.is-justify-content-start{justify-content:start !important}.is-justify-content-end{justify-content:end !important}.is-justify-content-left{justify-content:left !important}.is-justify-content-right{justify-content:right !important}.is-align-content-flex-start{align-content:flex-start !important}.is-align-content-flex-end{align-content:flex-end !important}.is-align-content-center{align-content:center !important}.is-align-content-space-between{align-content:space-between !important}.is-align-content-space-around{align-content:space-around !important}.is-align-content-space-evenly{align-content:space-evenly !important}.is-align-content-stretch{align-content:stretch !important}.is-align-content-start{align-content:start !important}.is-align-content-end{align-content:end !important}.is-align-content-baseline{align-content:baseline !important}.is-align-items-stretch{align-items:stretch !important}.is-align-items-flex-start{align-items:flex-start !important}.is-align-items-flex-end{align-items:flex-end !important}.is-align-items-center{align-items:center !important}.is-align-items-baseline{align-items:baseline !important}.is-align-items-start{align-items:start !important}.is-align-items-end{align-items:end !important}.is-align-items-self-start{align-items:self-start !important}.is-align-items-self-end{align-items:self-end !important}.is-align-self-auto{align-self:auto !important}.is-align-self-flex-start{align-self:flex-start !important}.is-align-self-flex-end{align-self:flex-end !important}.is-align-self-center{align-self:center !important}.is-align-self-baseline{align-self:baseline !important}.is-align-self-stretch{align-self:stretch !important}.is-flex-grow-0{flex-grow:0 !important}.is-flex-grow-1{flex-grow:1 !important}.is-flex-grow-2{flex-grow:2 !important}.is-flex-grow-3{flex-grow:3 !important}.is-flex-grow-4{flex-grow:4 !important}.is-flex-grow-5{flex-grow:5 !important}.is-flex-shrink-0{flex-shrink:0 !important}.is-flex-shrink-1{flex-shrink:1 !important}.is-flex-shrink-2{flex-shrink:2 !important}.is-flex-shrink-3{flex-shrink:3 !important}.is-flex-shrink-4{flex-shrink:4 !important}.is-flex-shrink-5{flex-shrink:5 !important}.is-clearfix::after{clear:both;content:" ";display:table}.is-pulled-left{float:left !important}.is-pulled-right{float:right !important}.is-radiusless{border-radius:0 !important}.is-shadowless{box-shadow:none !important}.is-clickable{cursor:pointer !important;pointer-events:all !important}.is-clipped{overflow:hidden !important}.is-relative{position:relative !important}.is-marginless{margin:0 !important}.is-paddingless{padding:0 !important}.m-0{margin:0 !important}.mt-0{margin-top:0 !important}.mr-0{margin-right:0 !important}.mb-0{margin-bottom:0 !important}.ml-0{margin-left:0 !important}.mx-0{margin-left:0 !important;margin-right:0 !important}.my-0{margin-top:0 !important;margin-bottom:0 !important}.m-1{margin:.25rem !important}.mt-1{margin-top:.25rem !important}.mr-1{margin-right:.25rem !important}.mb-1{margin-bottom:.25rem !important}.ml-1{margin-left:.25rem !important}.mx-1{margin-left:.25rem !important;margin-right:.25rem !important}.my-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.m-2{margin:.5rem !important}.mt-2{margin-top:.5rem !important}.mr-2{margin-right:.5rem !important}.mb-2{margin-bottom:.5rem !important}.ml-2{margin-left:.5rem !important}.mx-2{margin-left:.5rem !important;margin-right:.5rem !important}.my-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.m-3{margin:.75rem !important}.mt-3{margin-top:.75rem !important}.mr-3{margin-right:.75rem !important}.mb-3{margin-bottom:.75rem !important}.ml-3{margin-left:.75rem !important}.mx-3{margin-left:.75rem !important;margin-right:.75rem !important}.my-3{margin-top:.75rem !important;margin-bottom:.75rem !important}.m-4{margin:1rem !important}.mt-4{margin-top:1rem !important}.mr-4{margin-right:1rem !important}.mb-4{margin-bottom:1rem !important}.ml-4{margin-left:1rem !important}.mx-4{margin-left:1rem !important;margin-right:1rem !important}.my-4{margin-top:1rem !important;margin-bottom:1rem !important}.m-5{margin:1.5rem !important}.mt-5{margin-top:1.5rem !important}.mr-5{margin-right:1.5rem !important}.mb-5{margin-bottom:1.5rem !important}.ml-5{margin-left:1.5rem !important}.mx-5{margin-left:1.5rem !important;margin-right:1.5rem !important}.my-5{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.m-6{margin:3rem !important}.mt-6{margin-top:3rem !important}.mr-6{margin-right:3rem !important}.mb-6{margin-bottom:3rem !important}.ml-6{margin-left:3rem !important}.mx-6{margin-left:3rem !important;margin-right:3rem !important}.my-6{margin-top:3rem !important;margin-bottom:3rem !important}.m-auto{margin:auto !important}.mt-auto{margin-top:auto !important}.mr-auto{margin-right:auto !important}.mb-auto{margin-bottom:auto !important}.ml-auto{margin-left:auto !important}.mx-auto{margin-left:auto !important;margin-right:auto !important}.my-auto{margin-top:auto !important;margin-bottom:auto !important}.p-0{padding:0 !important}.pt-0{padding-top:0 !important}.pr-0{padding-right:0 !important}.pb-0{padding-bottom:0 !important}.pl-0{padding-left:0 !important}.px-0{padding-left:0 !important;padding-right:0 !important}.py-0{padding-top:0 !important;padding-bottom:0 !important}.p-1{padding:.25rem !important}.pt-1{padding-top:.25rem !important}.pr-1{padding-right:.25rem !important}.pb-1{padding-bottom:.25rem !important}.pl-1{padding-left:.25rem !important}.px-1{padding-left:.25rem !important;padding-right:.25rem !important}.py-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.p-2{padding:.5rem !important}.pt-2{padding-top:.5rem !important}.pr-2{padding-right:.5rem !important}.pb-2{padding-bottom:.5rem !important}.pl-2{padding-left:.5rem !important}.px-2{padding-left:.5rem !important;padding-right:.5rem !important}.py-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.p-3{padding:.75rem !important}.pt-3{padding-top:.75rem !important}.pr-3{padding-right:.75rem !important}.pb-3{padding-bottom:.75rem !important}.pl-3{padding-left:.75rem !important}.px-3{padding-left:.75rem !important;padding-right:.75rem !important}.py-3{padding-top:.75rem !important;padding-bottom:.75rem !important}.p-4{padding:1rem !important}.pt-4{padding-top:1rem !important}.pr-4{padding-right:1rem !important}.pb-4{padding-bottom:1rem !important}.pl-4{padding-left:1rem !important}.px-4{padding-left:1rem !important;padding-right:1rem !important}.py-4{padding-top:1rem !important;padding-bottom:1rem !important}.p-5{padding:1.5rem !important}.pt-5{padding-top:1.5rem !important}.pr-5{padding-right:1.5rem !important}.pb-5{padding-bottom:1.5rem !important}.pl-5{padding-left:1.5rem !important}.px-5{padding-left:1.5rem !important;padding-right:1.5rem !important}.py-5{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.p-6{padding:3rem !important}.pt-6{padding-top:3rem !important}.pr-6{padding-right:3rem !important}.pb-6{padding-bottom:3rem !important}.pl-6{padding-left:3rem !important}.px-6{padding-left:3rem !important;padding-right:3rem !important}.py-6{padding-top:3rem !important;padding-bottom:3rem !important}.p-auto{padding:auto !important}.pt-auto{padding-top:auto !important}.pr-auto{padding-right:auto !important}.pb-auto{padding-bottom:auto !important}.pl-auto{padding-left:auto !important}.px-auto{padding-left:auto !important;padding-right:auto !important}.py-auto{padding-top:auto !important;padding-bottom:auto !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,html.theme--catppuccin-macchiato .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}.is-underlined{text-decoration:underline !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}}html.theme--catppuccin-macchiato html{background-color:#24273a;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--catppuccin-macchiato article,html.theme--catppuccin-macchiato aside,html.theme--catppuccin-macchiato figure,html.theme--catppuccin-macchiato footer,html.theme--catppuccin-macchiato header,html.theme--catppuccin-macchiato hgroup,html.theme--catppuccin-macchiato section{display:block}html.theme--catppuccin-macchiato body,html.theme--catppuccin-macchiato button,html.theme--catppuccin-macchiato input,html.theme--catppuccin-macchiato optgroup,html.theme--catppuccin-macchiato select,html.theme--catppuccin-macchiato textarea{font-family:"Lato Medium",-apple-system,BlinkMacSystemFont,"Segoe UI","Helvetica Neue","Helvetica","Arial",sans-serif}html.theme--catppuccin-macchiato code,html.theme--catppuccin-macchiato 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--catppuccin-macchiato body{color:#cad3f5;font-size:1em;font-weight:400;line-height:1.5}html.theme--catppuccin-macchiato a{color:#8aadf4;cursor:pointer;text-decoration:none}html.theme--catppuccin-macchiato a strong{color:currentColor}html.theme--catppuccin-macchiato a:hover{color:#91d7e3}html.theme--catppuccin-macchiato code{background-color:#1e2030;color:#cad3f5;font-size:.875em;font-weight:normal;padding:.1em}html.theme--catppuccin-macchiato hr{background-color:#1e2030;border:none;display:block;height:2px;margin:1.5rem 0}html.theme--catppuccin-macchiato img{height:auto;max-width:100%}html.theme--catppuccin-macchiato input[type="checkbox"],html.theme--catppuccin-macchiato input[type="radio"]{vertical-align:baseline}html.theme--catppuccin-macchiato small{font-size:.875em}html.theme--catppuccin-macchiato span{font-style:inherit;font-weight:inherit}html.theme--catppuccin-macchiato strong{color:#b5c1f1;font-weight:700}html.theme--catppuccin-macchiato fieldset{border:none}html.theme--catppuccin-macchiato pre{-webkit-overflow-scrolling:touch;background-color:#1e2030;color:#cad3f5;font-size:.875em;overflow-x:auto;padding:1.25rem 1.5rem;white-space:pre;word-wrap:normal}html.theme--catppuccin-macchiato pre code{background-color:transparent;color:currentColor;font-size:1em;padding:0}html.theme--catppuccin-macchiato table td,html.theme--catppuccin-macchiato table th{vertical-align:top}html.theme--catppuccin-macchiato table td:not([align]),html.theme--catppuccin-macchiato table th:not([align]){text-align:inherit}html.theme--catppuccin-macchiato table th{color:#b5c1f1}html.theme--catppuccin-macchiato .box{background-color:#494d64;border-radius:8px;box-shadow:none;color:#cad3f5;display:block;padding:1.25rem}html.theme--catppuccin-macchiato a.box:hover,html.theme--catppuccin-macchiato a.box:focus{box-shadow:0 0.5em 1em -0.125em rgba(10,10,10,0.1),0 0 0 1px #8aadf4}html.theme--catppuccin-macchiato a.box:active{box-shadow:inset 0 1px 2px rgba(10,10,10,0.2),0 0 0 1px #8aadf4}html.theme--catppuccin-macchiato .button{background-color:#1e2030;border-color:#3b3f5f;border-width:1px;color:#8aadf4;cursor:pointer;justify-content:center;padding-bottom:calc(0.5em - 1px);padding-left:1em;padding-right:1em;padding-top:calc(0.5em - 1px);text-align:center;white-space:nowrap}html.theme--catppuccin-macchiato .button strong{color:inherit}html.theme--catppuccin-macchiato .button .icon,html.theme--catppuccin-macchiato .button .icon.is-small,html.theme--catppuccin-macchiato .button #documenter .docs-sidebar form.docs-search>input.icon,html.theme--catppuccin-macchiato #documenter .docs-sidebar .button form.docs-search>input.icon,html.theme--catppuccin-macchiato .button .icon.is-medium,html.theme--catppuccin-macchiato .button .icon.is-large{height:1.5em;width:1.5em}html.theme--catppuccin-macchiato .button .icon:first-child:not(:last-child){margin-left:calc(-0.5em - 1px);margin-right:.25em}html.theme--catppuccin-macchiato .button .icon:last-child:not(:first-child){margin-left:.25em;margin-right:calc(-0.5em - 1px)}html.theme--catppuccin-macchiato .button .icon:first-child:last-child{margin-left:calc(-0.5em - 1px);margin-right:calc(-0.5em - 1px)}html.theme--catppuccin-macchiato .button:hover,html.theme--catppuccin-macchiato .button.is-hovered{border-color:#6e738d;color:#b5c1f1}html.theme--catppuccin-macchiato .button:focus,html.theme--catppuccin-macchiato .button.is-focused{border-color:#6e738d;color:#739df2}html.theme--catppuccin-macchiato .button:focus:not(:active),html.theme--catppuccin-macchiato .button.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(138,173,244,0.25)}html.theme--catppuccin-macchiato .button:active,html.theme--catppuccin-macchiato .button.is-active{border-color:#494d64;color:#b5c1f1}html.theme--catppuccin-macchiato .button.is-text{background-color:transparent;border-color:transparent;color:#cad3f5;text-decoration:underline}html.theme--catppuccin-macchiato .button.is-text:hover,html.theme--catppuccin-macchiato .button.is-text.is-hovered,html.theme--catppuccin-macchiato .button.is-text:focus,html.theme--catppuccin-macchiato .button.is-text.is-focused{background-color:#1e2030;color:#b5c1f1}html.theme--catppuccin-macchiato .button.is-text:active,html.theme--catppuccin-macchiato .button.is-text.is-active{background-color:#141620;color:#b5c1f1}html.theme--catppuccin-macchiato .button.is-text[disabled],fieldset[disabled] html.theme--catppuccin-macchiato .button.is-text{background-color:transparent;border-color:transparent;box-shadow:none}html.theme--catppuccin-macchiato .button.is-ghost{background:none;border-color:rgba(0,0,0,0);color:#8aadf4;text-decoration:none}html.theme--catppuccin-macchiato .button.is-ghost:hover,html.theme--catppuccin-macchiato .button.is-ghost.is-hovered{color:#8aadf4;text-decoration:underline}html.theme--catppuccin-macchiato .button.is-white{background-color:#fff;border-color:transparent;color:#0a0a0a}html.theme--catppuccin-macchiato .button.is-white:hover,html.theme--catppuccin-macchiato .button.is-white.is-hovered{background-color:#f9f9f9;border-color:transparent;color:#0a0a0a}html.theme--catppuccin-macchiato .button.is-white:focus,html.theme--catppuccin-macchiato .button.is-white.is-focused{border-color:transparent;color:#0a0a0a}html.theme--catppuccin-macchiato .button.is-white:focus:not(:active),html.theme--catppuccin-macchiato .button.is-white.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(255,255,255,0.25)}html.theme--catppuccin-macchiato .button.is-white:active,html.theme--catppuccin-macchiato .button.is-white.is-active{background-color:#f2f2f2;border-color:transparent;color:#0a0a0a}html.theme--catppuccin-macchiato .button.is-white[disabled],fieldset[disabled] html.theme--catppuccin-macchiato .button.is-white{background-color:#fff;border-color:#fff;box-shadow:none}html.theme--catppuccin-macchiato .button.is-white.is-inverted{background-color:#0a0a0a;color:#fff}html.theme--catppuccin-macchiato .button.is-white.is-inverted:hover,html.theme--catppuccin-macchiato .button.is-white.is-inverted.is-hovered{background-color:#000}html.theme--catppuccin-macchiato .button.is-white.is-inverted[disabled],fieldset[disabled] html.theme--catppuccin-macchiato .button.is-white.is-inverted{background-color:#0a0a0a;border-color:transparent;box-shadow:none;color:#fff}html.theme--catppuccin-macchiato .button.is-white.is-loading::after{border-color:transparent transparent #0a0a0a #0a0a0a !important}html.theme--catppuccin-macchiato .button.is-white.is-outlined{background-color:transparent;border-color:#fff;color:#fff}html.theme--catppuccin-macchiato .button.is-white.is-outlined:hover,html.theme--catppuccin-macchiato .button.is-white.is-outlined.is-hovered,html.theme--catppuccin-macchiato .button.is-white.is-outlined:focus,html.theme--catppuccin-macchiato .button.is-white.is-outlined.is-focused{background-color:#fff;border-color:#fff;color:#0a0a0a}html.theme--catppuccin-macchiato .button.is-white.is-outlined.is-loading::after{border-color:transparent transparent #fff #fff !important}html.theme--catppuccin-macchiato .button.is-white.is-outlined.is-loading:hover::after,html.theme--catppuccin-macchiato .button.is-white.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-macchiato .button.is-white.is-outlined.is-loading:focus::after,html.theme--catppuccin-macchiato .button.is-white.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #0a0a0a #0a0a0a !important}html.theme--catppuccin-macchiato .button.is-white.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-macchiato .button.is-white.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}html.theme--catppuccin-macchiato .button.is-white.is-inverted.is-outlined{background-color:transparent;border-color:#0a0a0a;color:#0a0a0a}html.theme--catppuccin-macchiato .button.is-white.is-inverted.is-outlined:hover,html.theme--catppuccin-macchiato .button.is-white.is-inverted.is-outlined.is-hovered,html.theme--catppuccin-macchiato .button.is-white.is-inverted.is-outlined:focus,html.theme--catppuccin-macchiato .button.is-white.is-inverted.is-outlined.is-focused{background-color:#0a0a0a;color:#fff}html.theme--catppuccin-macchiato .button.is-white.is-inverted.is-outlined.is-loading:hover::after,html.theme--catppuccin-macchiato .button.is-white.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-macchiato .button.is-white.is-inverted.is-outlined.is-loading:focus::after,html.theme--catppuccin-macchiato .button.is-white.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #fff #fff !important}html.theme--catppuccin-macchiato .button.is-white.is-inverted.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-macchiato .button.is-white.is-inverted.is-outlined{background-color:transparent;border-color:#0a0a0a;box-shadow:none;color:#0a0a0a}html.theme--catppuccin-macchiato .button.is-black{background-color:#0a0a0a;border-color:transparent;color:#fff}html.theme--catppuccin-macchiato .button.is-black:hover,html.theme--catppuccin-macchiato .button.is-black.is-hovered{background-color:#040404;border-color:transparent;color:#fff}html.theme--catppuccin-macchiato .button.is-black:focus,html.theme--catppuccin-macchiato .button.is-black.is-focused{border-color:transparent;color:#fff}html.theme--catppuccin-macchiato .button.is-black:focus:not(:active),html.theme--catppuccin-macchiato .button.is-black.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(10,10,10,0.25)}html.theme--catppuccin-macchiato .button.is-black:active,html.theme--catppuccin-macchiato .button.is-black.is-active{background-color:#000;border-color:transparent;color:#fff}html.theme--catppuccin-macchiato .button.is-black[disabled],fieldset[disabled] html.theme--catppuccin-macchiato .button.is-black{background-color:#0a0a0a;border-color:#0a0a0a;box-shadow:none}html.theme--catppuccin-macchiato .button.is-black.is-inverted{background-color:#fff;color:#0a0a0a}html.theme--catppuccin-macchiato .button.is-black.is-inverted:hover,html.theme--catppuccin-macchiato .button.is-black.is-inverted.is-hovered{background-color:#f2f2f2}html.theme--catppuccin-macchiato .button.is-black.is-inverted[disabled],fieldset[disabled] html.theme--catppuccin-macchiato .button.is-black.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#0a0a0a}html.theme--catppuccin-macchiato .button.is-black.is-loading::after{border-color:transparent transparent #fff #fff !important}html.theme--catppuccin-macchiato .button.is-black.is-outlined{background-color:transparent;border-color:#0a0a0a;color:#0a0a0a}html.theme--catppuccin-macchiato .button.is-black.is-outlined:hover,html.theme--catppuccin-macchiato .button.is-black.is-outlined.is-hovered,html.theme--catppuccin-macchiato .button.is-black.is-outlined:focus,html.theme--catppuccin-macchiato .button.is-black.is-outlined.is-focused{background-color:#0a0a0a;border-color:#0a0a0a;color:#fff}html.theme--catppuccin-macchiato .button.is-black.is-outlined.is-loading::after{border-color:transparent transparent #0a0a0a #0a0a0a !important}html.theme--catppuccin-macchiato .button.is-black.is-outlined.is-loading:hover::after,html.theme--catppuccin-macchiato .button.is-black.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-macchiato .button.is-black.is-outlined.is-loading:focus::after,html.theme--catppuccin-macchiato .button.is-black.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #fff #fff !important}html.theme--catppuccin-macchiato .button.is-black.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-macchiato .button.is-black.is-outlined{background-color:transparent;border-color:#0a0a0a;box-shadow:none;color:#0a0a0a}html.theme--catppuccin-macchiato .button.is-black.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}html.theme--catppuccin-macchiato .button.is-black.is-inverted.is-outlined:hover,html.theme--catppuccin-macchiato .button.is-black.is-inverted.is-outlined.is-hovered,html.theme--catppuccin-macchiato .button.is-black.is-inverted.is-outlined:focus,html.theme--catppuccin-macchiato .button.is-black.is-inverted.is-outlined.is-focused{background-color:#fff;color:#0a0a0a}html.theme--catppuccin-macchiato .button.is-black.is-inverted.is-outlined.is-loading:hover::after,html.theme--catppuccin-macchiato .button.is-black.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-macchiato .button.is-black.is-inverted.is-outlined.is-loading:focus::after,html.theme--catppuccin-macchiato .button.is-black.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #0a0a0a #0a0a0a !important}html.theme--catppuccin-macchiato .button.is-black.is-inverted.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-macchiato .button.is-black.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}html.theme--catppuccin-macchiato .button.is-light{background-color:#f5f5f5;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .button.is-light:hover,html.theme--catppuccin-macchiato .button.is-light.is-hovered{background-color:#eee;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .button.is-light:focus,html.theme--catppuccin-macchiato .button.is-light.is-focused{border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .button.is-light:focus:not(:active),html.theme--catppuccin-macchiato .button.is-light.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(245,245,245,0.25)}html.theme--catppuccin-macchiato .button.is-light:active,html.theme--catppuccin-macchiato .button.is-light.is-active{background-color:#e8e8e8;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .button.is-light[disabled],fieldset[disabled] html.theme--catppuccin-macchiato .button.is-light{background-color:#f5f5f5;border-color:#f5f5f5;box-shadow:none}html.theme--catppuccin-macchiato .button.is-light.is-inverted{background-color:rgba(0,0,0,0.7);color:#f5f5f5}html.theme--catppuccin-macchiato .button.is-light.is-inverted:hover,html.theme--catppuccin-macchiato .button.is-light.is-inverted.is-hovered{background-color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .button.is-light.is-inverted[disabled],fieldset[disabled] html.theme--catppuccin-macchiato .button.is-light.is-inverted{background-color:rgba(0,0,0,0.7);border-color:transparent;box-shadow:none;color:#f5f5f5}html.theme--catppuccin-macchiato .button.is-light.is-loading::after{border-color:transparent transparent rgba(0,0,0,0.7) rgba(0,0,0,0.7) !important}html.theme--catppuccin-macchiato .button.is-light.is-outlined{background-color:transparent;border-color:#f5f5f5;color:#f5f5f5}html.theme--catppuccin-macchiato .button.is-light.is-outlined:hover,html.theme--catppuccin-macchiato .button.is-light.is-outlined.is-hovered,html.theme--catppuccin-macchiato .button.is-light.is-outlined:focus,html.theme--catppuccin-macchiato .button.is-light.is-outlined.is-focused{background-color:#f5f5f5;border-color:#f5f5f5;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .button.is-light.is-outlined.is-loading::after{border-color:transparent transparent #f5f5f5 #f5f5f5 !important}html.theme--catppuccin-macchiato .button.is-light.is-outlined.is-loading:hover::after,html.theme--catppuccin-macchiato .button.is-light.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-macchiato .button.is-light.is-outlined.is-loading:focus::after,html.theme--catppuccin-macchiato .button.is-light.is-outlined.is-loading.is-focused::after{border-color:transparent transparent rgba(0,0,0,0.7) rgba(0,0,0,0.7) !important}html.theme--catppuccin-macchiato .button.is-light.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-macchiato .button.is-light.is-outlined{background-color:transparent;border-color:#f5f5f5;box-shadow:none;color:#f5f5f5}html.theme--catppuccin-macchiato .button.is-light.is-inverted.is-outlined{background-color:transparent;border-color:rgba(0,0,0,0.7);color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .button.is-light.is-inverted.is-outlined:hover,html.theme--catppuccin-macchiato .button.is-light.is-inverted.is-outlined.is-hovered,html.theme--catppuccin-macchiato .button.is-light.is-inverted.is-outlined:focus,html.theme--catppuccin-macchiato .button.is-light.is-inverted.is-outlined.is-focused{background-color:rgba(0,0,0,0.7);color:#f5f5f5}html.theme--catppuccin-macchiato .button.is-light.is-inverted.is-outlined.is-loading:hover::after,html.theme--catppuccin-macchiato .button.is-light.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-macchiato .button.is-light.is-inverted.is-outlined.is-loading:focus::after,html.theme--catppuccin-macchiato .button.is-light.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #f5f5f5 #f5f5f5 !important}html.theme--catppuccin-macchiato .button.is-light.is-inverted.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-macchiato .button.is-light.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)}html.theme--catppuccin-macchiato .button.is-dark,html.theme--catppuccin-macchiato .content kbd.button{background-color:#363a4f;border-color:transparent;color:#fff}html.theme--catppuccin-macchiato .button.is-dark:hover,html.theme--catppuccin-macchiato .content kbd.button:hover,html.theme--catppuccin-macchiato .button.is-dark.is-hovered,html.theme--catppuccin-macchiato .content kbd.button.is-hovered{background-color:#313447;border-color:transparent;color:#fff}html.theme--catppuccin-macchiato .button.is-dark:focus,html.theme--catppuccin-macchiato .content kbd.button:focus,html.theme--catppuccin-macchiato .button.is-dark.is-focused,html.theme--catppuccin-macchiato .content kbd.button.is-focused{border-color:transparent;color:#fff}html.theme--catppuccin-macchiato .button.is-dark:focus:not(:active),html.theme--catppuccin-macchiato .content kbd.button:focus:not(:active),html.theme--catppuccin-macchiato .button.is-dark.is-focused:not(:active),html.theme--catppuccin-macchiato .content kbd.button.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(54,58,79,0.25)}html.theme--catppuccin-macchiato .button.is-dark:active,html.theme--catppuccin-macchiato .content kbd.button:active,html.theme--catppuccin-macchiato .button.is-dark.is-active,html.theme--catppuccin-macchiato .content kbd.button.is-active{background-color:#2c2f40;border-color:transparent;color:#fff}html.theme--catppuccin-macchiato .button.is-dark[disabled],html.theme--catppuccin-macchiato .content kbd.button[disabled],fieldset[disabled] html.theme--catppuccin-macchiato .button.is-dark,fieldset[disabled] html.theme--catppuccin-macchiato .content kbd.button{background-color:#363a4f;border-color:#363a4f;box-shadow:none}html.theme--catppuccin-macchiato .button.is-dark.is-inverted,html.theme--catppuccin-macchiato .content kbd.button.is-inverted{background-color:#fff;color:#363a4f}html.theme--catppuccin-macchiato .button.is-dark.is-inverted:hover,html.theme--catppuccin-macchiato .content kbd.button.is-inverted:hover,html.theme--catppuccin-macchiato .button.is-dark.is-inverted.is-hovered,html.theme--catppuccin-macchiato .content kbd.button.is-inverted.is-hovered{background-color:#f2f2f2}html.theme--catppuccin-macchiato .button.is-dark.is-inverted[disabled],html.theme--catppuccin-macchiato .content kbd.button.is-inverted[disabled],fieldset[disabled] html.theme--catppuccin-macchiato .button.is-dark.is-inverted,fieldset[disabled] html.theme--catppuccin-macchiato .content kbd.button.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#363a4f}html.theme--catppuccin-macchiato .button.is-dark.is-loading::after,html.theme--catppuccin-macchiato .content kbd.button.is-loading::after{border-color:transparent transparent #fff #fff !important}html.theme--catppuccin-macchiato .button.is-dark.is-outlined,html.theme--catppuccin-macchiato .content kbd.button.is-outlined{background-color:transparent;border-color:#363a4f;color:#363a4f}html.theme--catppuccin-macchiato .button.is-dark.is-outlined:hover,html.theme--catppuccin-macchiato .content kbd.button.is-outlined:hover,html.theme--catppuccin-macchiato .button.is-dark.is-outlined.is-hovered,html.theme--catppuccin-macchiato .content kbd.button.is-outlined.is-hovered,html.theme--catppuccin-macchiato .button.is-dark.is-outlined:focus,html.theme--catppuccin-macchiato .content kbd.button.is-outlined:focus,html.theme--catppuccin-macchiato .button.is-dark.is-outlined.is-focused,html.theme--catppuccin-macchiato .content kbd.button.is-outlined.is-focused{background-color:#363a4f;border-color:#363a4f;color:#fff}html.theme--catppuccin-macchiato .button.is-dark.is-outlined.is-loading::after,html.theme--catppuccin-macchiato .content kbd.button.is-outlined.is-loading::after{border-color:transparent transparent #363a4f #363a4f !important}html.theme--catppuccin-macchiato .button.is-dark.is-outlined.is-loading:hover::after,html.theme--catppuccin-macchiato .content kbd.button.is-outlined.is-loading:hover::after,html.theme--catppuccin-macchiato .button.is-dark.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-macchiato .content kbd.button.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-macchiato .button.is-dark.is-outlined.is-loading:focus::after,html.theme--catppuccin-macchiato .content kbd.button.is-outlined.is-loading:focus::after,html.theme--catppuccin-macchiato .button.is-dark.is-outlined.is-loading.is-focused::after,html.theme--catppuccin-macchiato .content kbd.button.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #fff #fff !important}html.theme--catppuccin-macchiato .button.is-dark.is-outlined[disabled],html.theme--catppuccin-macchiato .content kbd.button.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-macchiato .button.is-dark.is-outlined,fieldset[disabled] html.theme--catppuccin-macchiato .content kbd.button.is-outlined{background-color:transparent;border-color:#363a4f;box-shadow:none;color:#363a4f}html.theme--catppuccin-macchiato .button.is-dark.is-inverted.is-outlined,html.theme--catppuccin-macchiato .content kbd.button.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}html.theme--catppuccin-macchiato .button.is-dark.is-inverted.is-outlined:hover,html.theme--catppuccin-macchiato .content kbd.button.is-inverted.is-outlined:hover,html.theme--catppuccin-macchiato .button.is-dark.is-inverted.is-outlined.is-hovered,html.theme--catppuccin-macchiato .content kbd.button.is-inverted.is-outlined.is-hovered,html.theme--catppuccin-macchiato .button.is-dark.is-inverted.is-outlined:focus,html.theme--catppuccin-macchiato .content kbd.button.is-inverted.is-outlined:focus,html.theme--catppuccin-macchiato .button.is-dark.is-inverted.is-outlined.is-focused,html.theme--catppuccin-macchiato .content kbd.button.is-inverted.is-outlined.is-focused{background-color:#fff;color:#363a4f}html.theme--catppuccin-macchiato .button.is-dark.is-inverted.is-outlined.is-loading:hover::after,html.theme--catppuccin-macchiato .content kbd.button.is-inverted.is-outlined.is-loading:hover::after,html.theme--catppuccin-macchiato .button.is-dark.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-macchiato .content kbd.button.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-macchiato .button.is-dark.is-inverted.is-outlined.is-loading:focus::after,html.theme--catppuccin-macchiato .content kbd.button.is-inverted.is-outlined.is-loading:focus::after,html.theme--catppuccin-macchiato .button.is-dark.is-inverted.is-outlined.is-loading.is-focused::after,html.theme--catppuccin-macchiato .content kbd.button.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #363a4f #363a4f !important}html.theme--catppuccin-macchiato .button.is-dark.is-inverted.is-outlined[disabled],html.theme--catppuccin-macchiato .content kbd.button.is-inverted.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-macchiato .button.is-dark.is-inverted.is-outlined,fieldset[disabled] html.theme--catppuccin-macchiato .content kbd.button.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}html.theme--catppuccin-macchiato .button.is-primary,html.theme--catppuccin-macchiato .docstring>section>a.button.docs-sourcelink{background-color:#8aadf4;border-color:transparent;color:#fff}html.theme--catppuccin-macchiato .button.is-primary:hover,html.theme--catppuccin-macchiato .docstring>section>a.button.docs-sourcelink:hover,html.theme--catppuccin-macchiato .button.is-primary.is-hovered,html.theme--catppuccin-macchiato .docstring>section>a.button.is-hovered.docs-sourcelink{background-color:#7ea5f3;border-color:transparent;color:#fff}html.theme--catppuccin-macchiato .button.is-primary:focus,html.theme--catppuccin-macchiato .docstring>section>a.button.docs-sourcelink:focus,html.theme--catppuccin-macchiato .button.is-primary.is-focused,html.theme--catppuccin-macchiato .docstring>section>a.button.is-focused.docs-sourcelink{border-color:transparent;color:#fff}html.theme--catppuccin-macchiato .button.is-primary:focus:not(:active),html.theme--catppuccin-macchiato .docstring>section>a.button.docs-sourcelink:focus:not(:active),html.theme--catppuccin-macchiato .button.is-primary.is-focused:not(:active),html.theme--catppuccin-macchiato .docstring>section>a.button.is-focused.docs-sourcelink:not(:active){box-shadow:0 0 0 0.125em rgba(138,173,244,0.25)}html.theme--catppuccin-macchiato .button.is-primary:active,html.theme--catppuccin-macchiato .docstring>section>a.button.docs-sourcelink:active,html.theme--catppuccin-macchiato .button.is-primary.is-active,html.theme--catppuccin-macchiato .docstring>section>a.button.is-active.docs-sourcelink{background-color:#739df2;border-color:transparent;color:#fff}html.theme--catppuccin-macchiato .button.is-primary[disabled],html.theme--catppuccin-macchiato .docstring>section>a.button.docs-sourcelink[disabled],fieldset[disabled] html.theme--catppuccin-macchiato .button.is-primary,fieldset[disabled] html.theme--catppuccin-macchiato .docstring>section>a.button.docs-sourcelink{background-color:#8aadf4;border-color:#8aadf4;box-shadow:none}html.theme--catppuccin-macchiato .button.is-primary.is-inverted,html.theme--catppuccin-macchiato .docstring>section>a.button.is-inverted.docs-sourcelink{background-color:#fff;color:#8aadf4}html.theme--catppuccin-macchiato .button.is-primary.is-inverted:hover,html.theme--catppuccin-macchiato .docstring>section>a.button.is-inverted.docs-sourcelink:hover,html.theme--catppuccin-macchiato .button.is-primary.is-inverted.is-hovered,html.theme--catppuccin-macchiato .docstring>section>a.button.is-inverted.is-hovered.docs-sourcelink{background-color:#f2f2f2}html.theme--catppuccin-macchiato .button.is-primary.is-inverted[disabled],html.theme--catppuccin-macchiato .docstring>section>a.button.is-inverted.docs-sourcelink[disabled],fieldset[disabled] html.theme--catppuccin-macchiato .button.is-primary.is-inverted,fieldset[disabled] html.theme--catppuccin-macchiato .docstring>section>a.button.is-inverted.docs-sourcelink{background-color:#fff;border-color:transparent;box-shadow:none;color:#8aadf4}html.theme--catppuccin-macchiato .button.is-primary.is-loading::after,html.theme--catppuccin-macchiato .docstring>section>a.button.is-loading.docs-sourcelink::after{border-color:transparent transparent #fff #fff !important}html.theme--catppuccin-macchiato .button.is-primary.is-outlined,html.theme--catppuccin-macchiato .docstring>section>a.button.is-outlined.docs-sourcelink{background-color:transparent;border-color:#8aadf4;color:#8aadf4}html.theme--catppuccin-macchiato .button.is-primary.is-outlined:hover,html.theme--catppuccin-macchiato .docstring>section>a.button.is-outlined.docs-sourcelink:hover,html.theme--catppuccin-macchiato .button.is-primary.is-outlined.is-hovered,html.theme--catppuccin-macchiato .docstring>section>a.button.is-outlined.is-hovered.docs-sourcelink,html.theme--catppuccin-macchiato .button.is-primary.is-outlined:focus,html.theme--catppuccin-macchiato .docstring>section>a.button.is-outlined.docs-sourcelink:focus,html.theme--catppuccin-macchiato .button.is-primary.is-outlined.is-focused,html.theme--catppuccin-macchiato .docstring>section>a.button.is-outlined.is-focused.docs-sourcelink{background-color:#8aadf4;border-color:#8aadf4;color:#fff}html.theme--catppuccin-macchiato .button.is-primary.is-outlined.is-loading::after,html.theme--catppuccin-macchiato .docstring>section>a.button.is-outlined.is-loading.docs-sourcelink::after{border-color:transparent transparent #8aadf4 #8aadf4 !important}html.theme--catppuccin-macchiato .button.is-primary.is-outlined.is-loading:hover::after,html.theme--catppuccin-macchiato .docstring>section>a.button.is-outlined.is-loading.docs-sourcelink:hover::after,html.theme--catppuccin-macchiato .button.is-primary.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-macchiato .docstring>section>a.button.is-outlined.is-loading.is-hovered.docs-sourcelink::after,html.theme--catppuccin-macchiato .button.is-primary.is-outlined.is-loading:focus::after,html.theme--catppuccin-macchiato .docstring>section>a.button.is-outlined.is-loading.docs-sourcelink:focus::after,html.theme--catppuccin-macchiato .button.is-primary.is-outlined.is-loading.is-focused::after,html.theme--catppuccin-macchiato .docstring>section>a.button.is-outlined.is-loading.is-focused.docs-sourcelink::after{border-color:transparent transparent #fff #fff !important}html.theme--catppuccin-macchiato .button.is-primary.is-outlined[disabled],html.theme--catppuccin-macchiato .docstring>section>a.button.is-outlined.docs-sourcelink[disabled],fieldset[disabled] html.theme--catppuccin-macchiato .button.is-primary.is-outlined,fieldset[disabled] html.theme--catppuccin-macchiato .docstring>section>a.button.is-outlined.docs-sourcelink{background-color:transparent;border-color:#8aadf4;box-shadow:none;color:#8aadf4}html.theme--catppuccin-macchiato .button.is-primary.is-inverted.is-outlined,html.theme--catppuccin-macchiato .docstring>section>a.button.is-inverted.is-outlined.docs-sourcelink{background-color:transparent;border-color:#fff;color:#fff}html.theme--catppuccin-macchiato .button.is-primary.is-inverted.is-outlined:hover,html.theme--catppuccin-macchiato .docstring>section>a.button.is-inverted.is-outlined.docs-sourcelink:hover,html.theme--catppuccin-macchiato .button.is-primary.is-inverted.is-outlined.is-hovered,html.theme--catppuccin-macchiato .docstring>section>a.button.is-inverted.is-outlined.is-hovered.docs-sourcelink,html.theme--catppuccin-macchiato .button.is-primary.is-inverted.is-outlined:focus,html.theme--catppuccin-macchiato .docstring>section>a.button.is-inverted.is-outlined.docs-sourcelink:focus,html.theme--catppuccin-macchiato .button.is-primary.is-inverted.is-outlined.is-focused,html.theme--catppuccin-macchiato .docstring>section>a.button.is-inverted.is-outlined.is-focused.docs-sourcelink{background-color:#fff;color:#8aadf4}html.theme--catppuccin-macchiato .button.is-primary.is-inverted.is-outlined.is-loading:hover::after,html.theme--catppuccin-macchiato .docstring>section>a.button.is-inverted.is-outlined.is-loading.docs-sourcelink:hover::after,html.theme--catppuccin-macchiato .button.is-primary.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-macchiato .docstring>section>a.button.is-inverted.is-outlined.is-loading.is-hovered.docs-sourcelink::after,html.theme--catppuccin-macchiato .button.is-primary.is-inverted.is-outlined.is-loading:focus::after,html.theme--catppuccin-macchiato .docstring>section>a.button.is-inverted.is-outlined.is-loading.docs-sourcelink:focus::after,html.theme--catppuccin-macchiato .button.is-primary.is-inverted.is-outlined.is-loading.is-focused::after,html.theme--catppuccin-macchiato .docstring>section>a.button.is-inverted.is-outlined.is-loading.is-focused.docs-sourcelink::after{border-color:transparent transparent #8aadf4 #8aadf4 !important}html.theme--catppuccin-macchiato .button.is-primary.is-inverted.is-outlined[disabled],html.theme--catppuccin-macchiato .docstring>section>a.button.is-inverted.is-outlined.docs-sourcelink[disabled],fieldset[disabled] html.theme--catppuccin-macchiato .button.is-primary.is-inverted.is-outlined,fieldset[disabled] html.theme--catppuccin-macchiato .docstring>section>a.button.is-inverted.is-outlined.docs-sourcelink{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}html.theme--catppuccin-macchiato .button.is-primary.is-light,html.theme--catppuccin-macchiato .docstring>section>a.button.is-light.docs-sourcelink{background-color:#ecf2fd;color:#0e3b95}html.theme--catppuccin-macchiato .button.is-primary.is-light:hover,html.theme--catppuccin-macchiato .docstring>section>a.button.is-light.docs-sourcelink:hover,html.theme--catppuccin-macchiato .button.is-primary.is-light.is-hovered,html.theme--catppuccin-macchiato .docstring>section>a.button.is-light.is-hovered.docs-sourcelink{background-color:#e1eafc;border-color:transparent;color:#0e3b95}html.theme--catppuccin-macchiato .button.is-primary.is-light:active,html.theme--catppuccin-macchiato .docstring>section>a.button.is-light.docs-sourcelink:active,html.theme--catppuccin-macchiato .button.is-primary.is-light.is-active,html.theme--catppuccin-macchiato .docstring>section>a.button.is-light.is-active.docs-sourcelink{background-color:#d5e2fb;border-color:transparent;color:#0e3b95}html.theme--catppuccin-macchiato .button.is-link{background-color:#8aadf4;border-color:transparent;color:#fff}html.theme--catppuccin-macchiato .button.is-link:hover,html.theme--catppuccin-macchiato .button.is-link.is-hovered{background-color:#7ea5f3;border-color:transparent;color:#fff}html.theme--catppuccin-macchiato .button.is-link:focus,html.theme--catppuccin-macchiato .button.is-link.is-focused{border-color:transparent;color:#fff}html.theme--catppuccin-macchiato .button.is-link:focus:not(:active),html.theme--catppuccin-macchiato .button.is-link.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(138,173,244,0.25)}html.theme--catppuccin-macchiato .button.is-link:active,html.theme--catppuccin-macchiato .button.is-link.is-active{background-color:#739df2;border-color:transparent;color:#fff}html.theme--catppuccin-macchiato .button.is-link[disabled],fieldset[disabled] html.theme--catppuccin-macchiato .button.is-link{background-color:#8aadf4;border-color:#8aadf4;box-shadow:none}html.theme--catppuccin-macchiato .button.is-link.is-inverted{background-color:#fff;color:#8aadf4}html.theme--catppuccin-macchiato .button.is-link.is-inverted:hover,html.theme--catppuccin-macchiato .button.is-link.is-inverted.is-hovered{background-color:#f2f2f2}html.theme--catppuccin-macchiato .button.is-link.is-inverted[disabled],fieldset[disabled] html.theme--catppuccin-macchiato .button.is-link.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#8aadf4}html.theme--catppuccin-macchiato .button.is-link.is-loading::after{border-color:transparent transparent #fff #fff !important}html.theme--catppuccin-macchiato .button.is-link.is-outlined{background-color:transparent;border-color:#8aadf4;color:#8aadf4}html.theme--catppuccin-macchiato .button.is-link.is-outlined:hover,html.theme--catppuccin-macchiato .button.is-link.is-outlined.is-hovered,html.theme--catppuccin-macchiato .button.is-link.is-outlined:focus,html.theme--catppuccin-macchiato .button.is-link.is-outlined.is-focused{background-color:#8aadf4;border-color:#8aadf4;color:#fff}html.theme--catppuccin-macchiato .button.is-link.is-outlined.is-loading::after{border-color:transparent transparent #8aadf4 #8aadf4 !important}html.theme--catppuccin-macchiato .button.is-link.is-outlined.is-loading:hover::after,html.theme--catppuccin-macchiato .button.is-link.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-macchiato .button.is-link.is-outlined.is-loading:focus::after,html.theme--catppuccin-macchiato .button.is-link.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #fff #fff !important}html.theme--catppuccin-macchiato .button.is-link.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-macchiato .button.is-link.is-outlined{background-color:transparent;border-color:#8aadf4;box-shadow:none;color:#8aadf4}html.theme--catppuccin-macchiato .button.is-link.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}html.theme--catppuccin-macchiato .button.is-link.is-inverted.is-outlined:hover,html.theme--catppuccin-macchiato .button.is-link.is-inverted.is-outlined.is-hovered,html.theme--catppuccin-macchiato .button.is-link.is-inverted.is-outlined:focus,html.theme--catppuccin-macchiato .button.is-link.is-inverted.is-outlined.is-focused{background-color:#fff;color:#8aadf4}html.theme--catppuccin-macchiato .button.is-link.is-inverted.is-outlined.is-loading:hover::after,html.theme--catppuccin-macchiato .button.is-link.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-macchiato .button.is-link.is-inverted.is-outlined.is-loading:focus::after,html.theme--catppuccin-macchiato .button.is-link.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #8aadf4 #8aadf4 !important}html.theme--catppuccin-macchiato .button.is-link.is-inverted.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-macchiato .button.is-link.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}html.theme--catppuccin-macchiato .button.is-link.is-light{background-color:#ecf2fd;color:#0e3b95}html.theme--catppuccin-macchiato .button.is-link.is-light:hover,html.theme--catppuccin-macchiato .button.is-link.is-light.is-hovered{background-color:#e1eafc;border-color:transparent;color:#0e3b95}html.theme--catppuccin-macchiato .button.is-link.is-light:active,html.theme--catppuccin-macchiato .button.is-link.is-light.is-active{background-color:#d5e2fb;border-color:transparent;color:#0e3b95}html.theme--catppuccin-macchiato .button.is-info{background-color:#8bd5ca;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .button.is-info:hover,html.theme--catppuccin-macchiato .button.is-info.is-hovered{background-color:#82d2c6;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .button.is-info:focus,html.theme--catppuccin-macchiato .button.is-info.is-focused{border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .button.is-info:focus:not(:active),html.theme--catppuccin-macchiato .button.is-info.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(139,213,202,0.25)}html.theme--catppuccin-macchiato .button.is-info:active,html.theme--catppuccin-macchiato .button.is-info.is-active{background-color:#78cec1;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .button.is-info[disabled],fieldset[disabled] html.theme--catppuccin-macchiato .button.is-info{background-color:#8bd5ca;border-color:#8bd5ca;box-shadow:none}html.theme--catppuccin-macchiato .button.is-info.is-inverted{background-color:rgba(0,0,0,0.7);color:#8bd5ca}html.theme--catppuccin-macchiato .button.is-info.is-inverted:hover,html.theme--catppuccin-macchiato .button.is-info.is-inverted.is-hovered{background-color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .button.is-info.is-inverted[disabled],fieldset[disabled] html.theme--catppuccin-macchiato .button.is-info.is-inverted{background-color:rgba(0,0,0,0.7);border-color:transparent;box-shadow:none;color:#8bd5ca}html.theme--catppuccin-macchiato .button.is-info.is-loading::after{border-color:transparent transparent rgba(0,0,0,0.7) rgba(0,0,0,0.7) !important}html.theme--catppuccin-macchiato .button.is-info.is-outlined{background-color:transparent;border-color:#8bd5ca;color:#8bd5ca}html.theme--catppuccin-macchiato .button.is-info.is-outlined:hover,html.theme--catppuccin-macchiato .button.is-info.is-outlined.is-hovered,html.theme--catppuccin-macchiato .button.is-info.is-outlined:focus,html.theme--catppuccin-macchiato .button.is-info.is-outlined.is-focused{background-color:#8bd5ca;border-color:#8bd5ca;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .button.is-info.is-outlined.is-loading::after{border-color:transparent transparent #8bd5ca #8bd5ca !important}html.theme--catppuccin-macchiato .button.is-info.is-outlined.is-loading:hover::after,html.theme--catppuccin-macchiato .button.is-info.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-macchiato .button.is-info.is-outlined.is-loading:focus::after,html.theme--catppuccin-macchiato .button.is-info.is-outlined.is-loading.is-focused::after{border-color:transparent transparent rgba(0,0,0,0.7) rgba(0,0,0,0.7) !important}html.theme--catppuccin-macchiato .button.is-info.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-macchiato .button.is-info.is-outlined{background-color:transparent;border-color:#8bd5ca;box-shadow:none;color:#8bd5ca}html.theme--catppuccin-macchiato .button.is-info.is-inverted.is-outlined{background-color:transparent;border-color:rgba(0,0,0,0.7);color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .button.is-info.is-inverted.is-outlined:hover,html.theme--catppuccin-macchiato .button.is-info.is-inverted.is-outlined.is-hovered,html.theme--catppuccin-macchiato .button.is-info.is-inverted.is-outlined:focus,html.theme--catppuccin-macchiato .button.is-info.is-inverted.is-outlined.is-focused{background-color:rgba(0,0,0,0.7);color:#8bd5ca}html.theme--catppuccin-macchiato .button.is-info.is-inverted.is-outlined.is-loading:hover::after,html.theme--catppuccin-macchiato .button.is-info.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-macchiato .button.is-info.is-inverted.is-outlined.is-loading:focus::after,html.theme--catppuccin-macchiato .button.is-info.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #8bd5ca #8bd5ca !important}html.theme--catppuccin-macchiato .button.is-info.is-inverted.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-macchiato .button.is-info.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)}html.theme--catppuccin-macchiato .button.is-info.is-light{background-color:#f0faf8;color:#276d62}html.theme--catppuccin-macchiato .button.is-info.is-light:hover,html.theme--catppuccin-macchiato .button.is-info.is-light.is-hovered{background-color:#e7f6f4;border-color:transparent;color:#276d62}html.theme--catppuccin-macchiato .button.is-info.is-light:active,html.theme--catppuccin-macchiato .button.is-info.is-light.is-active{background-color:#ddf3f0;border-color:transparent;color:#276d62}html.theme--catppuccin-macchiato .button.is-success{background-color:#a6da95;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .button.is-success:hover,html.theme--catppuccin-macchiato .button.is-success.is-hovered{background-color:#9ed78c;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .button.is-success:focus,html.theme--catppuccin-macchiato .button.is-success.is-focused{border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .button.is-success:focus:not(:active),html.theme--catppuccin-macchiato .button.is-success.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(166,218,149,0.25)}html.theme--catppuccin-macchiato .button.is-success:active,html.theme--catppuccin-macchiato .button.is-success.is-active{background-color:#96d382;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .button.is-success[disabled],fieldset[disabled] html.theme--catppuccin-macchiato .button.is-success{background-color:#a6da95;border-color:#a6da95;box-shadow:none}html.theme--catppuccin-macchiato .button.is-success.is-inverted{background-color:rgba(0,0,0,0.7);color:#a6da95}html.theme--catppuccin-macchiato .button.is-success.is-inverted:hover,html.theme--catppuccin-macchiato .button.is-success.is-inverted.is-hovered{background-color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .button.is-success.is-inverted[disabled],fieldset[disabled] html.theme--catppuccin-macchiato .button.is-success.is-inverted{background-color:rgba(0,0,0,0.7);border-color:transparent;box-shadow:none;color:#a6da95}html.theme--catppuccin-macchiato .button.is-success.is-loading::after{border-color:transparent transparent rgba(0,0,0,0.7) rgba(0,0,0,0.7) !important}html.theme--catppuccin-macchiato .button.is-success.is-outlined{background-color:transparent;border-color:#a6da95;color:#a6da95}html.theme--catppuccin-macchiato .button.is-success.is-outlined:hover,html.theme--catppuccin-macchiato .button.is-success.is-outlined.is-hovered,html.theme--catppuccin-macchiato .button.is-success.is-outlined:focus,html.theme--catppuccin-macchiato .button.is-success.is-outlined.is-focused{background-color:#a6da95;border-color:#a6da95;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .button.is-success.is-outlined.is-loading::after{border-color:transparent transparent #a6da95 #a6da95 !important}html.theme--catppuccin-macchiato .button.is-success.is-outlined.is-loading:hover::after,html.theme--catppuccin-macchiato .button.is-success.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-macchiato .button.is-success.is-outlined.is-loading:focus::after,html.theme--catppuccin-macchiato .button.is-success.is-outlined.is-loading.is-focused::after{border-color:transparent transparent rgba(0,0,0,0.7) rgba(0,0,0,0.7) !important}html.theme--catppuccin-macchiato .button.is-success.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-macchiato .button.is-success.is-outlined{background-color:transparent;border-color:#a6da95;box-shadow:none;color:#a6da95}html.theme--catppuccin-macchiato .button.is-success.is-inverted.is-outlined{background-color:transparent;border-color:rgba(0,0,0,0.7);color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .button.is-success.is-inverted.is-outlined:hover,html.theme--catppuccin-macchiato .button.is-success.is-inverted.is-outlined.is-hovered,html.theme--catppuccin-macchiato .button.is-success.is-inverted.is-outlined:focus,html.theme--catppuccin-macchiato .button.is-success.is-inverted.is-outlined.is-focused{background-color:rgba(0,0,0,0.7);color:#a6da95}html.theme--catppuccin-macchiato .button.is-success.is-inverted.is-outlined.is-loading:hover::after,html.theme--catppuccin-macchiato .button.is-success.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-macchiato .button.is-success.is-inverted.is-outlined.is-loading:focus::after,html.theme--catppuccin-macchiato .button.is-success.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #a6da95 #a6da95 !important}html.theme--catppuccin-macchiato .button.is-success.is-inverted.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-macchiato .button.is-success.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)}html.theme--catppuccin-macchiato .button.is-success.is-light{background-color:#f2faf0;color:#386e26}html.theme--catppuccin-macchiato .button.is-success.is-light:hover,html.theme--catppuccin-macchiato .button.is-success.is-light.is-hovered{background-color:#eaf6e6;border-color:transparent;color:#386e26}html.theme--catppuccin-macchiato .button.is-success.is-light:active,html.theme--catppuccin-macchiato .button.is-success.is-light.is-active{background-color:#e2f3dd;border-color:transparent;color:#386e26}html.theme--catppuccin-macchiato .button.is-warning{background-color:#eed49f;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .button.is-warning:hover,html.theme--catppuccin-macchiato .button.is-warning.is-hovered{background-color:#eccf94;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .button.is-warning:focus,html.theme--catppuccin-macchiato .button.is-warning.is-focused{border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .button.is-warning:focus:not(:active),html.theme--catppuccin-macchiato .button.is-warning.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(238,212,159,0.25)}html.theme--catppuccin-macchiato .button.is-warning:active,html.theme--catppuccin-macchiato .button.is-warning.is-active{background-color:#eaca89;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .button.is-warning[disabled],fieldset[disabled] html.theme--catppuccin-macchiato .button.is-warning{background-color:#eed49f;border-color:#eed49f;box-shadow:none}html.theme--catppuccin-macchiato .button.is-warning.is-inverted{background-color:rgba(0,0,0,0.7);color:#eed49f}html.theme--catppuccin-macchiato .button.is-warning.is-inverted:hover,html.theme--catppuccin-macchiato .button.is-warning.is-inverted.is-hovered{background-color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .button.is-warning.is-inverted[disabled],fieldset[disabled] html.theme--catppuccin-macchiato .button.is-warning.is-inverted{background-color:rgba(0,0,0,0.7);border-color:transparent;box-shadow:none;color:#eed49f}html.theme--catppuccin-macchiato .button.is-warning.is-loading::after{border-color:transparent transparent rgba(0,0,0,0.7) rgba(0,0,0,0.7) !important}html.theme--catppuccin-macchiato .button.is-warning.is-outlined{background-color:transparent;border-color:#eed49f;color:#eed49f}html.theme--catppuccin-macchiato .button.is-warning.is-outlined:hover,html.theme--catppuccin-macchiato .button.is-warning.is-outlined.is-hovered,html.theme--catppuccin-macchiato .button.is-warning.is-outlined:focus,html.theme--catppuccin-macchiato .button.is-warning.is-outlined.is-focused{background-color:#eed49f;border-color:#eed49f;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .button.is-warning.is-outlined.is-loading::after{border-color:transparent transparent #eed49f #eed49f !important}html.theme--catppuccin-macchiato .button.is-warning.is-outlined.is-loading:hover::after,html.theme--catppuccin-macchiato .button.is-warning.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-macchiato .button.is-warning.is-outlined.is-loading:focus::after,html.theme--catppuccin-macchiato .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}html.theme--catppuccin-macchiato .button.is-warning.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-macchiato .button.is-warning.is-outlined{background-color:transparent;border-color:#eed49f;box-shadow:none;color:#eed49f}html.theme--catppuccin-macchiato .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)}html.theme--catppuccin-macchiato .button.is-warning.is-inverted.is-outlined:hover,html.theme--catppuccin-macchiato .button.is-warning.is-inverted.is-outlined.is-hovered,html.theme--catppuccin-macchiato .button.is-warning.is-inverted.is-outlined:focus,html.theme--catppuccin-macchiato .button.is-warning.is-inverted.is-outlined.is-focused{background-color:rgba(0,0,0,0.7);color:#eed49f}html.theme--catppuccin-macchiato .button.is-warning.is-inverted.is-outlined.is-loading:hover::after,html.theme--catppuccin-macchiato .button.is-warning.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-macchiato .button.is-warning.is-inverted.is-outlined.is-loading:focus::after,html.theme--catppuccin-macchiato .button.is-warning.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #eed49f #eed49f !important}html.theme--catppuccin-macchiato .button.is-warning.is-inverted.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-macchiato .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)}html.theme--catppuccin-macchiato .button.is-warning.is-light{background-color:#fcf7ee;color:#7e5c16}html.theme--catppuccin-macchiato .button.is-warning.is-light:hover,html.theme--catppuccin-macchiato .button.is-warning.is-light.is-hovered{background-color:#faf2e3;border-color:transparent;color:#7e5c16}html.theme--catppuccin-macchiato .button.is-warning.is-light:active,html.theme--catppuccin-macchiato .button.is-warning.is-light.is-active{background-color:#f8eed8;border-color:transparent;color:#7e5c16}html.theme--catppuccin-macchiato .button.is-danger{background-color:#ed8796;border-color:transparent;color:#fff}html.theme--catppuccin-macchiato .button.is-danger:hover,html.theme--catppuccin-macchiato .button.is-danger.is-hovered{background-color:#eb7c8c;border-color:transparent;color:#fff}html.theme--catppuccin-macchiato .button.is-danger:focus,html.theme--catppuccin-macchiato .button.is-danger.is-focused{border-color:transparent;color:#fff}html.theme--catppuccin-macchiato .button.is-danger:focus:not(:active),html.theme--catppuccin-macchiato .button.is-danger.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(237,135,150,0.25)}html.theme--catppuccin-macchiato .button.is-danger:active,html.theme--catppuccin-macchiato .button.is-danger.is-active{background-color:#ea7183;border-color:transparent;color:#fff}html.theme--catppuccin-macchiato .button.is-danger[disabled],fieldset[disabled] html.theme--catppuccin-macchiato .button.is-danger{background-color:#ed8796;border-color:#ed8796;box-shadow:none}html.theme--catppuccin-macchiato .button.is-danger.is-inverted{background-color:#fff;color:#ed8796}html.theme--catppuccin-macchiato .button.is-danger.is-inverted:hover,html.theme--catppuccin-macchiato .button.is-danger.is-inverted.is-hovered{background-color:#f2f2f2}html.theme--catppuccin-macchiato .button.is-danger.is-inverted[disabled],fieldset[disabled] html.theme--catppuccin-macchiato .button.is-danger.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#ed8796}html.theme--catppuccin-macchiato .button.is-danger.is-loading::after{border-color:transparent transparent #fff #fff !important}html.theme--catppuccin-macchiato .button.is-danger.is-outlined{background-color:transparent;border-color:#ed8796;color:#ed8796}html.theme--catppuccin-macchiato .button.is-danger.is-outlined:hover,html.theme--catppuccin-macchiato .button.is-danger.is-outlined.is-hovered,html.theme--catppuccin-macchiato .button.is-danger.is-outlined:focus,html.theme--catppuccin-macchiato .button.is-danger.is-outlined.is-focused{background-color:#ed8796;border-color:#ed8796;color:#fff}html.theme--catppuccin-macchiato .button.is-danger.is-outlined.is-loading::after{border-color:transparent transparent #ed8796 #ed8796 !important}html.theme--catppuccin-macchiato .button.is-danger.is-outlined.is-loading:hover::after,html.theme--catppuccin-macchiato .button.is-danger.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-macchiato .button.is-danger.is-outlined.is-loading:focus::after,html.theme--catppuccin-macchiato .button.is-danger.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #fff #fff !important}html.theme--catppuccin-macchiato .button.is-danger.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-macchiato .button.is-danger.is-outlined{background-color:transparent;border-color:#ed8796;box-shadow:none;color:#ed8796}html.theme--catppuccin-macchiato .button.is-danger.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}html.theme--catppuccin-macchiato .button.is-danger.is-inverted.is-outlined:hover,html.theme--catppuccin-macchiato .button.is-danger.is-inverted.is-outlined.is-hovered,html.theme--catppuccin-macchiato .button.is-danger.is-inverted.is-outlined:focus,html.theme--catppuccin-macchiato .button.is-danger.is-inverted.is-outlined.is-focused{background-color:#fff;color:#ed8796}html.theme--catppuccin-macchiato .button.is-danger.is-inverted.is-outlined.is-loading:hover::after,html.theme--catppuccin-macchiato .button.is-danger.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-macchiato .button.is-danger.is-inverted.is-outlined.is-loading:focus::after,html.theme--catppuccin-macchiato .button.is-danger.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #ed8796 #ed8796 !important}html.theme--catppuccin-macchiato .button.is-danger.is-inverted.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-macchiato .button.is-danger.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}html.theme--catppuccin-macchiato .button.is-danger.is-light{background-color:#fcedef;color:#971729}html.theme--catppuccin-macchiato .button.is-danger.is-light:hover,html.theme--catppuccin-macchiato .button.is-danger.is-light.is-hovered{background-color:#fbe2e6;border-color:transparent;color:#971729}html.theme--catppuccin-macchiato .button.is-danger.is-light:active,html.theme--catppuccin-macchiato .button.is-danger.is-light.is-active{background-color:#f9d7dc;border-color:transparent;color:#971729}html.theme--catppuccin-macchiato .button.is-small,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.button{font-size:.75rem}html.theme--catppuccin-macchiato .button.is-small:not(.is-rounded),html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.button:not(.is-rounded){border-radius:3px}html.theme--catppuccin-macchiato .button.is-normal{font-size:1rem}html.theme--catppuccin-macchiato .button.is-medium{font-size:1.25rem}html.theme--catppuccin-macchiato .button.is-large{font-size:1.5rem}html.theme--catppuccin-macchiato .button[disabled],fieldset[disabled] html.theme--catppuccin-macchiato .button{background-color:#6e738d;border-color:#5b6078;box-shadow:none;opacity:.5}html.theme--catppuccin-macchiato .button.is-fullwidth{display:flex;width:100%}html.theme--catppuccin-macchiato .button.is-loading{color:transparent !important;pointer-events:none}html.theme--catppuccin-macchiato .button.is-loading::after{position:absolute;left:calc(50% - (1em * 0.5));top:calc(50% - (1em * 0.5));position:absolute !important}html.theme--catppuccin-macchiato .button.is-static{background-color:#1e2030;border-color:#5b6078;color:#8087a2;box-shadow:none;pointer-events:none}html.theme--catppuccin-macchiato .button.is-rounded,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.button{border-radius:9999px;padding-left:calc(1em + 0.25em);padding-right:calc(1em + 0.25em)}html.theme--catppuccin-macchiato .buttons{align-items:center;display:flex;flex-wrap:wrap;justify-content:flex-start}html.theme--catppuccin-macchiato .buttons .button{margin-bottom:0.5rem}html.theme--catppuccin-macchiato .buttons .button:not(:last-child):not(.is-fullwidth){margin-right:.5rem}html.theme--catppuccin-macchiato .buttons:last-child{margin-bottom:-0.5rem}html.theme--catppuccin-macchiato .buttons:not(:last-child){margin-bottom:1rem}html.theme--catppuccin-macchiato .buttons.are-small .button:not(.is-normal):not(.is-medium):not(.is-large){font-size:.75rem}html.theme--catppuccin-macchiato .buttons.are-small .button:not(.is-normal):not(.is-medium):not(.is-large):not(.is-rounded){border-radius:3px}html.theme--catppuccin-macchiato .buttons.are-medium .button:not(.is-small):not(.is-normal):not(.is-large){font-size:1.25rem}html.theme--catppuccin-macchiato .buttons.are-large .button:not(.is-small):not(.is-normal):not(.is-medium){font-size:1.5rem}html.theme--catppuccin-macchiato .buttons.has-addons .button:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}html.theme--catppuccin-macchiato .buttons.has-addons .button:not(:last-child){border-bottom-right-radius:0;border-top-right-radius:0;margin-right:-1px}html.theme--catppuccin-macchiato .buttons.has-addons .button:last-child{margin-right:0}html.theme--catppuccin-macchiato .buttons.has-addons .button:hover,html.theme--catppuccin-macchiato .buttons.has-addons .button.is-hovered{z-index:2}html.theme--catppuccin-macchiato .buttons.has-addons .button:focus,html.theme--catppuccin-macchiato .buttons.has-addons .button.is-focused,html.theme--catppuccin-macchiato .buttons.has-addons .button:active,html.theme--catppuccin-macchiato .buttons.has-addons .button.is-active,html.theme--catppuccin-macchiato .buttons.has-addons .button.is-selected{z-index:3}html.theme--catppuccin-macchiato .buttons.has-addons .button:focus:hover,html.theme--catppuccin-macchiato .buttons.has-addons .button.is-focused:hover,html.theme--catppuccin-macchiato .buttons.has-addons .button:active:hover,html.theme--catppuccin-macchiato .buttons.has-addons .button.is-active:hover,html.theme--catppuccin-macchiato .buttons.has-addons .button.is-selected:hover{z-index:4}html.theme--catppuccin-macchiato .buttons.has-addons .button.is-expanded{flex-grow:1;flex-shrink:1}html.theme--catppuccin-macchiato .buttons.is-centered{justify-content:center}html.theme--catppuccin-macchiato .buttons.is-centered:not(.has-addons) .button:not(.is-fullwidth){margin-left:0.25rem;margin-right:0.25rem}html.theme--catppuccin-macchiato .buttons.is-right{justify-content:flex-end}html.theme--catppuccin-macchiato .buttons.is-right:not(.has-addons) .button:not(.is-fullwidth){margin-left:0.25rem;margin-right:0.25rem}@media screen and (max-width: 768px){html.theme--catppuccin-macchiato .button.is-responsive.is-small,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-responsive{font-size:.5625rem}html.theme--catppuccin-macchiato .button.is-responsive,html.theme--catppuccin-macchiato .button.is-responsive.is-normal{font-size:.65625rem}html.theme--catppuccin-macchiato .button.is-responsive.is-medium{font-size:.75rem}html.theme--catppuccin-macchiato .button.is-responsive.is-large{font-size:1rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--catppuccin-macchiato .button.is-responsive.is-small,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-responsive{font-size:.65625rem}html.theme--catppuccin-macchiato .button.is-responsive,html.theme--catppuccin-macchiato .button.is-responsive.is-normal{font-size:.75rem}html.theme--catppuccin-macchiato .button.is-responsive.is-medium{font-size:1rem}html.theme--catppuccin-macchiato .button.is-responsive.is-large{font-size:1.25rem}}html.theme--catppuccin-macchiato .container{flex-grow:1;margin:0 auto;position:relative;width:auto}html.theme--catppuccin-macchiato .container.is-fluid{max-width:none !important;padding-left:32px;padding-right:32px;width:100%}@media screen and (min-width: 1056px){html.theme--catppuccin-macchiato .container{max-width:992px}}@media screen and (max-width: 1215px){html.theme--catppuccin-macchiato .container.is-widescreen:not(.is-max-desktop){max-width:1152px}}@media screen and (max-width: 1407px){html.theme--catppuccin-macchiato .container.is-fullhd:not(.is-max-desktop):not(.is-max-widescreen){max-width:1344px}}@media screen and (min-width: 1216px){html.theme--catppuccin-macchiato .container:not(.is-max-desktop){max-width:1152px}}@media screen and (min-width: 1408px){html.theme--catppuccin-macchiato .container:not(.is-max-desktop):not(.is-max-widescreen){max-width:1344px}}html.theme--catppuccin-macchiato .content li+li{margin-top:0.25em}html.theme--catppuccin-macchiato .content p:not(:last-child),html.theme--catppuccin-macchiato .content dl:not(:last-child),html.theme--catppuccin-macchiato .content ol:not(:last-child),html.theme--catppuccin-macchiato .content ul:not(:last-child),html.theme--catppuccin-macchiato .content blockquote:not(:last-child),html.theme--catppuccin-macchiato .content pre:not(:last-child),html.theme--catppuccin-macchiato .content table:not(:last-child){margin-bottom:1em}html.theme--catppuccin-macchiato .content h1,html.theme--catppuccin-macchiato .content h2,html.theme--catppuccin-macchiato .content h3,html.theme--catppuccin-macchiato .content h4,html.theme--catppuccin-macchiato .content h5,html.theme--catppuccin-macchiato .content h6{color:#cad3f5;font-weight:600;line-height:1.125}html.theme--catppuccin-macchiato .content h1{font-size:2em;margin-bottom:0.5em}html.theme--catppuccin-macchiato .content h1:not(:first-child){margin-top:1em}html.theme--catppuccin-macchiato .content h2{font-size:1.75em;margin-bottom:0.5714em}html.theme--catppuccin-macchiato .content h2:not(:first-child){margin-top:1.1428em}html.theme--catppuccin-macchiato .content h3{font-size:1.5em;margin-bottom:0.6666em}html.theme--catppuccin-macchiato .content h3:not(:first-child){margin-top:1.3333em}html.theme--catppuccin-macchiato .content h4{font-size:1.25em;margin-bottom:0.8em}html.theme--catppuccin-macchiato .content h5{font-size:1.125em;margin-bottom:0.8888em}html.theme--catppuccin-macchiato .content h6{font-size:1em;margin-bottom:1em}html.theme--catppuccin-macchiato .content blockquote{background-color:#1e2030;border-left:5px solid #5b6078;padding:1.25em 1.5em}html.theme--catppuccin-macchiato .content ol{list-style-position:outside;margin-left:2em;margin-top:1em}html.theme--catppuccin-macchiato .content ol:not([type]){list-style-type:decimal}html.theme--catppuccin-macchiato .content ol.is-lower-alpha:not([type]){list-style-type:lower-alpha}html.theme--catppuccin-macchiato .content ol.is-lower-roman:not([type]){list-style-type:lower-roman}html.theme--catppuccin-macchiato .content ol.is-upper-alpha:not([type]){list-style-type:upper-alpha}html.theme--catppuccin-macchiato .content ol.is-upper-roman:not([type]){list-style-type:upper-roman}html.theme--catppuccin-macchiato .content ul{list-style:disc outside;margin-left:2em;margin-top:1em}html.theme--catppuccin-macchiato .content ul ul{list-style-type:circle;margin-top:0.5em}html.theme--catppuccin-macchiato .content ul ul ul{list-style-type:square}html.theme--catppuccin-macchiato .content dd{margin-left:2em}html.theme--catppuccin-macchiato .content figure{margin-left:2em;margin-right:2em;text-align:center}html.theme--catppuccin-macchiato .content figure:not(:first-child){margin-top:2em}html.theme--catppuccin-macchiato .content figure:not(:last-child){margin-bottom:2em}html.theme--catppuccin-macchiato .content figure img{display:inline-block}html.theme--catppuccin-macchiato .content figure figcaption{font-style:italic}html.theme--catppuccin-macchiato .content pre{-webkit-overflow-scrolling:touch;overflow-x:auto;padding:0;white-space:pre;word-wrap:normal}html.theme--catppuccin-macchiato .content sup,html.theme--catppuccin-macchiato .content sub{font-size:75%}html.theme--catppuccin-macchiato .content table{width:100%}html.theme--catppuccin-macchiato .content table td,html.theme--catppuccin-macchiato .content table th{border:1px solid #5b6078;border-width:0 0 1px;padding:0.5em 0.75em;vertical-align:top}html.theme--catppuccin-macchiato .content table th{color:#b5c1f1}html.theme--catppuccin-macchiato .content table th:not([align]){text-align:inherit}html.theme--catppuccin-macchiato .content table thead td,html.theme--catppuccin-macchiato .content table thead th{border-width:0 0 2px;color:#b5c1f1}html.theme--catppuccin-macchiato .content table tfoot td,html.theme--catppuccin-macchiato .content table tfoot th{border-width:2px 0 0;color:#b5c1f1}html.theme--catppuccin-macchiato .content table tbody tr:last-child td,html.theme--catppuccin-macchiato .content table tbody tr:last-child th{border-bottom-width:0}html.theme--catppuccin-macchiato .content .tabs li+li{margin-top:0}html.theme--catppuccin-macchiato .content.is-small,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.content{font-size:.75rem}html.theme--catppuccin-macchiato .content.is-normal{font-size:1rem}html.theme--catppuccin-macchiato .content.is-medium{font-size:1.25rem}html.theme--catppuccin-macchiato .content.is-large{font-size:1.5rem}html.theme--catppuccin-macchiato .icon{align-items:center;display:inline-flex;justify-content:center;height:1.5rem;width:1.5rem}html.theme--catppuccin-macchiato .icon.is-small,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.icon{height:1rem;width:1rem}html.theme--catppuccin-macchiato .icon.is-medium{height:2rem;width:2rem}html.theme--catppuccin-macchiato .icon.is-large{height:3rem;width:3rem}html.theme--catppuccin-macchiato .icon-text{align-items:flex-start;color:inherit;display:inline-flex;flex-wrap:wrap;line-height:1.5rem;vertical-align:top}html.theme--catppuccin-macchiato .icon-text .icon{flex-grow:0;flex-shrink:0}html.theme--catppuccin-macchiato .icon-text .icon:not(:last-child){margin-right:.25em}html.theme--catppuccin-macchiato .icon-text .icon:not(:first-child){margin-left:.25em}html.theme--catppuccin-macchiato div.icon-text{display:flex}html.theme--catppuccin-macchiato .image,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img{display:block;position:relative}html.theme--catppuccin-macchiato .image img,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img img{display:block;height:auto;width:100%}html.theme--catppuccin-macchiato .image img.is-rounded,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img img.is-rounded{border-radius:9999px}html.theme--catppuccin-macchiato .image.is-fullwidth,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-fullwidth{width:100%}html.theme--catppuccin-macchiato .image.is-square img,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-square img,html.theme--catppuccin-macchiato .image.is-square .has-ratio,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-square .has-ratio,html.theme--catppuccin-macchiato .image.is-1by1 img,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-1by1 img,html.theme--catppuccin-macchiato .image.is-1by1 .has-ratio,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-1by1 .has-ratio,html.theme--catppuccin-macchiato .image.is-5by4 img,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-5by4 img,html.theme--catppuccin-macchiato .image.is-5by4 .has-ratio,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-5by4 .has-ratio,html.theme--catppuccin-macchiato .image.is-4by3 img,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-4by3 img,html.theme--catppuccin-macchiato .image.is-4by3 .has-ratio,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-4by3 .has-ratio,html.theme--catppuccin-macchiato .image.is-3by2 img,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-3by2 img,html.theme--catppuccin-macchiato .image.is-3by2 .has-ratio,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-3by2 .has-ratio,html.theme--catppuccin-macchiato .image.is-5by3 img,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-5by3 img,html.theme--catppuccin-macchiato .image.is-5by3 .has-ratio,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-5by3 .has-ratio,html.theme--catppuccin-macchiato .image.is-16by9 img,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-16by9 img,html.theme--catppuccin-macchiato .image.is-16by9 .has-ratio,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-16by9 .has-ratio,html.theme--catppuccin-macchiato .image.is-2by1 img,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-2by1 img,html.theme--catppuccin-macchiato .image.is-2by1 .has-ratio,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-2by1 .has-ratio,html.theme--catppuccin-macchiato .image.is-3by1 img,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-3by1 img,html.theme--catppuccin-macchiato .image.is-3by1 .has-ratio,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-3by1 .has-ratio,html.theme--catppuccin-macchiato .image.is-4by5 img,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-4by5 img,html.theme--catppuccin-macchiato .image.is-4by5 .has-ratio,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-4by5 .has-ratio,html.theme--catppuccin-macchiato .image.is-3by4 img,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-3by4 img,html.theme--catppuccin-macchiato .image.is-3by4 .has-ratio,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-3by4 .has-ratio,html.theme--catppuccin-macchiato .image.is-2by3 img,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-2by3 img,html.theme--catppuccin-macchiato .image.is-2by3 .has-ratio,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-2by3 .has-ratio,html.theme--catppuccin-macchiato .image.is-3by5 img,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-3by5 img,html.theme--catppuccin-macchiato .image.is-3by5 .has-ratio,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-3by5 .has-ratio,html.theme--catppuccin-macchiato .image.is-9by16 img,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-9by16 img,html.theme--catppuccin-macchiato .image.is-9by16 .has-ratio,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-9by16 .has-ratio,html.theme--catppuccin-macchiato .image.is-1by2 img,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-1by2 img,html.theme--catppuccin-macchiato .image.is-1by2 .has-ratio,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-1by2 .has-ratio,html.theme--catppuccin-macchiato .image.is-1by3 img,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-1by3 img,html.theme--catppuccin-macchiato .image.is-1by3 .has-ratio,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-1by3 .has-ratio{height:100%;width:100%}html.theme--catppuccin-macchiato .image.is-square,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-square,html.theme--catppuccin-macchiato .image.is-1by1,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-1by1{padding-top:100%}html.theme--catppuccin-macchiato .image.is-5by4,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-5by4{padding-top:80%}html.theme--catppuccin-macchiato .image.is-4by3,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-4by3{padding-top:75%}html.theme--catppuccin-macchiato .image.is-3by2,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-3by2{padding-top:66.6666%}html.theme--catppuccin-macchiato .image.is-5by3,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-5by3{padding-top:60%}html.theme--catppuccin-macchiato .image.is-16by9,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-16by9{padding-top:56.25%}html.theme--catppuccin-macchiato .image.is-2by1,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-2by1{padding-top:50%}html.theme--catppuccin-macchiato .image.is-3by1,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-3by1{padding-top:33.3333%}html.theme--catppuccin-macchiato .image.is-4by5,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-4by5{padding-top:125%}html.theme--catppuccin-macchiato .image.is-3by4,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-3by4{padding-top:133.3333%}html.theme--catppuccin-macchiato .image.is-2by3,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-2by3{padding-top:150%}html.theme--catppuccin-macchiato .image.is-3by5,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-3by5{padding-top:166.6666%}html.theme--catppuccin-macchiato .image.is-9by16,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-9by16{padding-top:177.7777%}html.theme--catppuccin-macchiato .image.is-1by2,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-1by2{padding-top:200%}html.theme--catppuccin-macchiato .image.is-1by3,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-1by3{padding-top:300%}html.theme--catppuccin-macchiato .image.is-16x16,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-16x16{height:16px;width:16px}html.theme--catppuccin-macchiato .image.is-24x24,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-24x24{height:24px;width:24px}html.theme--catppuccin-macchiato .image.is-32x32,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-32x32{height:32px;width:32px}html.theme--catppuccin-macchiato .image.is-48x48,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-48x48{height:48px;width:48px}html.theme--catppuccin-macchiato .image.is-64x64,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-64x64{height:64px;width:64px}html.theme--catppuccin-macchiato .image.is-96x96,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-96x96{height:96px;width:96px}html.theme--catppuccin-macchiato .image.is-128x128,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-128x128{height:128px;width:128px}html.theme--catppuccin-macchiato .notification{background-color:#1e2030;border-radius:.4em;position:relative;padding:1.25rem 2.5rem 1.25rem 1.5rem}html.theme--catppuccin-macchiato .notification a:not(.button):not(.dropdown-item){color:currentColor;text-decoration:underline}html.theme--catppuccin-macchiato .notification strong{color:currentColor}html.theme--catppuccin-macchiato .notification code,html.theme--catppuccin-macchiato .notification pre{background:#fff}html.theme--catppuccin-macchiato .notification pre code{background:transparent}html.theme--catppuccin-macchiato .notification>.delete{right:.5rem;position:absolute;top:0.5rem}html.theme--catppuccin-macchiato .notification .title,html.theme--catppuccin-macchiato .notification .subtitle,html.theme--catppuccin-macchiato .notification .content{color:currentColor}html.theme--catppuccin-macchiato .notification.is-white{background-color:#fff;color:#0a0a0a}html.theme--catppuccin-macchiato .notification.is-black{background-color:#0a0a0a;color:#fff}html.theme--catppuccin-macchiato .notification.is-light{background-color:#f5f5f5;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .notification.is-dark,html.theme--catppuccin-macchiato .content kbd.notification{background-color:#363a4f;color:#fff}html.theme--catppuccin-macchiato .notification.is-primary,html.theme--catppuccin-macchiato .docstring>section>a.notification.docs-sourcelink{background-color:#8aadf4;color:#fff}html.theme--catppuccin-macchiato .notification.is-primary.is-light,html.theme--catppuccin-macchiato .docstring>section>a.notification.is-light.docs-sourcelink{background-color:#ecf2fd;color:#0e3b95}html.theme--catppuccin-macchiato .notification.is-link{background-color:#8aadf4;color:#fff}html.theme--catppuccin-macchiato .notification.is-link.is-light{background-color:#ecf2fd;color:#0e3b95}html.theme--catppuccin-macchiato .notification.is-info{background-color:#8bd5ca;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .notification.is-info.is-light{background-color:#f0faf8;color:#276d62}html.theme--catppuccin-macchiato .notification.is-success{background-color:#a6da95;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .notification.is-success.is-light{background-color:#f2faf0;color:#386e26}html.theme--catppuccin-macchiato .notification.is-warning{background-color:#eed49f;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .notification.is-warning.is-light{background-color:#fcf7ee;color:#7e5c16}html.theme--catppuccin-macchiato .notification.is-danger{background-color:#ed8796;color:#fff}html.theme--catppuccin-macchiato .notification.is-danger.is-light{background-color:#fcedef;color:#971729}html.theme--catppuccin-macchiato .progress{-moz-appearance:none;-webkit-appearance:none;border:none;border-radius:9999px;display:block;height:1rem;overflow:hidden;padding:0;width:100%}html.theme--catppuccin-macchiato .progress::-webkit-progress-bar{background-color:#494d64}html.theme--catppuccin-macchiato .progress::-webkit-progress-value{background-color:#8087a2}html.theme--catppuccin-macchiato .progress::-moz-progress-bar{background-color:#8087a2}html.theme--catppuccin-macchiato .progress::-ms-fill{background-color:#8087a2;border:none}html.theme--catppuccin-macchiato .progress.is-white::-webkit-progress-value{background-color:#fff}html.theme--catppuccin-macchiato .progress.is-white::-moz-progress-bar{background-color:#fff}html.theme--catppuccin-macchiato .progress.is-white::-ms-fill{background-color:#fff}html.theme--catppuccin-macchiato .progress.is-white:indeterminate{background-image:linear-gradient(to right, #fff 30%, #494d64 30%)}html.theme--catppuccin-macchiato .progress.is-black::-webkit-progress-value{background-color:#0a0a0a}html.theme--catppuccin-macchiato .progress.is-black::-moz-progress-bar{background-color:#0a0a0a}html.theme--catppuccin-macchiato .progress.is-black::-ms-fill{background-color:#0a0a0a}html.theme--catppuccin-macchiato .progress.is-black:indeterminate{background-image:linear-gradient(to right, #0a0a0a 30%, #494d64 30%)}html.theme--catppuccin-macchiato .progress.is-light::-webkit-progress-value{background-color:#f5f5f5}html.theme--catppuccin-macchiato .progress.is-light::-moz-progress-bar{background-color:#f5f5f5}html.theme--catppuccin-macchiato .progress.is-light::-ms-fill{background-color:#f5f5f5}html.theme--catppuccin-macchiato .progress.is-light:indeterminate{background-image:linear-gradient(to right, #f5f5f5 30%, #494d64 30%)}html.theme--catppuccin-macchiato .progress.is-dark::-webkit-progress-value,html.theme--catppuccin-macchiato .content kbd.progress::-webkit-progress-value{background-color:#363a4f}html.theme--catppuccin-macchiato .progress.is-dark::-moz-progress-bar,html.theme--catppuccin-macchiato .content kbd.progress::-moz-progress-bar{background-color:#363a4f}html.theme--catppuccin-macchiato .progress.is-dark::-ms-fill,html.theme--catppuccin-macchiato .content kbd.progress::-ms-fill{background-color:#363a4f}html.theme--catppuccin-macchiato .progress.is-dark:indeterminate,html.theme--catppuccin-macchiato .content kbd.progress:indeterminate{background-image:linear-gradient(to right, #363a4f 30%, #494d64 30%)}html.theme--catppuccin-macchiato .progress.is-primary::-webkit-progress-value,html.theme--catppuccin-macchiato .docstring>section>a.progress.docs-sourcelink::-webkit-progress-value{background-color:#8aadf4}html.theme--catppuccin-macchiato .progress.is-primary::-moz-progress-bar,html.theme--catppuccin-macchiato .docstring>section>a.progress.docs-sourcelink::-moz-progress-bar{background-color:#8aadf4}html.theme--catppuccin-macchiato .progress.is-primary::-ms-fill,html.theme--catppuccin-macchiato .docstring>section>a.progress.docs-sourcelink::-ms-fill{background-color:#8aadf4}html.theme--catppuccin-macchiato .progress.is-primary:indeterminate,html.theme--catppuccin-macchiato .docstring>section>a.progress.docs-sourcelink:indeterminate{background-image:linear-gradient(to right, #8aadf4 30%, #494d64 30%)}html.theme--catppuccin-macchiato .progress.is-link::-webkit-progress-value{background-color:#8aadf4}html.theme--catppuccin-macchiato .progress.is-link::-moz-progress-bar{background-color:#8aadf4}html.theme--catppuccin-macchiato .progress.is-link::-ms-fill{background-color:#8aadf4}html.theme--catppuccin-macchiato .progress.is-link:indeterminate{background-image:linear-gradient(to right, #8aadf4 30%, #494d64 30%)}html.theme--catppuccin-macchiato .progress.is-info::-webkit-progress-value{background-color:#8bd5ca}html.theme--catppuccin-macchiato .progress.is-info::-moz-progress-bar{background-color:#8bd5ca}html.theme--catppuccin-macchiato .progress.is-info::-ms-fill{background-color:#8bd5ca}html.theme--catppuccin-macchiato .progress.is-info:indeterminate{background-image:linear-gradient(to right, #8bd5ca 30%, #494d64 30%)}html.theme--catppuccin-macchiato .progress.is-success::-webkit-progress-value{background-color:#a6da95}html.theme--catppuccin-macchiato .progress.is-success::-moz-progress-bar{background-color:#a6da95}html.theme--catppuccin-macchiato .progress.is-success::-ms-fill{background-color:#a6da95}html.theme--catppuccin-macchiato .progress.is-success:indeterminate{background-image:linear-gradient(to right, #a6da95 30%, #494d64 30%)}html.theme--catppuccin-macchiato .progress.is-warning::-webkit-progress-value{background-color:#eed49f}html.theme--catppuccin-macchiato .progress.is-warning::-moz-progress-bar{background-color:#eed49f}html.theme--catppuccin-macchiato .progress.is-warning::-ms-fill{background-color:#eed49f}html.theme--catppuccin-macchiato .progress.is-warning:indeterminate{background-image:linear-gradient(to right, #eed49f 30%, #494d64 30%)}html.theme--catppuccin-macchiato .progress.is-danger::-webkit-progress-value{background-color:#ed8796}html.theme--catppuccin-macchiato .progress.is-danger::-moz-progress-bar{background-color:#ed8796}html.theme--catppuccin-macchiato .progress.is-danger::-ms-fill{background-color:#ed8796}html.theme--catppuccin-macchiato .progress.is-danger:indeterminate{background-image:linear-gradient(to right, #ed8796 30%, #494d64 30%)}html.theme--catppuccin-macchiato .progress:indeterminate{animation-duration:1.5s;animation-iteration-count:infinite;animation-name:moveIndeterminate;animation-timing-function:linear;background-color:#494d64;background-image:linear-gradient(to right, #cad3f5 30%, #494d64 30%);background-position:top left;background-repeat:no-repeat;background-size:150% 150%}html.theme--catppuccin-macchiato .progress:indeterminate::-webkit-progress-bar{background-color:transparent}html.theme--catppuccin-macchiato .progress:indeterminate::-moz-progress-bar{background-color:transparent}html.theme--catppuccin-macchiato .progress:indeterminate::-ms-fill{animation-name:none}html.theme--catppuccin-macchiato .progress.is-small,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.progress{height:.75rem}html.theme--catppuccin-macchiato .progress.is-medium{height:1.25rem}html.theme--catppuccin-macchiato .progress.is-large{height:1.5rem}@keyframes moveIndeterminate{from{background-position:200% 0}to{background-position:-200% 0}}html.theme--catppuccin-macchiato .table{background-color:#494d64;color:#cad3f5}html.theme--catppuccin-macchiato .table td,html.theme--catppuccin-macchiato .table th{border:1px solid #5b6078;border-width:0 0 1px;padding:0.5em 0.75em;vertical-align:top}html.theme--catppuccin-macchiato .table td.is-white,html.theme--catppuccin-macchiato .table th.is-white{background-color:#fff;border-color:#fff;color:#0a0a0a}html.theme--catppuccin-macchiato .table td.is-black,html.theme--catppuccin-macchiato .table th.is-black{background-color:#0a0a0a;border-color:#0a0a0a;color:#fff}html.theme--catppuccin-macchiato .table td.is-light,html.theme--catppuccin-macchiato .table th.is-light{background-color:#f5f5f5;border-color:#f5f5f5;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .table td.is-dark,html.theme--catppuccin-macchiato .table th.is-dark{background-color:#363a4f;border-color:#363a4f;color:#fff}html.theme--catppuccin-macchiato .table td.is-primary,html.theme--catppuccin-macchiato .table th.is-primary{background-color:#8aadf4;border-color:#8aadf4;color:#fff}html.theme--catppuccin-macchiato .table td.is-link,html.theme--catppuccin-macchiato .table th.is-link{background-color:#8aadf4;border-color:#8aadf4;color:#fff}html.theme--catppuccin-macchiato .table td.is-info,html.theme--catppuccin-macchiato .table th.is-info{background-color:#8bd5ca;border-color:#8bd5ca;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .table td.is-success,html.theme--catppuccin-macchiato .table th.is-success{background-color:#a6da95;border-color:#a6da95;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .table td.is-warning,html.theme--catppuccin-macchiato .table th.is-warning{background-color:#eed49f;border-color:#eed49f;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .table td.is-danger,html.theme--catppuccin-macchiato .table th.is-danger{background-color:#ed8796;border-color:#ed8796;color:#fff}html.theme--catppuccin-macchiato .table td.is-narrow,html.theme--catppuccin-macchiato .table th.is-narrow{white-space:nowrap;width:1%}html.theme--catppuccin-macchiato .table td.is-selected,html.theme--catppuccin-macchiato .table th.is-selected{background-color:#8aadf4;color:#fff}html.theme--catppuccin-macchiato .table td.is-selected a,html.theme--catppuccin-macchiato .table td.is-selected strong,html.theme--catppuccin-macchiato .table th.is-selected a,html.theme--catppuccin-macchiato .table th.is-selected strong{color:currentColor}html.theme--catppuccin-macchiato .table td.is-vcentered,html.theme--catppuccin-macchiato .table th.is-vcentered{vertical-align:middle}html.theme--catppuccin-macchiato .table th{color:#b5c1f1}html.theme--catppuccin-macchiato .table th:not([align]){text-align:left}html.theme--catppuccin-macchiato .table tr.is-selected{background-color:#8aadf4;color:#fff}html.theme--catppuccin-macchiato .table tr.is-selected a,html.theme--catppuccin-macchiato .table tr.is-selected strong{color:currentColor}html.theme--catppuccin-macchiato .table tr.is-selected td,html.theme--catppuccin-macchiato .table tr.is-selected th{border-color:#fff;color:currentColor}html.theme--catppuccin-macchiato .table thead{background-color:rgba(0,0,0,0)}html.theme--catppuccin-macchiato .table thead td,html.theme--catppuccin-macchiato .table thead th{border-width:0 0 2px;color:#b5c1f1}html.theme--catppuccin-macchiato .table tfoot{background-color:rgba(0,0,0,0)}html.theme--catppuccin-macchiato .table tfoot td,html.theme--catppuccin-macchiato .table tfoot th{border-width:2px 0 0;color:#b5c1f1}html.theme--catppuccin-macchiato .table tbody{background-color:rgba(0,0,0,0)}html.theme--catppuccin-macchiato .table tbody tr:last-child td,html.theme--catppuccin-macchiato .table tbody tr:last-child th{border-bottom-width:0}html.theme--catppuccin-macchiato .table.is-bordered td,html.theme--catppuccin-macchiato .table.is-bordered th{border-width:1px}html.theme--catppuccin-macchiato .table.is-bordered tr:last-child td,html.theme--catppuccin-macchiato .table.is-bordered tr:last-child th{border-bottom-width:1px}html.theme--catppuccin-macchiato .table.is-fullwidth{width:100%}html.theme--catppuccin-macchiato .table.is-hoverable tbody tr:not(.is-selected):hover{background-color:#363a4f}html.theme--catppuccin-macchiato .table.is-hoverable.is-striped tbody tr:not(.is-selected):hover{background-color:#363a4f}html.theme--catppuccin-macchiato .table.is-hoverable.is-striped tbody tr:not(.is-selected):hover:nth-child(even){background-color:#3a3e55}html.theme--catppuccin-macchiato .table.is-narrow td,html.theme--catppuccin-macchiato .table.is-narrow th{padding:0.25em 0.5em}html.theme--catppuccin-macchiato .table.is-striped tbody tr:not(.is-selected):nth-child(even){background-color:#363a4f}html.theme--catppuccin-macchiato .table-container{-webkit-overflow-scrolling:touch;overflow:auto;overflow-y:hidden;max-width:100%}html.theme--catppuccin-macchiato .tags{align-items:center;display:flex;flex-wrap:wrap;justify-content:flex-start}html.theme--catppuccin-macchiato .tags .tag,html.theme--catppuccin-macchiato .tags .content kbd,html.theme--catppuccin-macchiato .content .tags kbd,html.theme--catppuccin-macchiato .tags .docstring>section>a.docs-sourcelink{margin-bottom:0.5rem}html.theme--catppuccin-macchiato .tags .tag:not(:last-child),html.theme--catppuccin-macchiato .tags .content kbd:not(:last-child),html.theme--catppuccin-macchiato .content .tags kbd:not(:last-child),html.theme--catppuccin-macchiato .tags .docstring>section>a.docs-sourcelink:not(:last-child){margin-right:.5rem}html.theme--catppuccin-macchiato .tags:last-child{margin-bottom:-0.5rem}html.theme--catppuccin-macchiato .tags:not(:last-child){margin-bottom:1rem}html.theme--catppuccin-macchiato .tags.are-medium .tag:not(.is-normal):not(.is-large),html.theme--catppuccin-macchiato .tags.are-medium .content kbd:not(.is-normal):not(.is-large),html.theme--catppuccin-macchiato .content .tags.are-medium kbd:not(.is-normal):not(.is-large),html.theme--catppuccin-macchiato .tags.are-medium .docstring>section>a.docs-sourcelink:not(.is-normal):not(.is-large){font-size:1rem}html.theme--catppuccin-macchiato .tags.are-large .tag:not(.is-normal):not(.is-medium),html.theme--catppuccin-macchiato .tags.are-large .content kbd:not(.is-normal):not(.is-medium),html.theme--catppuccin-macchiato .content .tags.are-large kbd:not(.is-normal):not(.is-medium),html.theme--catppuccin-macchiato .tags.are-large .docstring>section>a.docs-sourcelink:not(.is-normal):not(.is-medium){font-size:1.25rem}html.theme--catppuccin-macchiato .tags.is-centered{justify-content:center}html.theme--catppuccin-macchiato .tags.is-centered .tag,html.theme--catppuccin-macchiato .tags.is-centered .content kbd,html.theme--catppuccin-macchiato .content .tags.is-centered kbd,html.theme--catppuccin-macchiato .tags.is-centered .docstring>section>a.docs-sourcelink{margin-right:0.25rem;margin-left:0.25rem}html.theme--catppuccin-macchiato .tags.is-right{justify-content:flex-end}html.theme--catppuccin-macchiato .tags.is-right .tag:not(:first-child),html.theme--catppuccin-macchiato .tags.is-right .content kbd:not(:first-child),html.theme--catppuccin-macchiato .content .tags.is-right kbd:not(:first-child),html.theme--catppuccin-macchiato .tags.is-right .docstring>section>a.docs-sourcelink:not(:first-child){margin-left:0.5rem}html.theme--catppuccin-macchiato .tags.is-right .tag:not(:last-child),html.theme--catppuccin-macchiato .tags.is-right .content kbd:not(:last-child),html.theme--catppuccin-macchiato .content .tags.is-right kbd:not(:last-child),html.theme--catppuccin-macchiato .tags.is-right .docstring>section>a.docs-sourcelink:not(:last-child){margin-right:0}html.theme--catppuccin-macchiato .tags.has-addons .tag,html.theme--catppuccin-macchiato .tags.has-addons .content kbd,html.theme--catppuccin-macchiato .content .tags.has-addons kbd,html.theme--catppuccin-macchiato .tags.has-addons .docstring>section>a.docs-sourcelink{margin-right:0}html.theme--catppuccin-macchiato .tags.has-addons .tag:not(:first-child),html.theme--catppuccin-macchiato .tags.has-addons .content kbd:not(:first-child),html.theme--catppuccin-macchiato .content .tags.has-addons kbd:not(:first-child),html.theme--catppuccin-macchiato .tags.has-addons .docstring>section>a.docs-sourcelink:not(:first-child){margin-left:0;border-top-left-radius:0;border-bottom-left-radius:0}html.theme--catppuccin-macchiato .tags.has-addons .tag:not(:last-child),html.theme--catppuccin-macchiato .tags.has-addons .content kbd:not(:last-child),html.theme--catppuccin-macchiato .content .tags.has-addons kbd:not(:last-child),html.theme--catppuccin-macchiato .tags.has-addons .docstring>section>a.docs-sourcelink:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}html.theme--catppuccin-macchiato .tag:not(body),html.theme--catppuccin-macchiato .content kbd:not(body),html.theme--catppuccin-macchiato .docstring>section>a.docs-sourcelink:not(body){align-items:center;background-color:#1e2030;border-radius:.4em;color:#cad3f5;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}html.theme--catppuccin-macchiato .tag:not(body) .delete,html.theme--catppuccin-macchiato .content kbd:not(body) .delete,html.theme--catppuccin-macchiato .docstring>section>a.docs-sourcelink:not(body) .delete{margin-left:.25rem;margin-right:-.375rem}html.theme--catppuccin-macchiato .tag.is-white:not(body),html.theme--catppuccin-macchiato .content kbd.is-white:not(body),html.theme--catppuccin-macchiato .docstring>section>a.docs-sourcelink.is-white:not(body){background-color:#fff;color:#0a0a0a}html.theme--catppuccin-macchiato .tag.is-black:not(body),html.theme--catppuccin-macchiato .content kbd.is-black:not(body),html.theme--catppuccin-macchiato .docstring>section>a.docs-sourcelink.is-black:not(body){background-color:#0a0a0a;color:#fff}html.theme--catppuccin-macchiato .tag.is-light:not(body),html.theme--catppuccin-macchiato .content kbd.is-light:not(body),html.theme--catppuccin-macchiato .docstring>section>a.docs-sourcelink.is-light:not(body){background-color:#f5f5f5;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .tag.is-dark:not(body),html.theme--catppuccin-macchiato .content kbd:not(body),html.theme--catppuccin-macchiato .docstring>section>a.docs-sourcelink.is-dark:not(body),html.theme--catppuccin-macchiato .content .docstring>section>kbd:not(body){background-color:#363a4f;color:#fff}html.theme--catppuccin-macchiato .tag.is-primary:not(body),html.theme--catppuccin-macchiato .content kbd.is-primary:not(body),html.theme--catppuccin-macchiato .docstring>section>a.docs-sourcelink:not(body){background-color:#8aadf4;color:#fff}html.theme--catppuccin-macchiato .tag.is-primary.is-light:not(body),html.theme--catppuccin-macchiato .content kbd.is-primary.is-light:not(body),html.theme--catppuccin-macchiato .docstring>section>a.docs-sourcelink.is-light:not(body){background-color:#ecf2fd;color:#0e3b95}html.theme--catppuccin-macchiato .tag.is-link:not(body),html.theme--catppuccin-macchiato .content kbd.is-link:not(body),html.theme--catppuccin-macchiato .docstring>section>a.docs-sourcelink.is-link:not(body){background-color:#8aadf4;color:#fff}html.theme--catppuccin-macchiato .tag.is-link.is-light:not(body),html.theme--catppuccin-macchiato .content kbd.is-link.is-light:not(body),html.theme--catppuccin-macchiato .docstring>section>a.docs-sourcelink.is-link.is-light:not(body){background-color:#ecf2fd;color:#0e3b95}html.theme--catppuccin-macchiato .tag.is-info:not(body),html.theme--catppuccin-macchiato .content kbd.is-info:not(body),html.theme--catppuccin-macchiato .docstring>section>a.docs-sourcelink.is-info:not(body){background-color:#8bd5ca;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .tag.is-info.is-light:not(body),html.theme--catppuccin-macchiato .content kbd.is-info.is-light:not(body),html.theme--catppuccin-macchiato .docstring>section>a.docs-sourcelink.is-info.is-light:not(body){background-color:#f0faf8;color:#276d62}html.theme--catppuccin-macchiato .tag.is-success:not(body),html.theme--catppuccin-macchiato .content kbd.is-success:not(body),html.theme--catppuccin-macchiato .docstring>section>a.docs-sourcelink.is-success:not(body){background-color:#a6da95;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .tag.is-success.is-light:not(body),html.theme--catppuccin-macchiato .content kbd.is-success.is-light:not(body),html.theme--catppuccin-macchiato .docstring>section>a.docs-sourcelink.is-success.is-light:not(body){background-color:#f2faf0;color:#386e26}html.theme--catppuccin-macchiato .tag.is-warning:not(body),html.theme--catppuccin-macchiato .content kbd.is-warning:not(body),html.theme--catppuccin-macchiato .docstring>section>a.docs-sourcelink.is-warning:not(body){background-color:#eed49f;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .tag.is-warning.is-light:not(body),html.theme--catppuccin-macchiato .content kbd.is-warning.is-light:not(body),html.theme--catppuccin-macchiato .docstring>section>a.docs-sourcelink.is-warning.is-light:not(body){background-color:#fcf7ee;color:#7e5c16}html.theme--catppuccin-macchiato .tag.is-danger:not(body),html.theme--catppuccin-macchiato .content kbd.is-danger:not(body),html.theme--catppuccin-macchiato .docstring>section>a.docs-sourcelink.is-danger:not(body){background-color:#ed8796;color:#fff}html.theme--catppuccin-macchiato .tag.is-danger.is-light:not(body),html.theme--catppuccin-macchiato .content kbd.is-danger.is-light:not(body),html.theme--catppuccin-macchiato .docstring>section>a.docs-sourcelink.is-danger.is-light:not(body){background-color:#fcedef;color:#971729}html.theme--catppuccin-macchiato .tag.is-normal:not(body),html.theme--catppuccin-macchiato .content kbd.is-normal:not(body),html.theme--catppuccin-macchiato .docstring>section>a.docs-sourcelink.is-normal:not(body){font-size:.75rem}html.theme--catppuccin-macchiato .tag.is-medium:not(body),html.theme--catppuccin-macchiato .content kbd.is-medium:not(body),html.theme--catppuccin-macchiato .docstring>section>a.docs-sourcelink.is-medium:not(body){font-size:1rem}html.theme--catppuccin-macchiato .tag.is-large:not(body),html.theme--catppuccin-macchiato .content kbd.is-large:not(body),html.theme--catppuccin-macchiato .docstring>section>a.docs-sourcelink.is-large:not(body){font-size:1.25rem}html.theme--catppuccin-macchiato .tag:not(body) .icon:first-child:not(:last-child),html.theme--catppuccin-macchiato .content kbd:not(body) .icon:first-child:not(:last-child),html.theme--catppuccin-macchiato .docstring>section>a.docs-sourcelink:not(body) .icon:first-child:not(:last-child){margin-left:-.375em;margin-right:.1875em}html.theme--catppuccin-macchiato .tag:not(body) .icon:last-child:not(:first-child),html.theme--catppuccin-macchiato .content kbd:not(body) .icon:last-child:not(:first-child),html.theme--catppuccin-macchiato .docstring>section>a.docs-sourcelink:not(body) .icon:last-child:not(:first-child){margin-left:.1875em;margin-right:-.375em}html.theme--catppuccin-macchiato .tag:not(body) .icon:first-child:last-child,html.theme--catppuccin-macchiato .content kbd:not(body) .icon:first-child:last-child,html.theme--catppuccin-macchiato .docstring>section>a.docs-sourcelink:not(body) .icon:first-child:last-child{margin-left:-.375em;margin-right:-.375em}html.theme--catppuccin-macchiato .tag.is-delete:not(body),html.theme--catppuccin-macchiato .content kbd.is-delete:not(body),html.theme--catppuccin-macchiato .docstring>section>a.docs-sourcelink.is-delete:not(body){margin-left:1px;padding:0;position:relative;width:2em}html.theme--catppuccin-macchiato .tag.is-delete:not(body)::before,html.theme--catppuccin-macchiato .content kbd.is-delete:not(body)::before,html.theme--catppuccin-macchiato .docstring>section>a.docs-sourcelink.is-delete:not(body)::before,html.theme--catppuccin-macchiato .tag.is-delete:not(body)::after,html.theme--catppuccin-macchiato .content kbd.is-delete:not(body)::after,html.theme--catppuccin-macchiato .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--catppuccin-macchiato .tag.is-delete:not(body)::before,html.theme--catppuccin-macchiato .content kbd.is-delete:not(body)::before,html.theme--catppuccin-macchiato .docstring>section>a.docs-sourcelink.is-delete:not(body)::before{height:1px;width:50%}html.theme--catppuccin-macchiato .tag.is-delete:not(body)::after,html.theme--catppuccin-macchiato .content kbd.is-delete:not(body)::after,html.theme--catppuccin-macchiato .docstring>section>a.docs-sourcelink.is-delete:not(body)::after{height:50%;width:1px}html.theme--catppuccin-macchiato .tag.is-delete:not(body):hover,html.theme--catppuccin-macchiato .content kbd.is-delete:not(body):hover,html.theme--catppuccin-macchiato .docstring>section>a.docs-sourcelink.is-delete:not(body):hover,html.theme--catppuccin-macchiato .tag.is-delete:not(body):focus,html.theme--catppuccin-macchiato .content kbd.is-delete:not(body):focus,html.theme--catppuccin-macchiato .docstring>section>a.docs-sourcelink.is-delete:not(body):focus{background-color:#141620}html.theme--catppuccin-macchiato .tag.is-delete:not(body):active,html.theme--catppuccin-macchiato .content kbd.is-delete:not(body):active,html.theme--catppuccin-macchiato .docstring>section>a.docs-sourcelink.is-delete:not(body):active{background-color:#0a0b11}html.theme--catppuccin-macchiato .tag.is-rounded:not(body),html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input:not(body),html.theme--catppuccin-macchiato .content kbd.is-rounded:not(body),html.theme--catppuccin-macchiato #documenter .docs-sidebar .content form.docs-search>input:not(body),html.theme--catppuccin-macchiato .docstring>section>a.docs-sourcelink.is-rounded:not(body){border-radius:9999px}html.theme--catppuccin-macchiato a.tag:hover,html.theme--catppuccin-macchiato .docstring>section>a.docs-sourcelink:hover{text-decoration:underline}html.theme--catppuccin-macchiato .title,html.theme--catppuccin-macchiato .subtitle{word-break:break-word}html.theme--catppuccin-macchiato .title em,html.theme--catppuccin-macchiato .title span,html.theme--catppuccin-macchiato .subtitle em,html.theme--catppuccin-macchiato .subtitle span{font-weight:inherit}html.theme--catppuccin-macchiato .title sub,html.theme--catppuccin-macchiato .subtitle sub{font-size:.75em}html.theme--catppuccin-macchiato .title sup,html.theme--catppuccin-macchiato .subtitle sup{font-size:.75em}html.theme--catppuccin-macchiato .title .tag,html.theme--catppuccin-macchiato .title .content kbd,html.theme--catppuccin-macchiato .content .title kbd,html.theme--catppuccin-macchiato .title .docstring>section>a.docs-sourcelink,html.theme--catppuccin-macchiato .subtitle .tag,html.theme--catppuccin-macchiato .subtitle .content kbd,html.theme--catppuccin-macchiato .content .subtitle kbd,html.theme--catppuccin-macchiato .subtitle .docstring>section>a.docs-sourcelink{vertical-align:middle}html.theme--catppuccin-macchiato .title{color:#fff;font-size:2rem;font-weight:500;line-height:1.125}html.theme--catppuccin-macchiato .title strong{color:inherit;font-weight:inherit}html.theme--catppuccin-macchiato .title:not(.is-spaced)+.subtitle{margin-top:-1.25rem}html.theme--catppuccin-macchiato .title.is-1{font-size:3rem}html.theme--catppuccin-macchiato .title.is-2{font-size:2.5rem}html.theme--catppuccin-macchiato .title.is-3{font-size:2rem}html.theme--catppuccin-macchiato .title.is-4{font-size:1.5rem}html.theme--catppuccin-macchiato .title.is-5{font-size:1.25rem}html.theme--catppuccin-macchiato .title.is-6{font-size:1rem}html.theme--catppuccin-macchiato .title.is-7{font-size:.75rem}html.theme--catppuccin-macchiato .subtitle{color:#6e738d;font-size:1.25rem;font-weight:400;line-height:1.25}html.theme--catppuccin-macchiato .subtitle strong{color:#6e738d;font-weight:600}html.theme--catppuccin-macchiato .subtitle:not(.is-spaced)+.title{margin-top:-1.25rem}html.theme--catppuccin-macchiato .subtitle.is-1{font-size:3rem}html.theme--catppuccin-macchiato .subtitle.is-2{font-size:2.5rem}html.theme--catppuccin-macchiato .subtitle.is-3{font-size:2rem}html.theme--catppuccin-macchiato .subtitle.is-4{font-size:1.5rem}html.theme--catppuccin-macchiato .subtitle.is-5{font-size:1.25rem}html.theme--catppuccin-macchiato .subtitle.is-6{font-size:1rem}html.theme--catppuccin-macchiato .subtitle.is-7{font-size:.75rem}html.theme--catppuccin-macchiato .heading{display:block;font-size:11px;letter-spacing:1px;margin-bottom:5px;text-transform:uppercase}html.theme--catppuccin-macchiato .number{align-items:center;background-color:#1e2030;border-radius:9999px;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--catppuccin-macchiato .select select,html.theme--catppuccin-macchiato .textarea,html.theme--catppuccin-macchiato .input,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input{background-color:#24273a;border-color:#5b6078;border-radius:.4em;color:#8087a2}html.theme--catppuccin-macchiato .select select::-moz-placeholder,html.theme--catppuccin-macchiato .textarea::-moz-placeholder,html.theme--catppuccin-macchiato .input::-moz-placeholder,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input::-moz-placeholder{color:#868c98}html.theme--catppuccin-macchiato .select select::-webkit-input-placeholder,html.theme--catppuccin-macchiato .textarea::-webkit-input-placeholder,html.theme--catppuccin-macchiato .input::-webkit-input-placeholder,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input::-webkit-input-placeholder{color:#868c98}html.theme--catppuccin-macchiato .select select:-moz-placeholder,html.theme--catppuccin-macchiato .textarea:-moz-placeholder,html.theme--catppuccin-macchiato .input:-moz-placeholder,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input:-moz-placeholder{color:#868c98}html.theme--catppuccin-macchiato .select select:-ms-input-placeholder,html.theme--catppuccin-macchiato .textarea:-ms-input-placeholder,html.theme--catppuccin-macchiato .input:-ms-input-placeholder,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input:-ms-input-placeholder{color:#868c98}html.theme--catppuccin-macchiato .select select:hover,html.theme--catppuccin-macchiato .textarea:hover,html.theme--catppuccin-macchiato .input:hover,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input:hover,html.theme--catppuccin-macchiato .select select.is-hovered,html.theme--catppuccin-macchiato .is-hovered.textarea,html.theme--catppuccin-macchiato .is-hovered.input,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-hovered{border-color:#6e738d}html.theme--catppuccin-macchiato .select select:focus,html.theme--catppuccin-macchiato .textarea:focus,html.theme--catppuccin-macchiato .input:focus,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input:focus,html.theme--catppuccin-macchiato .select select.is-focused,html.theme--catppuccin-macchiato .is-focused.textarea,html.theme--catppuccin-macchiato .is-focused.input,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--catppuccin-macchiato .select select:active,html.theme--catppuccin-macchiato .textarea:active,html.theme--catppuccin-macchiato .input:active,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input:active,html.theme--catppuccin-macchiato .select select.is-active,html.theme--catppuccin-macchiato .is-active.textarea,html.theme--catppuccin-macchiato .is-active.input,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-active{border-color:#8aadf4;box-shadow:0 0 0 0.125em rgba(138,173,244,0.25)}html.theme--catppuccin-macchiato .select select[disabled],html.theme--catppuccin-macchiato .textarea[disabled],html.theme--catppuccin-macchiato .input[disabled],html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input[disabled],fieldset[disabled] html.theme--catppuccin-macchiato .select select,fieldset[disabled] html.theme--catppuccin-macchiato .textarea,fieldset[disabled] html.theme--catppuccin-macchiato .input,fieldset[disabled] html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input{background-color:#6e738d;border-color:#1e2030;box-shadow:none;color:#f5f7fd}html.theme--catppuccin-macchiato .select select[disabled]::-moz-placeholder,html.theme--catppuccin-macchiato .textarea[disabled]::-moz-placeholder,html.theme--catppuccin-macchiato .input[disabled]::-moz-placeholder,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input[disabled]::-moz-placeholder,fieldset[disabled] html.theme--catppuccin-macchiato .select select::-moz-placeholder,fieldset[disabled] html.theme--catppuccin-macchiato .textarea::-moz-placeholder,fieldset[disabled] html.theme--catppuccin-macchiato .input::-moz-placeholder,fieldset[disabled] html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input::-moz-placeholder{color:rgba(245,247,253,0.3)}html.theme--catppuccin-macchiato .select select[disabled]::-webkit-input-placeholder,html.theme--catppuccin-macchiato .textarea[disabled]::-webkit-input-placeholder,html.theme--catppuccin-macchiato .input[disabled]::-webkit-input-placeholder,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input[disabled]::-webkit-input-placeholder,fieldset[disabled] html.theme--catppuccin-macchiato .select select::-webkit-input-placeholder,fieldset[disabled] html.theme--catppuccin-macchiato .textarea::-webkit-input-placeholder,fieldset[disabled] html.theme--catppuccin-macchiato .input::-webkit-input-placeholder,fieldset[disabled] html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input::-webkit-input-placeholder{color:rgba(245,247,253,0.3)}html.theme--catppuccin-macchiato .select select[disabled]:-moz-placeholder,html.theme--catppuccin-macchiato .textarea[disabled]:-moz-placeholder,html.theme--catppuccin-macchiato .input[disabled]:-moz-placeholder,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input[disabled]:-moz-placeholder,fieldset[disabled] html.theme--catppuccin-macchiato .select select:-moz-placeholder,fieldset[disabled] html.theme--catppuccin-macchiato .textarea:-moz-placeholder,fieldset[disabled] html.theme--catppuccin-macchiato .input:-moz-placeholder,fieldset[disabled] html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input:-moz-placeholder{color:rgba(245,247,253,0.3)}html.theme--catppuccin-macchiato .select select[disabled]:-ms-input-placeholder,html.theme--catppuccin-macchiato .textarea[disabled]:-ms-input-placeholder,html.theme--catppuccin-macchiato .input[disabled]:-ms-input-placeholder,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input[disabled]:-ms-input-placeholder,fieldset[disabled] html.theme--catppuccin-macchiato .select select:-ms-input-placeholder,fieldset[disabled] html.theme--catppuccin-macchiato .textarea:-ms-input-placeholder,fieldset[disabled] html.theme--catppuccin-macchiato .input:-ms-input-placeholder,fieldset[disabled] html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input:-ms-input-placeholder{color:rgba(245,247,253,0.3)}html.theme--catppuccin-macchiato .textarea,html.theme--catppuccin-macchiato .input,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input{box-shadow:inset 0 0.0625em 0.125em rgba(10,10,10,0.05);max-width:100%;width:100%}html.theme--catppuccin-macchiato .textarea[readonly],html.theme--catppuccin-macchiato .input[readonly],html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input[readonly]{box-shadow:none}html.theme--catppuccin-macchiato .is-white.textarea,html.theme--catppuccin-macchiato .is-white.input,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-white{border-color:#fff}html.theme--catppuccin-macchiato .is-white.textarea:focus,html.theme--catppuccin-macchiato .is-white.input:focus,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-white:focus,html.theme--catppuccin-macchiato .is-white.is-focused.textarea,html.theme--catppuccin-macchiato .is-white.is-focused.input,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--catppuccin-macchiato .is-white.textarea:active,html.theme--catppuccin-macchiato .is-white.input:active,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-white:active,html.theme--catppuccin-macchiato .is-white.is-active.textarea,html.theme--catppuccin-macchiato .is-white.is-active.input,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(255,255,255,0.25)}html.theme--catppuccin-macchiato .is-black.textarea,html.theme--catppuccin-macchiato .is-black.input,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-black{border-color:#0a0a0a}html.theme--catppuccin-macchiato .is-black.textarea:focus,html.theme--catppuccin-macchiato .is-black.input:focus,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-black:focus,html.theme--catppuccin-macchiato .is-black.is-focused.textarea,html.theme--catppuccin-macchiato .is-black.is-focused.input,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--catppuccin-macchiato .is-black.textarea:active,html.theme--catppuccin-macchiato .is-black.input:active,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-black:active,html.theme--catppuccin-macchiato .is-black.is-active.textarea,html.theme--catppuccin-macchiato .is-black.is-active.input,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(10,10,10,0.25)}html.theme--catppuccin-macchiato .is-light.textarea,html.theme--catppuccin-macchiato .is-light.input,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-light{border-color:#f5f5f5}html.theme--catppuccin-macchiato .is-light.textarea:focus,html.theme--catppuccin-macchiato .is-light.input:focus,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-light:focus,html.theme--catppuccin-macchiato .is-light.is-focused.textarea,html.theme--catppuccin-macchiato .is-light.is-focused.input,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--catppuccin-macchiato .is-light.textarea:active,html.theme--catppuccin-macchiato .is-light.input:active,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-light:active,html.theme--catppuccin-macchiato .is-light.is-active.textarea,html.theme--catppuccin-macchiato .is-light.is-active.input,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(245,245,245,0.25)}html.theme--catppuccin-macchiato .is-dark.textarea,html.theme--catppuccin-macchiato .content kbd.textarea,html.theme--catppuccin-macchiato .is-dark.input,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-dark,html.theme--catppuccin-macchiato .content kbd.input{border-color:#363a4f}html.theme--catppuccin-macchiato .is-dark.textarea:focus,html.theme--catppuccin-macchiato .content kbd.textarea:focus,html.theme--catppuccin-macchiato .is-dark.input:focus,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-dark:focus,html.theme--catppuccin-macchiato .content kbd.input:focus,html.theme--catppuccin-macchiato .is-dark.is-focused.textarea,html.theme--catppuccin-macchiato .content kbd.is-focused.textarea,html.theme--catppuccin-macchiato .is-dark.is-focused.input,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--catppuccin-macchiato .content kbd.is-focused.input,html.theme--catppuccin-macchiato #documenter .docs-sidebar .content form.docs-search>input.is-focused,html.theme--catppuccin-macchiato .is-dark.textarea:active,html.theme--catppuccin-macchiato .content kbd.textarea:active,html.theme--catppuccin-macchiato .is-dark.input:active,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-dark:active,html.theme--catppuccin-macchiato .content kbd.input:active,html.theme--catppuccin-macchiato .is-dark.is-active.textarea,html.theme--catppuccin-macchiato .content kbd.is-active.textarea,html.theme--catppuccin-macchiato .is-dark.is-active.input,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-active,html.theme--catppuccin-macchiato .content kbd.is-active.input,html.theme--catppuccin-macchiato #documenter .docs-sidebar .content form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(54,58,79,0.25)}html.theme--catppuccin-macchiato .is-primary.textarea,html.theme--catppuccin-macchiato .docstring>section>a.textarea.docs-sourcelink,html.theme--catppuccin-macchiato .is-primary.input,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-primary,html.theme--catppuccin-macchiato .docstring>section>a.input.docs-sourcelink{border-color:#8aadf4}html.theme--catppuccin-macchiato .is-primary.textarea:focus,html.theme--catppuccin-macchiato .docstring>section>a.textarea.docs-sourcelink:focus,html.theme--catppuccin-macchiato .is-primary.input:focus,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-primary:focus,html.theme--catppuccin-macchiato .docstring>section>a.input.docs-sourcelink:focus,html.theme--catppuccin-macchiato .is-primary.is-focused.textarea,html.theme--catppuccin-macchiato .docstring>section>a.is-focused.textarea.docs-sourcelink,html.theme--catppuccin-macchiato .is-primary.is-focused.input,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--catppuccin-macchiato .docstring>section>a.is-focused.input.docs-sourcelink,html.theme--catppuccin-macchiato .is-primary.textarea:active,html.theme--catppuccin-macchiato .docstring>section>a.textarea.docs-sourcelink:active,html.theme--catppuccin-macchiato .is-primary.input:active,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-primary:active,html.theme--catppuccin-macchiato .docstring>section>a.input.docs-sourcelink:active,html.theme--catppuccin-macchiato .is-primary.is-active.textarea,html.theme--catppuccin-macchiato .docstring>section>a.is-active.textarea.docs-sourcelink,html.theme--catppuccin-macchiato .is-primary.is-active.input,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-active,html.theme--catppuccin-macchiato .docstring>section>a.is-active.input.docs-sourcelink{box-shadow:0 0 0 0.125em rgba(138,173,244,0.25)}html.theme--catppuccin-macchiato .is-link.textarea,html.theme--catppuccin-macchiato .is-link.input,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-link{border-color:#8aadf4}html.theme--catppuccin-macchiato .is-link.textarea:focus,html.theme--catppuccin-macchiato .is-link.input:focus,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-link:focus,html.theme--catppuccin-macchiato .is-link.is-focused.textarea,html.theme--catppuccin-macchiato .is-link.is-focused.input,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--catppuccin-macchiato .is-link.textarea:active,html.theme--catppuccin-macchiato .is-link.input:active,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-link:active,html.theme--catppuccin-macchiato .is-link.is-active.textarea,html.theme--catppuccin-macchiato .is-link.is-active.input,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(138,173,244,0.25)}html.theme--catppuccin-macchiato .is-info.textarea,html.theme--catppuccin-macchiato .is-info.input,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-info{border-color:#8bd5ca}html.theme--catppuccin-macchiato .is-info.textarea:focus,html.theme--catppuccin-macchiato .is-info.input:focus,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-info:focus,html.theme--catppuccin-macchiato .is-info.is-focused.textarea,html.theme--catppuccin-macchiato .is-info.is-focused.input,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--catppuccin-macchiato .is-info.textarea:active,html.theme--catppuccin-macchiato .is-info.input:active,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-info:active,html.theme--catppuccin-macchiato .is-info.is-active.textarea,html.theme--catppuccin-macchiato .is-info.is-active.input,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(139,213,202,0.25)}html.theme--catppuccin-macchiato .is-success.textarea,html.theme--catppuccin-macchiato .is-success.input,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-success{border-color:#a6da95}html.theme--catppuccin-macchiato .is-success.textarea:focus,html.theme--catppuccin-macchiato .is-success.input:focus,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-success:focus,html.theme--catppuccin-macchiato .is-success.is-focused.textarea,html.theme--catppuccin-macchiato .is-success.is-focused.input,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--catppuccin-macchiato .is-success.textarea:active,html.theme--catppuccin-macchiato .is-success.input:active,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-success:active,html.theme--catppuccin-macchiato .is-success.is-active.textarea,html.theme--catppuccin-macchiato .is-success.is-active.input,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(166,218,149,0.25)}html.theme--catppuccin-macchiato .is-warning.textarea,html.theme--catppuccin-macchiato .is-warning.input,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-warning{border-color:#eed49f}html.theme--catppuccin-macchiato .is-warning.textarea:focus,html.theme--catppuccin-macchiato .is-warning.input:focus,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-warning:focus,html.theme--catppuccin-macchiato .is-warning.is-focused.textarea,html.theme--catppuccin-macchiato .is-warning.is-focused.input,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--catppuccin-macchiato .is-warning.textarea:active,html.theme--catppuccin-macchiato .is-warning.input:active,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-warning:active,html.theme--catppuccin-macchiato .is-warning.is-active.textarea,html.theme--catppuccin-macchiato .is-warning.is-active.input,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(238,212,159,0.25)}html.theme--catppuccin-macchiato .is-danger.textarea,html.theme--catppuccin-macchiato .is-danger.input,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-danger{border-color:#ed8796}html.theme--catppuccin-macchiato .is-danger.textarea:focus,html.theme--catppuccin-macchiato .is-danger.input:focus,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-danger:focus,html.theme--catppuccin-macchiato .is-danger.is-focused.textarea,html.theme--catppuccin-macchiato .is-danger.is-focused.input,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--catppuccin-macchiato .is-danger.textarea:active,html.theme--catppuccin-macchiato .is-danger.input:active,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-danger:active,html.theme--catppuccin-macchiato .is-danger.is-active.textarea,html.theme--catppuccin-macchiato .is-danger.is-active.input,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(237,135,150,0.25)}html.theme--catppuccin-macchiato .is-small.textarea,html.theme--catppuccin-macchiato .is-small.input,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input{border-radius:3px;font-size:.75rem}html.theme--catppuccin-macchiato .is-medium.textarea,html.theme--catppuccin-macchiato .is-medium.input,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-medium{font-size:1.25rem}html.theme--catppuccin-macchiato .is-large.textarea,html.theme--catppuccin-macchiato .is-large.input,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-large{font-size:1.5rem}html.theme--catppuccin-macchiato .is-fullwidth.textarea,html.theme--catppuccin-macchiato .is-fullwidth.input,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-fullwidth{display:block;width:100%}html.theme--catppuccin-macchiato .is-inline.textarea,html.theme--catppuccin-macchiato .is-inline.input,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-inline{display:inline;width:auto}html.theme--catppuccin-macchiato .input.is-rounded,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input{border-radius:9999px;padding-left:calc(calc(0.75em - 1px) + 0.375em);padding-right:calc(calc(0.75em - 1px) + 0.375em)}html.theme--catppuccin-macchiato .input.is-static,html.theme--catppuccin-macchiato #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--catppuccin-macchiato .textarea{display:block;max-width:100%;min-width:100%;padding:calc(0.75em - 1px);resize:vertical}html.theme--catppuccin-macchiato .textarea:not([rows]){max-height:40em;min-height:8em}html.theme--catppuccin-macchiato .textarea[rows]{height:initial}html.theme--catppuccin-macchiato .textarea.has-fixed-size{resize:none}html.theme--catppuccin-macchiato .radio,html.theme--catppuccin-macchiato .checkbox{cursor:pointer;display:inline-block;line-height:1.25;position:relative}html.theme--catppuccin-macchiato .radio input,html.theme--catppuccin-macchiato .checkbox input{cursor:pointer}html.theme--catppuccin-macchiato .radio:hover,html.theme--catppuccin-macchiato .checkbox:hover{color:#91d7e3}html.theme--catppuccin-macchiato .radio[disabled],html.theme--catppuccin-macchiato .checkbox[disabled],fieldset[disabled] html.theme--catppuccin-macchiato .radio,fieldset[disabled] html.theme--catppuccin-macchiato .checkbox,html.theme--catppuccin-macchiato .radio input[disabled],html.theme--catppuccin-macchiato .checkbox input[disabled]{color:#f5f7fd;cursor:not-allowed}html.theme--catppuccin-macchiato .radio+.radio{margin-left:.5em}html.theme--catppuccin-macchiato .select{display:inline-block;max-width:100%;position:relative;vertical-align:top}html.theme--catppuccin-macchiato .select:not(.is-multiple){height:2.5em}html.theme--catppuccin-macchiato .select:not(.is-multiple):not(.is-loading)::after{border-color:#8aadf4;right:1.125em;z-index:4}html.theme--catppuccin-macchiato .select.is-rounded select,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.select select{border-radius:9999px;padding-left:1em}html.theme--catppuccin-macchiato .select select{cursor:pointer;display:block;font-size:1em;max-width:100%;outline:none}html.theme--catppuccin-macchiato .select select::-ms-expand{display:none}html.theme--catppuccin-macchiato .select select[disabled]:hover,fieldset[disabled] html.theme--catppuccin-macchiato .select select:hover{border-color:#1e2030}html.theme--catppuccin-macchiato .select select:not([multiple]){padding-right:2.5em}html.theme--catppuccin-macchiato .select select[multiple]{height:auto;padding:0}html.theme--catppuccin-macchiato .select select[multiple] option{padding:0.5em 1em}html.theme--catppuccin-macchiato .select:not(.is-multiple):not(.is-loading):hover::after{border-color:#91d7e3}html.theme--catppuccin-macchiato .select.is-white:not(:hover)::after{border-color:#fff}html.theme--catppuccin-macchiato .select.is-white select{border-color:#fff}html.theme--catppuccin-macchiato .select.is-white select:hover,html.theme--catppuccin-macchiato .select.is-white select.is-hovered{border-color:#f2f2f2}html.theme--catppuccin-macchiato .select.is-white select:focus,html.theme--catppuccin-macchiato .select.is-white select.is-focused,html.theme--catppuccin-macchiato .select.is-white select:active,html.theme--catppuccin-macchiato .select.is-white select.is-active{box-shadow:0 0 0 0.125em rgba(255,255,255,0.25)}html.theme--catppuccin-macchiato .select.is-black:not(:hover)::after{border-color:#0a0a0a}html.theme--catppuccin-macchiato .select.is-black select{border-color:#0a0a0a}html.theme--catppuccin-macchiato .select.is-black select:hover,html.theme--catppuccin-macchiato .select.is-black select.is-hovered{border-color:#000}html.theme--catppuccin-macchiato .select.is-black select:focus,html.theme--catppuccin-macchiato .select.is-black select.is-focused,html.theme--catppuccin-macchiato .select.is-black select:active,html.theme--catppuccin-macchiato .select.is-black select.is-active{box-shadow:0 0 0 0.125em rgba(10,10,10,0.25)}html.theme--catppuccin-macchiato .select.is-light:not(:hover)::after{border-color:#f5f5f5}html.theme--catppuccin-macchiato .select.is-light select{border-color:#f5f5f5}html.theme--catppuccin-macchiato .select.is-light select:hover,html.theme--catppuccin-macchiato .select.is-light select.is-hovered{border-color:#e8e8e8}html.theme--catppuccin-macchiato .select.is-light select:focus,html.theme--catppuccin-macchiato .select.is-light select.is-focused,html.theme--catppuccin-macchiato .select.is-light select:active,html.theme--catppuccin-macchiato .select.is-light select.is-active{box-shadow:0 0 0 0.125em rgba(245,245,245,0.25)}html.theme--catppuccin-macchiato .select.is-dark:not(:hover)::after,html.theme--catppuccin-macchiato .content kbd.select:not(:hover)::after{border-color:#363a4f}html.theme--catppuccin-macchiato .select.is-dark select,html.theme--catppuccin-macchiato .content kbd.select select{border-color:#363a4f}html.theme--catppuccin-macchiato .select.is-dark select:hover,html.theme--catppuccin-macchiato .content kbd.select select:hover,html.theme--catppuccin-macchiato .select.is-dark select.is-hovered,html.theme--catppuccin-macchiato .content kbd.select select.is-hovered{border-color:#2c2f40}html.theme--catppuccin-macchiato .select.is-dark select:focus,html.theme--catppuccin-macchiato .content kbd.select select:focus,html.theme--catppuccin-macchiato .select.is-dark select.is-focused,html.theme--catppuccin-macchiato .content kbd.select select.is-focused,html.theme--catppuccin-macchiato .select.is-dark select:active,html.theme--catppuccin-macchiato .content kbd.select select:active,html.theme--catppuccin-macchiato .select.is-dark select.is-active,html.theme--catppuccin-macchiato .content kbd.select select.is-active{box-shadow:0 0 0 0.125em rgba(54,58,79,0.25)}html.theme--catppuccin-macchiato .select.is-primary:not(:hover)::after,html.theme--catppuccin-macchiato .docstring>section>a.select.docs-sourcelink:not(:hover)::after{border-color:#8aadf4}html.theme--catppuccin-macchiato .select.is-primary select,html.theme--catppuccin-macchiato .docstring>section>a.select.docs-sourcelink select{border-color:#8aadf4}html.theme--catppuccin-macchiato .select.is-primary select:hover,html.theme--catppuccin-macchiato .docstring>section>a.select.docs-sourcelink select:hover,html.theme--catppuccin-macchiato .select.is-primary select.is-hovered,html.theme--catppuccin-macchiato .docstring>section>a.select.docs-sourcelink select.is-hovered{border-color:#739df2}html.theme--catppuccin-macchiato .select.is-primary select:focus,html.theme--catppuccin-macchiato .docstring>section>a.select.docs-sourcelink select:focus,html.theme--catppuccin-macchiato .select.is-primary select.is-focused,html.theme--catppuccin-macchiato .docstring>section>a.select.docs-sourcelink select.is-focused,html.theme--catppuccin-macchiato .select.is-primary select:active,html.theme--catppuccin-macchiato .docstring>section>a.select.docs-sourcelink select:active,html.theme--catppuccin-macchiato .select.is-primary select.is-active,html.theme--catppuccin-macchiato .docstring>section>a.select.docs-sourcelink select.is-active{box-shadow:0 0 0 0.125em rgba(138,173,244,0.25)}html.theme--catppuccin-macchiato .select.is-link:not(:hover)::after{border-color:#8aadf4}html.theme--catppuccin-macchiato .select.is-link select{border-color:#8aadf4}html.theme--catppuccin-macchiato .select.is-link select:hover,html.theme--catppuccin-macchiato .select.is-link select.is-hovered{border-color:#739df2}html.theme--catppuccin-macchiato .select.is-link select:focus,html.theme--catppuccin-macchiato .select.is-link select.is-focused,html.theme--catppuccin-macchiato .select.is-link select:active,html.theme--catppuccin-macchiato .select.is-link select.is-active{box-shadow:0 0 0 0.125em rgba(138,173,244,0.25)}html.theme--catppuccin-macchiato .select.is-info:not(:hover)::after{border-color:#8bd5ca}html.theme--catppuccin-macchiato .select.is-info select{border-color:#8bd5ca}html.theme--catppuccin-macchiato .select.is-info select:hover,html.theme--catppuccin-macchiato .select.is-info select.is-hovered{border-color:#78cec1}html.theme--catppuccin-macchiato .select.is-info select:focus,html.theme--catppuccin-macchiato .select.is-info select.is-focused,html.theme--catppuccin-macchiato .select.is-info select:active,html.theme--catppuccin-macchiato .select.is-info select.is-active{box-shadow:0 0 0 0.125em rgba(139,213,202,0.25)}html.theme--catppuccin-macchiato .select.is-success:not(:hover)::after{border-color:#a6da95}html.theme--catppuccin-macchiato .select.is-success select{border-color:#a6da95}html.theme--catppuccin-macchiato .select.is-success select:hover,html.theme--catppuccin-macchiato .select.is-success select.is-hovered{border-color:#96d382}html.theme--catppuccin-macchiato .select.is-success select:focus,html.theme--catppuccin-macchiato .select.is-success select.is-focused,html.theme--catppuccin-macchiato .select.is-success select:active,html.theme--catppuccin-macchiato .select.is-success select.is-active{box-shadow:0 0 0 0.125em rgba(166,218,149,0.25)}html.theme--catppuccin-macchiato .select.is-warning:not(:hover)::after{border-color:#eed49f}html.theme--catppuccin-macchiato .select.is-warning select{border-color:#eed49f}html.theme--catppuccin-macchiato .select.is-warning select:hover,html.theme--catppuccin-macchiato .select.is-warning select.is-hovered{border-color:#eaca89}html.theme--catppuccin-macchiato .select.is-warning select:focus,html.theme--catppuccin-macchiato .select.is-warning select.is-focused,html.theme--catppuccin-macchiato .select.is-warning select:active,html.theme--catppuccin-macchiato .select.is-warning select.is-active{box-shadow:0 0 0 0.125em rgba(238,212,159,0.25)}html.theme--catppuccin-macchiato .select.is-danger:not(:hover)::after{border-color:#ed8796}html.theme--catppuccin-macchiato .select.is-danger select{border-color:#ed8796}html.theme--catppuccin-macchiato .select.is-danger select:hover,html.theme--catppuccin-macchiato .select.is-danger select.is-hovered{border-color:#ea7183}html.theme--catppuccin-macchiato .select.is-danger select:focus,html.theme--catppuccin-macchiato .select.is-danger select.is-focused,html.theme--catppuccin-macchiato .select.is-danger select:active,html.theme--catppuccin-macchiato .select.is-danger select.is-active{box-shadow:0 0 0 0.125em rgba(237,135,150,0.25)}html.theme--catppuccin-macchiato .select.is-small,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.select{border-radius:3px;font-size:.75rem}html.theme--catppuccin-macchiato .select.is-medium{font-size:1.25rem}html.theme--catppuccin-macchiato .select.is-large{font-size:1.5rem}html.theme--catppuccin-macchiato .select.is-disabled::after{border-color:#f5f7fd !important;opacity:0.5}html.theme--catppuccin-macchiato .select.is-fullwidth{width:100%}html.theme--catppuccin-macchiato .select.is-fullwidth select{width:100%}html.theme--catppuccin-macchiato .select.is-loading::after{margin-top:0;position:absolute;right:.625em;top:0.625em;transform:none}html.theme--catppuccin-macchiato .select.is-loading.is-small:after,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-loading:after{font-size:.75rem}html.theme--catppuccin-macchiato .select.is-loading.is-medium:after{font-size:1.25rem}html.theme--catppuccin-macchiato .select.is-loading.is-large:after{font-size:1.5rem}html.theme--catppuccin-macchiato .file{align-items:stretch;display:flex;justify-content:flex-start;position:relative}html.theme--catppuccin-macchiato .file.is-white .file-cta{background-color:#fff;border-color:transparent;color:#0a0a0a}html.theme--catppuccin-macchiato .file.is-white:hover .file-cta,html.theme--catppuccin-macchiato .file.is-white.is-hovered .file-cta{background-color:#f9f9f9;border-color:transparent;color:#0a0a0a}html.theme--catppuccin-macchiato .file.is-white:focus .file-cta,html.theme--catppuccin-macchiato .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--catppuccin-macchiato .file.is-white:active .file-cta,html.theme--catppuccin-macchiato .file.is-white.is-active .file-cta{background-color:#f2f2f2;border-color:transparent;color:#0a0a0a}html.theme--catppuccin-macchiato .file.is-black .file-cta{background-color:#0a0a0a;border-color:transparent;color:#fff}html.theme--catppuccin-macchiato .file.is-black:hover .file-cta,html.theme--catppuccin-macchiato .file.is-black.is-hovered .file-cta{background-color:#040404;border-color:transparent;color:#fff}html.theme--catppuccin-macchiato .file.is-black:focus .file-cta,html.theme--catppuccin-macchiato .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--catppuccin-macchiato .file.is-black:active .file-cta,html.theme--catppuccin-macchiato .file.is-black.is-active .file-cta{background-color:#000;border-color:transparent;color:#fff}html.theme--catppuccin-macchiato .file.is-light .file-cta{background-color:#f5f5f5;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .file.is-light:hover .file-cta,html.theme--catppuccin-macchiato .file.is-light.is-hovered .file-cta{background-color:#eee;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .file.is-light:focus .file-cta,html.theme--catppuccin-macchiato .file.is-light.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(245,245,245,0.25);color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .file.is-light:active .file-cta,html.theme--catppuccin-macchiato .file.is-light.is-active .file-cta{background-color:#e8e8e8;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .file.is-dark .file-cta,html.theme--catppuccin-macchiato .content kbd.file .file-cta{background-color:#363a4f;border-color:transparent;color:#fff}html.theme--catppuccin-macchiato .file.is-dark:hover .file-cta,html.theme--catppuccin-macchiato .content kbd.file:hover .file-cta,html.theme--catppuccin-macchiato .file.is-dark.is-hovered .file-cta,html.theme--catppuccin-macchiato .content kbd.file.is-hovered .file-cta{background-color:#313447;border-color:transparent;color:#fff}html.theme--catppuccin-macchiato .file.is-dark:focus .file-cta,html.theme--catppuccin-macchiato .content kbd.file:focus .file-cta,html.theme--catppuccin-macchiato .file.is-dark.is-focused .file-cta,html.theme--catppuccin-macchiato .content kbd.file.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(54,58,79,0.25);color:#fff}html.theme--catppuccin-macchiato .file.is-dark:active .file-cta,html.theme--catppuccin-macchiato .content kbd.file:active .file-cta,html.theme--catppuccin-macchiato .file.is-dark.is-active .file-cta,html.theme--catppuccin-macchiato .content kbd.file.is-active .file-cta{background-color:#2c2f40;border-color:transparent;color:#fff}html.theme--catppuccin-macchiato .file.is-primary .file-cta,html.theme--catppuccin-macchiato .docstring>section>a.file.docs-sourcelink .file-cta{background-color:#8aadf4;border-color:transparent;color:#fff}html.theme--catppuccin-macchiato .file.is-primary:hover .file-cta,html.theme--catppuccin-macchiato .docstring>section>a.file.docs-sourcelink:hover .file-cta,html.theme--catppuccin-macchiato .file.is-primary.is-hovered .file-cta,html.theme--catppuccin-macchiato .docstring>section>a.file.is-hovered.docs-sourcelink .file-cta{background-color:#7ea5f3;border-color:transparent;color:#fff}html.theme--catppuccin-macchiato .file.is-primary:focus .file-cta,html.theme--catppuccin-macchiato .docstring>section>a.file.docs-sourcelink:focus .file-cta,html.theme--catppuccin-macchiato .file.is-primary.is-focused .file-cta,html.theme--catppuccin-macchiato .docstring>section>a.file.is-focused.docs-sourcelink .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(138,173,244,0.25);color:#fff}html.theme--catppuccin-macchiato .file.is-primary:active .file-cta,html.theme--catppuccin-macchiato .docstring>section>a.file.docs-sourcelink:active .file-cta,html.theme--catppuccin-macchiato .file.is-primary.is-active .file-cta,html.theme--catppuccin-macchiato .docstring>section>a.file.is-active.docs-sourcelink .file-cta{background-color:#739df2;border-color:transparent;color:#fff}html.theme--catppuccin-macchiato .file.is-link .file-cta{background-color:#8aadf4;border-color:transparent;color:#fff}html.theme--catppuccin-macchiato .file.is-link:hover .file-cta,html.theme--catppuccin-macchiato .file.is-link.is-hovered .file-cta{background-color:#7ea5f3;border-color:transparent;color:#fff}html.theme--catppuccin-macchiato .file.is-link:focus .file-cta,html.theme--catppuccin-macchiato .file.is-link.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(138,173,244,0.25);color:#fff}html.theme--catppuccin-macchiato .file.is-link:active .file-cta,html.theme--catppuccin-macchiato .file.is-link.is-active .file-cta{background-color:#739df2;border-color:transparent;color:#fff}html.theme--catppuccin-macchiato .file.is-info .file-cta{background-color:#8bd5ca;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .file.is-info:hover .file-cta,html.theme--catppuccin-macchiato .file.is-info.is-hovered .file-cta{background-color:#82d2c6;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .file.is-info:focus .file-cta,html.theme--catppuccin-macchiato .file.is-info.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(139,213,202,0.25);color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .file.is-info:active .file-cta,html.theme--catppuccin-macchiato .file.is-info.is-active .file-cta{background-color:#78cec1;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .file.is-success .file-cta{background-color:#a6da95;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .file.is-success:hover .file-cta,html.theme--catppuccin-macchiato .file.is-success.is-hovered .file-cta{background-color:#9ed78c;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .file.is-success:focus .file-cta,html.theme--catppuccin-macchiato .file.is-success.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(166,218,149,0.25);color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .file.is-success:active .file-cta,html.theme--catppuccin-macchiato .file.is-success.is-active .file-cta{background-color:#96d382;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .file.is-warning .file-cta{background-color:#eed49f;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .file.is-warning:hover .file-cta,html.theme--catppuccin-macchiato .file.is-warning.is-hovered .file-cta{background-color:#eccf94;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .file.is-warning:focus .file-cta,html.theme--catppuccin-macchiato .file.is-warning.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(238,212,159,0.25);color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .file.is-warning:active .file-cta,html.theme--catppuccin-macchiato .file.is-warning.is-active .file-cta{background-color:#eaca89;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .file.is-danger .file-cta{background-color:#ed8796;border-color:transparent;color:#fff}html.theme--catppuccin-macchiato .file.is-danger:hover .file-cta,html.theme--catppuccin-macchiato .file.is-danger.is-hovered .file-cta{background-color:#eb7c8c;border-color:transparent;color:#fff}html.theme--catppuccin-macchiato .file.is-danger:focus .file-cta,html.theme--catppuccin-macchiato .file.is-danger.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(237,135,150,0.25);color:#fff}html.theme--catppuccin-macchiato .file.is-danger:active .file-cta,html.theme--catppuccin-macchiato .file.is-danger.is-active .file-cta{background-color:#ea7183;border-color:transparent;color:#fff}html.theme--catppuccin-macchiato .file.is-small,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.file{font-size:.75rem}html.theme--catppuccin-macchiato .file.is-normal{font-size:1rem}html.theme--catppuccin-macchiato .file.is-medium{font-size:1.25rem}html.theme--catppuccin-macchiato .file.is-medium .file-icon .fa{font-size:21px}html.theme--catppuccin-macchiato .file.is-large{font-size:1.5rem}html.theme--catppuccin-macchiato .file.is-large .file-icon .fa{font-size:28px}html.theme--catppuccin-macchiato .file.has-name .file-cta{border-bottom-right-radius:0;border-top-right-radius:0}html.theme--catppuccin-macchiato .file.has-name .file-name{border-bottom-left-radius:0;border-top-left-radius:0}html.theme--catppuccin-macchiato .file.has-name.is-empty .file-cta{border-radius:.4em}html.theme--catppuccin-macchiato .file.has-name.is-empty .file-name{display:none}html.theme--catppuccin-macchiato .file.is-boxed .file-label{flex-direction:column}html.theme--catppuccin-macchiato .file.is-boxed .file-cta{flex-direction:column;height:auto;padding:1em 3em}html.theme--catppuccin-macchiato .file.is-boxed .file-name{border-width:0 1px 1px}html.theme--catppuccin-macchiato .file.is-boxed .file-icon{height:1.5em;width:1.5em}html.theme--catppuccin-macchiato .file.is-boxed .file-icon .fa{font-size:21px}html.theme--catppuccin-macchiato .file.is-boxed.is-small .file-icon .fa,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-boxed .file-icon .fa{font-size:14px}html.theme--catppuccin-macchiato .file.is-boxed.is-medium .file-icon .fa{font-size:28px}html.theme--catppuccin-macchiato .file.is-boxed.is-large .file-icon .fa{font-size:35px}html.theme--catppuccin-macchiato .file.is-boxed.has-name .file-cta{border-radius:.4em .4em 0 0}html.theme--catppuccin-macchiato .file.is-boxed.has-name .file-name{border-radius:0 0 .4em .4em;border-width:0 1px 1px}html.theme--catppuccin-macchiato .file.is-centered{justify-content:center}html.theme--catppuccin-macchiato .file.is-fullwidth .file-label{width:100%}html.theme--catppuccin-macchiato .file.is-fullwidth .file-name{flex-grow:1;max-width:none}html.theme--catppuccin-macchiato .file.is-right{justify-content:flex-end}html.theme--catppuccin-macchiato .file.is-right .file-cta{border-radius:0 .4em .4em 0}html.theme--catppuccin-macchiato .file.is-right .file-name{border-radius:.4em 0 0 .4em;border-width:1px 0 1px 1px;order:-1}html.theme--catppuccin-macchiato .file-label{align-items:stretch;display:flex;cursor:pointer;justify-content:flex-start;overflow:hidden;position:relative}html.theme--catppuccin-macchiato .file-label:hover .file-cta{background-color:#313447;color:#b5c1f1}html.theme--catppuccin-macchiato .file-label:hover .file-name{border-color:#565a71}html.theme--catppuccin-macchiato .file-label:active .file-cta{background-color:#2c2f40;color:#b5c1f1}html.theme--catppuccin-macchiato .file-label:active .file-name{border-color:#505469}html.theme--catppuccin-macchiato .file-input{height:100%;left:0;opacity:0;outline:none;position:absolute;top:0;width:100%}html.theme--catppuccin-macchiato .file-cta,html.theme--catppuccin-macchiato .file-name{border-color:#5b6078;border-radius:.4em;font-size:1em;padding-left:1em;padding-right:1em;white-space:nowrap}html.theme--catppuccin-macchiato .file-cta{background-color:#363a4f;color:#cad3f5}html.theme--catppuccin-macchiato .file-name{border-color:#5b6078;border-style:solid;border-width:1px 1px 1px 0;display:block;max-width:16em;overflow:hidden;text-align:inherit;text-overflow:ellipsis}html.theme--catppuccin-macchiato .file-icon{align-items:center;display:flex;height:1em;justify-content:center;margin-right:.5em;width:1em}html.theme--catppuccin-macchiato .file-icon .fa{font-size:14px}html.theme--catppuccin-macchiato .label{color:#b5c1f1;display:block;font-size:1rem;font-weight:700}html.theme--catppuccin-macchiato .label:not(:last-child){margin-bottom:0.5em}html.theme--catppuccin-macchiato .label.is-small,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.label{font-size:.75rem}html.theme--catppuccin-macchiato .label.is-medium{font-size:1.25rem}html.theme--catppuccin-macchiato .label.is-large{font-size:1.5rem}html.theme--catppuccin-macchiato .help{display:block;font-size:.75rem;margin-top:0.25rem}html.theme--catppuccin-macchiato .help.is-white{color:#fff}html.theme--catppuccin-macchiato .help.is-black{color:#0a0a0a}html.theme--catppuccin-macchiato .help.is-light{color:#f5f5f5}html.theme--catppuccin-macchiato .help.is-dark,html.theme--catppuccin-macchiato .content kbd.help{color:#363a4f}html.theme--catppuccin-macchiato .help.is-primary,html.theme--catppuccin-macchiato .docstring>section>a.help.docs-sourcelink{color:#8aadf4}html.theme--catppuccin-macchiato .help.is-link{color:#8aadf4}html.theme--catppuccin-macchiato .help.is-info{color:#8bd5ca}html.theme--catppuccin-macchiato .help.is-success{color:#a6da95}html.theme--catppuccin-macchiato .help.is-warning{color:#eed49f}html.theme--catppuccin-macchiato .help.is-danger{color:#ed8796}html.theme--catppuccin-macchiato .field:not(:last-child){margin-bottom:0.75rem}html.theme--catppuccin-macchiato .field.has-addons{display:flex;justify-content:flex-start}html.theme--catppuccin-macchiato .field.has-addons .control:not(:last-child){margin-right:-1px}html.theme--catppuccin-macchiato .field.has-addons .control:not(:first-child):not(:last-child) .button,html.theme--catppuccin-macchiato .field.has-addons .control:not(:first-child):not(:last-child) .input,html.theme--catppuccin-macchiato .field.has-addons .control:not(:first-child):not(:last-child) #documenter .docs-sidebar form.docs-search>input,html.theme--catppuccin-macchiato #documenter .docs-sidebar .field.has-addons .control:not(:first-child):not(:last-child) form.docs-search>input,html.theme--catppuccin-macchiato .field.has-addons .control:not(:first-child):not(:last-child) .select select{border-radius:0}html.theme--catppuccin-macchiato .field.has-addons .control:first-child:not(:only-child) .button,html.theme--catppuccin-macchiato .field.has-addons .control:first-child:not(:only-child) .input,html.theme--catppuccin-macchiato .field.has-addons .control:first-child:not(:only-child) #documenter .docs-sidebar form.docs-search>input,html.theme--catppuccin-macchiato #documenter .docs-sidebar .field.has-addons .control:first-child:not(:only-child) form.docs-search>input,html.theme--catppuccin-macchiato .field.has-addons .control:first-child:not(:only-child) .select select{border-bottom-right-radius:0;border-top-right-radius:0}html.theme--catppuccin-macchiato .field.has-addons .control:last-child:not(:only-child) .button,html.theme--catppuccin-macchiato .field.has-addons .control:last-child:not(:only-child) .input,html.theme--catppuccin-macchiato .field.has-addons .control:last-child:not(:only-child) #documenter .docs-sidebar form.docs-search>input,html.theme--catppuccin-macchiato #documenter .docs-sidebar .field.has-addons .control:last-child:not(:only-child) form.docs-search>input,html.theme--catppuccin-macchiato .field.has-addons .control:last-child:not(:only-child) .select select{border-bottom-left-radius:0;border-top-left-radius:0}html.theme--catppuccin-macchiato .field.has-addons .control .button:not([disabled]):hover,html.theme--catppuccin-macchiato .field.has-addons .control .button.is-hovered:not([disabled]),html.theme--catppuccin-macchiato .field.has-addons .control .input:not([disabled]):hover,html.theme--catppuccin-macchiato .field.has-addons .control #documenter .docs-sidebar form.docs-search>input:not([disabled]):hover,html.theme--catppuccin-macchiato #documenter .docs-sidebar .field.has-addons .control form.docs-search>input:not([disabled]):hover,html.theme--catppuccin-macchiato .field.has-addons .control .input.is-hovered:not([disabled]),html.theme--catppuccin-macchiato .field.has-addons .control #documenter .docs-sidebar form.docs-search>input.is-hovered:not([disabled]),html.theme--catppuccin-macchiato #documenter .docs-sidebar .field.has-addons .control form.docs-search>input.is-hovered:not([disabled]),html.theme--catppuccin-macchiato .field.has-addons .control .select select:not([disabled]):hover,html.theme--catppuccin-macchiato .field.has-addons .control .select select.is-hovered:not([disabled]){z-index:2}html.theme--catppuccin-macchiato .field.has-addons .control .button:not([disabled]):focus,html.theme--catppuccin-macchiato .field.has-addons .control .button.is-focused:not([disabled]),html.theme--catppuccin-macchiato .field.has-addons .control .button:not([disabled]):active,html.theme--catppuccin-macchiato .field.has-addons .control .button.is-active:not([disabled]),html.theme--catppuccin-macchiato .field.has-addons .control .input:not([disabled]):focus,html.theme--catppuccin-macchiato .field.has-addons .control #documenter .docs-sidebar form.docs-search>input:not([disabled]):focus,html.theme--catppuccin-macchiato #documenter .docs-sidebar .field.has-addons .control form.docs-search>input:not([disabled]):focus,html.theme--catppuccin-macchiato .field.has-addons .control .input.is-focused:not([disabled]),html.theme--catppuccin-macchiato .field.has-addons .control #documenter .docs-sidebar form.docs-search>input.is-focused:not([disabled]),html.theme--catppuccin-macchiato #documenter .docs-sidebar .field.has-addons .control form.docs-search>input.is-focused:not([disabled]),html.theme--catppuccin-macchiato .field.has-addons .control .input:not([disabled]):active,html.theme--catppuccin-macchiato .field.has-addons .control #documenter .docs-sidebar form.docs-search>input:not([disabled]):active,html.theme--catppuccin-macchiato #documenter .docs-sidebar .field.has-addons .control form.docs-search>input:not([disabled]):active,html.theme--catppuccin-macchiato .field.has-addons .control .input.is-active:not([disabled]),html.theme--catppuccin-macchiato .field.has-addons .control #documenter .docs-sidebar form.docs-search>input.is-active:not([disabled]),html.theme--catppuccin-macchiato #documenter .docs-sidebar .field.has-addons .control form.docs-search>input.is-active:not([disabled]),html.theme--catppuccin-macchiato .field.has-addons .control .select select:not([disabled]):focus,html.theme--catppuccin-macchiato .field.has-addons .control .select select.is-focused:not([disabled]),html.theme--catppuccin-macchiato .field.has-addons .control .select select:not([disabled]):active,html.theme--catppuccin-macchiato .field.has-addons .control .select select.is-active:not([disabled]){z-index:3}html.theme--catppuccin-macchiato .field.has-addons .control .button:not([disabled]):focus:hover,html.theme--catppuccin-macchiato .field.has-addons .control .button.is-focused:not([disabled]):hover,html.theme--catppuccin-macchiato .field.has-addons .control .button:not([disabled]):active:hover,html.theme--catppuccin-macchiato .field.has-addons .control .button.is-active:not([disabled]):hover,html.theme--catppuccin-macchiato .field.has-addons .control .input:not([disabled]):focus:hover,html.theme--catppuccin-macchiato .field.has-addons .control #documenter .docs-sidebar form.docs-search>input:not([disabled]):focus:hover,html.theme--catppuccin-macchiato #documenter .docs-sidebar .field.has-addons .control form.docs-search>input:not([disabled]):focus:hover,html.theme--catppuccin-macchiato .field.has-addons .control .input.is-focused:not([disabled]):hover,html.theme--catppuccin-macchiato .field.has-addons .control #documenter .docs-sidebar form.docs-search>input.is-focused:not([disabled]):hover,html.theme--catppuccin-macchiato #documenter .docs-sidebar .field.has-addons .control form.docs-search>input.is-focused:not([disabled]):hover,html.theme--catppuccin-macchiato .field.has-addons .control .input:not([disabled]):active:hover,html.theme--catppuccin-macchiato .field.has-addons .control #documenter .docs-sidebar form.docs-search>input:not([disabled]):active:hover,html.theme--catppuccin-macchiato #documenter .docs-sidebar .field.has-addons .control form.docs-search>input:not([disabled]):active:hover,html.theme--catppuccin-macchiato .field.has-addons .control .input.is-active:not([disabled]):hover,html.theme--catppuccin-macchiato .field.has-addons .control #documenter .docs-sidebar form.docs-search>input.is-active:not([disabled]):hover,html.theme--catppuccin-macchiato #documenter .docs-sidebar .field.has-addons .control form.docs-search>input.is-active:not([disabled]):hover,html.theme--catppuccin-macchiato .field.has-addons .control .select select:not([disabled]):focus:hover,html.theme--catppuccin-macchiato .field.has-addons .control .select select.is-focused:not([disabled]):hover,html.theme--catppuccin-macchiato .field.has-addons .control .select select:not([disabled]):active:hover,html.theme--catppuccin-macchiato .field.has-addons .control .select select.is-active:not([disabled]):hover{z-index:4}html.theme--catppuccin-macchiato .field.has-addons .control.is-expanded{flex-grow:1;flex-shrink:1}html.theme--catppuccin-macchiato .field.has-addons.has-addons-centered{justify-content:center}html.theme--catppuccin-macchiato .field.has-addons.has-addons-right{justify-content:flex-end}html.theme--catppuccin-macchiato .field.has-addons.has-addons-fullwidth .control{flex-grow:1;flex-shrink:0}html.theme--catppuccin-macchiato .field.is-grouped{display:flex;justify-content:flex-start}html.theme--catppuccin-macchiato .field.is-grouped>.control{flex-shrink:0}html.theme--catppuccin-macchiato .field.is-grouped>.control:not(:last-child){margin-bottom:0;margin-right:.75rem}html.theme--catppuccin-macchiato .field.is-grouped>.control.is-expanded{flex-grow:1;flex-shrink:1}html.theme--catppuccin-macchiato .field.is-grouped.is-grouped-centered{justify-content:center}html.theme--catppuccin-macchiato .field.is-grouped.is-grouped-right{justify-content:flex-end}html.theme--catppuccin-macchiato .field.is-grouped.is-grouped-multiline{flex-wrap:wrap}html.theme--catppuccin-macchiato .field.is-grouped.is-grouped-multiline>.control:last-child,html.theme--catppuccin-macchiato .field.is-grouped.is-grouped-multiline>.control:not(:last-child){margin-bottom:0.75rem}html.theme--catppuccin-macchiato .field.is-grouped.is-grouped-multiline:last-child{margin-bottom:-0.75rem}html.theme--catppuccin-macchiato .field.is-grouped.is-grouped-multiline:not(:last-child){margin-bottom:0}@media screen and (min-width: 769px),print{html.theme--catppuccin-macchiato .field.is-horizontal{display:flex}}html.theme--catppuccin-macchiato .field-label .label{font-size:inherit}@media screen and (max-width: 768px){html.theme--catppuccin-macchiato .field-label{margin-bottom:0.5rem}}@media screen and (min-width: 769px),print{html.theme--catppuccin-macchiato .field-label{flex-basis:0;flex-grow:1;flex-shrink:0;margin-right:1.5rem;text-align:right}html.theme--catppuccin-macchiato .field-label.is-small,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.field-label{font-size:.75rem;padding-top:0.375em}html.theme--catppuccin-macchiato .field-label.is-normal{padding-top:0.375em}html.theme--catppuccin-macchiato .field-label.is-medium{font-size:1.25rem;padding-top:0.375em}html.theme--catppuccin-macchiato .field-label.is-large{font-size:1.5rem;padding-top:0.375em}}html.theme--catppuccin-macchiato .field-body .field .field{margin-bottom:0}@media screen and (min-width: 769px),print{html.theme--catppuccin-macchiato .field-body{display:flex;flex-basis:0;flex-grow:5;flex-shrink:1}html.theme--catppuccin-macchiato .field-body .field{margin-bottom:0}html.theme--catppuccin-macchiato .field-body>.field{flex-shrink:1}html.theme--catppuccin-macchiato .field-body>.field:not(.is-narrow){flex-grow:1}html.theme--catppuccin-macchiato .field-body>.field:not(:last-child){margin-right:.75rem}}html.theme--catppuccin-macchiato .control{box-sizing:border-box;clear:both;font-size:1rem;position:relative;text-align:inherit}html.theme--catppuccin-macchiato .control.has-icons-left .input:focus~.icon,html.theme--catppuccin-macchiato .control.has-icons-left #documenter .docs-sidebar form.docs-search>input:focus~.icon,html.theme--catppuccin-macchiato #documenter .docs-sidebar .control.has-icons-left form.docs-search>input:focus~.icon,html.theme--catppuccin-macchiato .control.has-icons-left .select:focus~.icon,html.theme--catppuccin-macchiato .control.has-icons-right .input:focus~.icon,html.theme--catppuccin-macchiato .control.has-icons-right #documenter .docs-sidebar form.docs-search>input:focus~.icon,html.theme--catppuccin-macchiato #documenter .docs-sidebar .control.has-icons-right form.docs-search>input:focus~.icon,html.theme--catppuccin-macchiato .control.has-icons-right .select:focus~.icon{color:#363a4f}html.theme--catppuccin-macchiato .control.has-icons-left .input.is-small~.icon,html.theme--catppuccin-macchiato .control.has-icons-left #documenter .docs-sidebar form.docs-search>input~.icon,html.theme--catppuccin-macchiato #documenter .docs-sidebar .control.has-icons-left form.docs-search>input~.icon,html.theme--catppuccin-macchiato .control.has-icons-left .select.is-small~.icon,html.theme--catppuccin-macchiato .control.has-icons-right .input.is-small~.icon,html.theme--catppuccin-macchiato .control.has-icons-right #documenter .docs-sidebar form.docs-search>input~.icon,html.theme--catppuccin-macchiato #documenter .docs-sidebar .control.has-icons-right form.docs-search>input~.icon,html.theme--catppuccin-macchiato .control.has-icons-right .select.is-small~.icon{font-size:.75rem}html.theme--catppuccin-macchiato .control.has-icons-left .input.is-medium~.icon,html.theme--catppuccin-macchiato .control.has-icons-left #documenter .docs-sidebar form.docs-search>input.is-medium~.icon,html.theme--catppuccin-macchiato #documenter .docs-sidebar .control.has-icons-left form.docs-search>input.is-medium~.icon,html.theme--catppuccin-macchiato .control.has-icons-left .select.is-medium~.icon,html.theme--catppuccin-macchiato .control.has-icons-right .input.is-medium~.icon,html.theme--catppuccin-macchiato .control.has-icons-right #documenter .docs-sidebar form.docs-search>input.is-medium~.icon,html.theme--catppuccin-macchiato #documenter .docs-sidebar .control.has-icons-right form.docs-search>input.is-medium~.icon,html.theme--catppuccin-macchiato .control.has-icons-right .select.is-medium~.icon{font-size:1.25rem}html.theme--catppuccin-macchiato .control.has-icons-left .input.is-large~.icon,html.theme--catppuccin-macchiato .control.has-icons-left #documenter .docs-sidebar form.docs-search>input.is-large~.icon,html.theme--catppuccin-macchiato #documenter .docs-sidebar .control.has-icons-left form.docs-search>input.is-large~.icon,html.theme--catppuccin-macchiato .control.has-icons-left .select.is-large~.icon,html.theme--catppuccin-macchiato .control.has-icons-right .input.is-large~.icon,html.theme--catppuccin-macchiato .control.has-icons-right #documenter .docs-sidebar form.docs-search>input.is-large~.icon,html.theme--catppuccin-macchiato #documenter .docs-sidebar .control.has-icons-right form.docs-search>input.is-large~.icon,html.theme--catppuccin-macchiato .control.has-icons-right .select.is-large~.icon{font-size:1.5rem}html.theme--catppuccin-macchiato .control.has-icons-left .icon,html.theme--catppuccin-macchiato .control.has-icons-right .icon{color:#5b6078;height:2.5em;pointer-events:none;position:absolute;top:0;width:2.5em;z-index:4}html.theme--catppuccin-macchiato .control.has-icons-left .input,html.theme--catppuccin-macchiato .control.has-icons-left #documenter .docs-sidebar form.docs-search>input,html.theme--catppuccin-macchiato #documenter .docs-sidebar .control.has-icons-left form.docs-search>input,html.theme--catppuccin-macchiato .control.has-icons-left .select select{padding-left:2.5em}html.theme--catppuccin-macchiato .control.has-icons-left .icon.is-left{left:0}html.theme--catppuccin-macchiato .control.has-icons-right .input,html.theme--catppuccin-macchiato .control.has-icons-right #documenter .docs-sidebar form.docs-search>input,html.theme--catppuccin-macchiato #documenter .docs-sidebar .control.has-icons-right form.docs-search>input,html.theme--catppuccin-macchiato .control.has-icons-right .select select{padding-right:2.5em}html.theme--catppuccin-macchiato .control.has-icons-right .icon.is-right{right:0}html.theme--catppuccin-macchiato .control.is-loading::after{position:absolute !important;right:.625em;top:0.625em;z-index:4}html.theme--catppuccin-macchiato .control.is-loading.is-small:after,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-loading:after{font-size:.75rem}html.theme--catppuccin-macchiato .control.is-loading.is-medium:after{font-size:1.25rem}html.theme--catppuccin-macchiato .control.is-loading.is-large:after{font-size:1.5rem}html.theme--catppuccin-macchiato .breadcrumb{font-size:1rem;white-space:nowrap}html.theme--catppuccin-macchiato .breadcrumb a{align-items:center;color:#8aadf4;display:flex;justify-content:center;padding:0 .75em}html.theme--catppuccin-macchiato .breadcrumb a:hover{color:#91d7e3}html.theme--catppuccin-macchiato .breadcrumb li{align-items:center;display:flex}html.theme--catppuccin-macchiato .breadcrumb li:first-child a{padding-left:0}html.theme--catppuccin-macchiato .breadcrumb li.is-active a{color:#b5c1f1;cursor:default;pointer-events:none}html.theme--catppuccin-macchiato .breadcrumb li+li::before{color:#6e738d;content:"\0002f"}html.theme--catppuccin-macchiato .breadcrumb ul,html.theme--catppuccin-macchiato .breadcrumb ol{align-items:flex-start;display:flex;flex-wrap:wrap;justify-content:flex-start}html.theme--catppuccin-macchiato .breadcrumb .icon:first-child{margin-right:.5em}html.theme--catppuccin-macchiato .breadcrumb .icon:last-child{margin-left:.5em}html.theme--catppuccin-macchiato .breadcrumb.is-centered ol,html.theme--catppuccin-macchiato .breadcrumb.is-centered ul{justify-content:center}html.theme--catppuccin-macchiato .breadcrumb.is-right ol,html.theme--catppuccin-macchiato .breadcrumb.is-right ul{justify-content:flex-end}html.theme--catppuccin-macchiato .breadcrumb.is-small,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.breadcrumb{font-size:.75rem}html.theme--catppuccin-macchiato .breadcrumb.is-medium{font-size:1.25rem}html.theme--catppuccin-macchiato .breadcrumb.is-large{font-size:1.5rem}html.theme--catppuccin-macchiato .breadcrumb.has-arrow-separator li+li::before{content:"\02192"}html.theme--catppuccin-macchiato .breadcrumb.has-bullet-separator li+li::before{content:"\02022"}html.theme--catppuccin-macchiato .breadcrumb.has-dot-separator li+li::before{content:"\000b7"}html.theme--catppuccin-macchiato .breadcrumb.has-succeeds-separator li+li::before{content:"\0227B"}html.theme--catppuccin-macchiato .card{background-color:#fff;border-radius:.25rem;box-shadow:#171717;color:#cad3f5;max-width:100%;position:relative}html.theme--catppuccin-macchiato .card-footer:first-child,html.theme--catppuccin-macchiato .card-content:first-child,html.theme--catppuccin-macchiato .card-header:first-child{border-top-left-radius:.25rem;border-top-right-radius:.25rem}html.theme--catppuccin-macchiato .card-footer:last-child,html.theme--catppuccin-macchiato .card-content:last-child,html.theme--catppuccin-macchiato .card-header:last-child{border-bottom-left-radius:.25rem;border-bottom-right-radius:.25rem}html.theme--catppuccin-macchiato .card-header{background-color:rgba(0,0,0,0);align-items:stretch;box-shadow:0 0.125em 0.25em rgba(10,10,10,0.1);display:flex}html.theme--catppuccin-macchiato .card-header-title{align-items:center;color:#b5c1f1;display:flex;flex-grow:1;font-weight:700;padding:0.75rem 1rem}html.theme--catppuccin-macchiato .card-header-title.is-centered{justify-content:center}html.theme--catppuccin-macchiato .card-header-icon{-moz-appearance:none;-webkit-appearance:none;appearance:none;background:none;border:none;color:currentColor;font-family:inherit;font-size:1em;margin:0;padding:0;align-items:center;cursor:pointer;display:flex;justify-content:center;padding:0.75rem 1rem}html.theme--catppuccin-macchiato .card-image{display:block;position:relative}html.theme--catppuccin-macchiato .card-image:first-child img{border-top-left-radius:.25rem;border-top-right-radius:.25rem}html.theme--catppuccin-macchiato .card-image:last-child img{border-bottom-left-radius:.25rem;border-bottom-right-radius:.25rem}html.theme--catppuccin-macchiato .card-content{background-color:rgba(0,0,0,0);padding:1.5rem}html.theme--catppuccin-macchiato .card-footer{background-color:rgba(0,0,0,0);border-top:1px solid #ededed;align-items:stretch;display:flex}html.theme--catppuccin-macchiato .card-footer-item{align-items:center;display:flex;flex-basis:0;flex-grow:1;flex-shrink:0;justify-content:center;padding:.75rem}html.theme--catppuccin-macchiato .card-footer-item:not(:last-child){border-right:1px solid #ededed}html.theme--catppuccin-macchiato .card .media:not(:last-child){margin-bottom:1.5rem}html.theme--catppuccin-macchiato .dropdown{display:inline-flex;position:relative;vertical-align:top}html.theme--catppuccin-macchiato .dropdown.is-active .dropdown-menu,html.theme--catppuccin-macchiato .dropdown.is-hoverable:hover .dropdown-menu{display:block}html.theme--catppuccin-macchiato .dropdown.is-right .dropdown-menu{left:auto;right:0}html.theme--catppuccin-macchiato .dropdown.is-up .dropdown-menu{bottom:100%;padding-bottom:4px;padding-top:initial;top:auto}html.theme--catppuccin-macchiato .dropdown-menu{display:none;left:0;min-width:12rem;padding-top:4px;position:absolute;top:100%;z-index:20}html.theme--catppuccin-macchiato .dropdown-content{background-color:#1e2030;border-radius:.4em;box-shadow:#171717;padding-bottom:.5rem;padding-top:.5rem}html.theme--catppuccin-macchiato .dropdown-item{color:#cad3f5;display:block;font-size:0.875rem;line-height:1.5;padding:0.375rem 1rem;position:relative}html.theme--catppuccin-macchiato a.dropdown-item,html.theme--catppuccin-macchiato button.dropdown-item{padding-right:3rem;text-align:inherit;white-space:nowrap;width:100%}html.theme--catppuccin-macchiato a.dropdown-item:hover,html.theme--catppuccin-macchiato button.dropdown-item:hover{background-color:#1e2030;color:#0a0a0a}html.theme--catppuccin-macchiato a.dropdown-item.is-active,html.theme--catppuccin-macchiato button.dropdown-item.is-active{background-color:#8aadf4;color:#fff}html.theme--catppuccin-macchiato .dropdown-divider{background-color:#ededed;border:none;display:block;height:1px;margin:0.5rem 0}html.theme--catppuccin-macchiato .level{align-items:center;justify-content:space-between}html.theme--catppuccin-macchiato .level code{border-radius:.4em}html.theme--catppuccin-macchiato .level img{display:inline-block;vertical-align:top}html.theme--catppuccin-macchiato .level.is-mobile{display:flex}html.theme--catppuccin-macchiato .level.is-mobile .level-left,html.theme--catppuccin-macchiato .level.is-mobile .level-right{display:flex}html.theme--catppuccin-macchiato .level.is-mobile .level-left+.level-right{margin-top:0}html.theme--catppuccin-macchiato .level.is-mobile .level-item:not(:last-child){margin-bottom:0;margin-right:.75rem}html.theme--catppuccin-macchiato .level.is-mobile .level-item:not(.is-narrow){flex-grow:1}@media screen and (min-width: 769px),print{html.theme--catppuccin-macchiato .level{display:flex}html.theme--catppuccin-macchiato .level>.level-item:not(.is-narrow){flex-grow:1}}html.theme--catppuccin-macchiato .level-item{align-items:center;display:flex;flex-basis:auto;flex-grow:0;flex-shrink:0;justify-content:center}html.theme--catppuccin-macchiato .level-item .title,html.theme--catppuccin-macchiato .level-item .subtitle{margin-bottom:0}@media screen and (max-width: 768px){html.theme--catppuccin-macchiato .level-item:not(:last-child){margin-bottom:.75rem}}html.theme--catppuccin-macchiato .level-left,html.theme--catppuccin-macchiato .level-right{flex-basis:auto;flex-grow:0;flex-shrink:0}html.theme--catppuccin-macchiato .level-left .level-item.is-flexible,html.theme--catppuccin-macchiato .level-right .level-item.is-flexible{flex-grow:1}@media screen and (min-width: 769px),print{html.theme--catppuccin-macchiato .level-left .level-item:not(:last-child),html.theme--catppuccin-macchiato .level-right .level-item:not(:last-child){margin-right:.75rem}}html.theme--catppuccin-macchiato .level-left{align-items:center;justify-content:flex-start}@media screen and (max-width: 768px){html.theme--catppuccin-macchiato .level-left+.level-right{margin-top:1.5rem}}@media screen and (min-width: 769px),print{html.theme--catppuccin-macchiato .level-left{display:flex}}html.theme--catppuccin-macchiato .level-right{align-items:center;justify-content:flex-end}@media screen and (min-width: 769px),print{html.theme--catppuccin-macchiato .level-right{display:flex}}html.theme--catppuccin-macchiato .media{align-items:flex-start;display:flex;text-align:inherit}html.theme--catppuccin-macchiato .media .content:not(:last-child){margin-bottom:.75rem}html.theme--catppuccin-macchiato .media .media{border-top:1px solid rgba(91,96,120,0.5);display:flex;padding-top:.75rem}html.theme--catppuccin-macchiato .media .media .content:not(:last-child),html.theme--catppuccin-macchiato .media .media .control:not(:last-child){margin-bottom:.5rem}html.theme--catppuccin-macchiato .media .media .media{padding-top:.5rem}html.theme--catppuccin-macchiato .media .media .media+.media{margin-top:.5rem}html.theme--catppuccin-macchiato .media+.media{border-top:1px solid rgba(91,96,120,0.5);margin-top:1rem;padding-top:1rem}html.theme--catppuccin-macchiato .media.is-large+.media{margin-top:1.5rem;padding-top:1.5rem}html.theme--catppuccin-macchiato .media-left,html.theme--catppuccin-macchiato .media-right{flex-basis:auto;flex-grow:0;flex-shrink:0}html.theme--catppuccin-macchiato .media-left{margin-right:1rem}html.theme--catppuccin-macchiato .media-right{margin-left:1rem}html.theme--catppuccin-macchiato .media-content{flex-basis:auto;flex-grow:1;flex-shrink:1;text-align:inherit}@media screen and (max-width: 768px){html.theme--catppuccin-macchiato .media-content{overflow-x:auto}}html.theme--catppuccin-macchiato .menu{font-size:1rem}html.theme--catppuccin-macchiato .menu.is-small,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.menu{font-size:.75rem}html.theme--catppuccin-macchiato .menu.is-medium{font-size:1.25rem}html.theme--catppuccin-macchiato .menu.is-large{font-size:1.5rem}html.theme--catppuccin-macchiato .menu-list{line-height:1.25}html.theme--catppuccin-macchiato .menu-list a{border-radius:3px;color:#cad3f5;display:block;padding:0.5em 0.75em}html.theme--catppuccin-macchiato .menu-list a:hover{background-color:#1e2030;color:#b5c1f1}html.theme--catppuccin-macchiato .menu-list a.is-active{background-color:#8aadf4;color:#fff}html.theme--catppuccin-macchiato .menu-list li ul{border-left:1px solid #5b6078;margin:.75em;padding-left:.75em}html.theme--catppuccin-macchiato .menu-label{color:#f5f7fd;font-size:.75em;letter-spacing:.1em;text-transform:uppercase}html.theme--catppuccin-macchiato .menu-label:not(:first-child){margin-top:1em}html.theme--catppuccin-macchiato .menu-label:not(:last-child){margin-bottom:1em}html.theme--catppuccin-macchiato .message{background-color:#1e2030;border-radius:.4em;font-size:1rem}html.theme--catppuccin-macchiato .message strong{color:currentColor}html.theme--catppuccin-macchiato .message a:not(.button):not(.tag):not(.dropdown-item){color:currentColor;text-decoration:underline}html.theme--catppuccin-macchiato .message.is-small,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.message{font-size:.75rem}html.theme--catppuccin-macchiato .message.is-medium{font-size:1.25rem}html.theme--catppuccin-macchiato .message.is-large{font-size:1.5rem}html.theme--catppuccin-macchiato .message.is-white{background-color:#fff}html.theme--catppuccin-macchiato .message.is-white .message-header{background-color:#fff;color:#0a0a0a}html.theme--catppuccin-macchiato .message.is-white .message-body{border-color:#fff}html.theme--catppuccin-macchiato .message.is-black{background-color:#fafafa}html.theme--catppuccin-macchiato .message.is-black .message-header{background-color:#0a0a0a;color:#fff}html.theme--catppuccin-macchiato .message.is-black .message-body{border-color:#0a0a0a}html.theme--catppuccin-macchiato .message.is-light{background-color:#fafafa}html.theme--catppuccin-macchiato .message.is-light .message-header{background-color:#f5f5f5;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .message.is-light .message-body{border-color:#f5f5f5}html.theme--catppuccin-macchiato .message.is-dark,html.theme--catppuccin-macchiato .content kbd.message{background-color:#f9f9fb}html.theme--catppuccin-macchiato .message.is-dark .message-header,html.theme--catppuccin-macchiato .content kbd.message .message-header{background-color:#363a4f;color:#fff}html.theme--catppuccin-macchiato .message.is-dark .message-body,html.theme--catppuccin-macchiato .content kbd.message .message-body{border-color:#363a4f}html.theme--catppuccin-macchiato .message.is-primary,html.theme--catppuccin-macchiato .docstring>section>a.message.docs-sourcelink{background-color:#ecf2fd}html.theme--catppuccin-macchiato .message.is-primary .message-header,html.theme--catppuccin-macchiato .docstring>section>a.message.docs-sourcelink .message-header{background-color:#8aadf4;color:#fff}html.theme--catppuccin-macchiato .message.is-primary .message-body,html.theme--catppuccin-macchiato .docstring>section>a.message.docs-sourcelink .message-body{border-color:#8aadf4;color:#0e3b95}html.theme--catppuccin-macchiato .message.is-link{background-color:#ecf2fd}html.theme--catppuccin-macchiato .message.is-link .message-header{background-color:#8aadf4;color:#fff}html.theme--catppuccin-macchiato .message.is-link .message-body{border-color:#8aadf4;color:#0e3b95}html.theme--catppuccin-macchiato .message.is-info{background-color:#f0faf8}html.theme--catppuccin-macchiato .message.is-info .message-header{background-color:#8bd5ca;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .message.is-info .message-body{border-color:#8bd5ca;color:#276d62}html.theme--catppuccin-macchiato .message.is-success{background-color:#f2faf0}html.theme--catppuccin-macchiato .message.is-success .message-header{background-color:#a6da95;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .message.is-success .message-body{border-color:#a6da95;color:#386e26}html.theme--catppuccin-macchiato .message.is-warning{background-color:#fcf7ee}html.theme--catppuccin-macchiato .message.is-warning .message-header{background-color:#eed49f;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .message.is-warning .message-body{border-color:#eed49f;color:#7e5c16}html.theme--catppuccin-macchiato .message.is-danger{background-color:#fcedef}html.theme--catppuccin-macchiato .message.is-danger .message-header{background-color:#ed8796;color:#fff}html.theme--catppuccin-macchiato .message.is-danger .message-body{border-color:#ed8796;color:#971729}html.theme--catppuccin-macchiato .message-header{align-items:center;background-color:#cad3f5;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--catppuccin-macchiato .message-header .delete{flex-grow:0;flex-shrink:0;margin-left:.75em}html.theme--catppuccin-macchiato .message-header+.message-body{border-width:0;border-top-left-radius:0;border-top-right-radius:0}html.theme--catppuccin-macchiato .message-body{border-color:#5b6078;border-radius:.4em;border-style:solid;border-width:0 0 0 4px;color:#cad3f5;padding:1.25em 1.5em}html.theme--catppuccin-macchiato .message-body code,html.theme--catppuccin-macchiato .message-body pre{background-color:#fff}html.theme--catppuccin-macchiato .message-body pre code{background-color:rgba(0,0,0,0)}html.theme--catppuccin-macchiato .modal{align-items:center;display:none;flex-direction:column;justify-content:center;overflow:hidden;position:fixed;z-index:40}html.theme--catppuccin-macchiato .modal.is-active{display:flex}html.theme--catppuccin-macchiato .modal-background{background-color:rgba(10,10,10,0.86)}html.theme--catppuccin-macchiato .modal-content,html.theme--catppuccin-macchiato .modal-card{margin:0 20px;max-height:calc(100vh - 160px);overflow:auto;position:relative;width:100%}@media screen and (min-width: 769px){html.theme--catppuccin-macchiato .modal-content,html.theme--catppuccin-macchiato .modal-card{margin:0 auto;max-height:calc(100vh - 40px);width:640px}}html.theme--catppuccin-macchiato .modal-close{background:none;height:40px;position:fixed;right:20px;top:20px;width:40px}html.theme--catppuccin-macchiato .modal-card{display:flex;flex-direction:column;max-height:calc(100vh - 40px);overflow:hidden;-ms-overflow-y:visible}html.theme--catppuccin-macchiato .modal-card-head,html.theme--catppuccin-macchiato .modal-card-foot{align-items:center;background-color:#1e2030;display:flex;flex-shrink:0;justify-content:flex-start;padding:20px;position:relative}html.theme--catppuccin-macchiato .modal-card-head{border-bottom:1px solid #5b6078;border-top-left-radius:8px;border-top-right-radius:8px}html.theme--catppuccin-macchiato .modal-card-title{color:#cad3f5;flex-grow:1;flex-shrink:0;font-size:1.5rem;line-height:1}html.theme--catppuccin-macchiato .modal-card-foot{border-bottom-left-radius:8px;border-bottom-right-radius:8px;border-top:1px solid #5b6078}html.theme--catppuccin-macchiato .modal-card-foot .button:not(:last-child){margin-right:.5em}html.theme--catppuccin-macchiato .modal-card-body{-webkit-overflow-scrolling:touch;background-color:#24273a;flex-grow:1;flex-shrink:1;overflow:auto;padding:20px}html.theme--catppuccin-macchiato .navbar{background-color:#8aadf4;min-height:4rem;position:relative;z-index:30}html.theme--catppuccin-macchiato .navbar.is-white{background-color:#fff;color:#0a0a0a}html.theme--catppuccin-macchiato .navbar.is-white .navbar-brand>.navbar-item,html.theme--catppuccin-macchiato .navbar.is-white .navbar-brand .navbar-link{color:#0a0a0a}html.theme--catppuccin-macchiato .navbar.is-white .navbar-brand>a.navbar-item:focus,html.theme--catppuccin-macchiato .navbar.is-white .navbar-brand>a.navbar-item:hover,html.theme--catppuccin-macchiato .navbar.is-white .navbar-brand>a.navbar-item.is-active,html.theme--catppuccin-macchiato .navbar.is-white .navbar-brand .navbar-link:focus,html.theme--catppuccin-macchiato .navbar.is-white .navbar-brand .navbar-link:hover,html.theme--catppuccin-macchiato .navbar.is-white .navbar-brand .navbar-link.is-active{background-color:#f2f2f2;color:#0a0a0a}html.theme--catppuccin-macchiato .navbar.is-white .navbar-brand .navbar-link::after{border-color:#0a0a0a}html.theme--catppuccin-macchiato .navbar.is-white .navbar-burger{color:#0a0a0a}@media screen and (min-width: 1056px){html.theme--catppuccin-macchiato .navbar.is-white .navbar-start>.navbar-item,html.theme--catppuccin-macchiato .navbar.is-white .navbar-start .navbar-link,html.theme--catppuccin-macchiato .navbar.is-white .navbar-end>.navbar-item,html.theme--catppuccin-macchiato .navbar.is-white .navbar-end .navbar-link{color:#0a0a0a}html.theme--catppuccin-macchiato .navbar.is-white .navbar-start>a.navbar-item:focus,html.theme--catppuccin-macchiato .navbar.is-white .navbar-start>a.navbar-item:hover,html.theme--catppuccin-macchiato .navbar.is-white .navbar-start>a.navbar-item.is-active,html.theme--catppuccin-macchiato .navbar.is-white .navbar-start .navbar-link:focus,html.theme--catppuccin-macchiato .navbar.is-white .navbar-start .navbar-link:hover,html.theme--catppuccin-macchiato .navbar.is-white .navbar-start .navbar-link.is-active,html.theme--catppuccin-macchiato .navbar.is-white .navbar-end>a.navbar-item:focus,html.theme--catppuccin-macchiato .navbar.is-white .navbar-end>a.navbar-item:hover,html.theme--catppuccin-macchiato .navbar.is-white .navbar-end>a.navbar-item.is-active,html.theme--catppuccin-macchiato .navbar.is-white .navbar-end .navbar-link:focus,html.theme--catppuccin-macchiato .navbar.is-white .navbar-end .navbar-link:hover,html.theme--catppuccin-macchiato .navbar.is-white .navbar-end .navbar-link.is-active{background-color:#f2f2f2;color:#0a0a0a}html.theme--catppuccin-macchiato .navbar.is-white .navbar-start .navbar-link::after,html.theme--catppuccin-macchiato .navbar.is-white .navbar-end .navbar-link::after{border-color:#0a0a0a}html.theme--catppuccin-macchiato .navbar.is-white .navbar-item.has-dropdown:focus .navbar-link,html.theme--catppuccin-macchiato .navbar.is-white .navbar-item.has-dropdown:hover .navbar-link,html.theme--catppuccin-macchiato .navbar.is-white .navbar-item.has-dropdown.is-active .navbar-link{background-color:#f2f2f2;color:#0a0a0a}html.theme--catppuccin-macchiato .navbar.is-white .navbar-dropdown a.navbar-item.is-active{background-color:#fff;color:#0a0a0a}}html.theme--catppuccin-macchiato .navbar.is-black{background-color:#0a0a0a;color:#fff}html.theme--catppuccin-macchiato .navbar.is-black .navbar-brand>.navbar-item,html.theme--catppuccin-macchiato .navbar.is-black .navbar-brand .navbar-link{color:#fff}html.theme--catppuccin-macchiato .navbar.is-black .navbar-brand>a.navbar-item:focus,html.theme--catppuccin-macchiato .navbar.is-black .navbar-brand>a.navbar-item:hover,html.theme--catppuccin-macchiato .navbar.is-black .navbar-brand>a.navbar-item.is-active,html.theme--catppuccin-macchiato .navbar.is-black .navbar-brand .navbar-link:focus,html.theme--catppuccin-macchiato .navbar.is-black .navbar-brand .navbar-link:hover,html.theme--catppuccin-macchiato .navbar.is-black .navbar-brand .navbar-link.is-active{background-color:#000;color:#fff}html.theme--catppuccin-macchiato .navbar.is-black .navbar-brand .navbar-link::after{border-color:#fff}html.theme--catppuccin-macchiato .navbar.is-black .navbar-burger{color:#fff}@media screen and (min-width: 1056px){html.theme--catppuccin-macchiato .navbar.is-black .navbar-start>.navbar-item,html.theme--catppuccin-macchiato .navbar.is-black .navbar-start .navbar-link,html.theme--catppuccin-macchiato .navbar.is-black .navbar-end>.navbar-item,html.theme--catppuccin-macchiato .navbar.is-black .navbar-end .navbar-link{color:#fff}html.theme--catppuccin-macchiato .navbar.is-black .navbar-start>a.navbar-item:focus,html.theme--catppuccin-macchiato .navbar.is-black .navbar-start>a.navbar-item:hover,html.theme--catppuccin-macchiato .navbar.is-black .navbar-start>a.navbar-item.is-active,html.theme--catppuccin-macchiato .navbar.is-black .navbar-start .navbar-link:focus,html.theme--catppuccin-macchiato .navbar.is-black .navbar-start .navbar-link:hover,html.theme--catppuccin-macchiato .navbar.is-black .navbar-start .navbar-link.is-active,html.theme--catppuccin-macchiato .navbar.is-black .navbar-end>a.navbar-item:focus,html.theme--catppuccin-macchiato .navbar.is-black .navbar-end>a.navbar-item:hover,html.theme--catppuccin-macchiato .navbar.is-black .navbar-end>a.navbar-item.is-active,html.theme--catppuccin-macchiato .navbar.is-black .navbar-end .navbar-link:focus,html.theme--catppuccin-macchiato .navbar.is-black .navbar-end .navbar-link:hover,html.theme--catppuccin-macchiato .navbar.is-black .navbar-end .navbar-link.is-active{background-color:#000;color:#fff}html.theme--catppuccin-macchiato .navbar.is-black .navbar-start .navbar-link::after,html.theme--catppuccin-macchiato .navbar.is-black .navbar-end .navbar-link::after{border-color:#fff}html.theme--catppuccin-macchiato .navbar.is-black .navbar-item.has-dropdown:focus .navbar-link,html.theme--catppuccin-macchiato .navbar.is-black .navbar-item.has-dropdown:hover .navbar-link,html.theme--catppuccin-macchiato .navbar.is-black .navbar-item.has-dropdown.is-active .navbar-link{background-color:#000;color:#fff}html.theme--catppuccin-macchiato .navbar.is-black .navbar-dropdown a.navbar-item.is-active{background-color:#0a0a0a;color:#fff}}html.theme--catppuccin-macchiato .navbar.is-light{background-color:#f5f5f5;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .navbar.is-light .navbar-brand>.navbar-item,html.theme--catppuccin-macchiato .navbar.is-light .navbar-brand .navbar-link{color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .navbar.is-light .navbar-brand>a.navbar-item:focus,html.theme--catppuccin-macchiato .navbar.is-light .navbar-brand>a.navbar-item:hover,html.theme--catppuccin-macchiato .navbar.is-light .navbar-brand>a.navbar-item.is-active,html.theme--catppuccin-macchiato .navbar.is-light .navbar-brand .navbar-link:focus,html.theme--catppuccin-macchiato .navbar.is-light .navbar-brand .navbar-link:hover,html.theme--catppuccin-macchiato .navbar.is-light .navbar-brand .navbar-link.is-active{background-color:#e8e8e8;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .navbar.is-light .navbar-brand .navbar-link::after{border-color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .navbar.is-light .navbar-burger{color:rgba(0,0,0,0.7)}@media screen and (min-width: 1056px){html.theme--catppuccin-macchiato .navbar.is-light .navbar-start>.navbar-item,html.theme--catppuccin-macchiato .navbar.is-light .navbar-start .navbar-link,html.theme--catppuccin-macchiato .navbar.is-light .navbar-end>.navbar-item,html.theme--catppuccin-macchiato .navbar.is-light .navbar-end .navbar-link{color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .navbar.is-light .navbar-start>a.navbar-item:focus,html.theme--catppuccin-macchiato .navbar.is-light .navbar-start>a.navbar-item:hover,html.theme--catppuccin-macchiato .navbar.is-light .navbar-start>a.navbar-item.is-active,html.theme--catppuccin-macchiato .navbar.is-light .navbar-start .navbar-link:focus,html.theme--catppuccin-macchiato .navbar.is-light .navbar-start .navbar-link:hover,html.theme--catppuccin-macchiato .navbar.is-light .navbar-start .navbar-link.is-active,html.theme--catppuccin-macchiato .navbar.is-light .navbar-end>a.navbar-item:focus,html.theme--catppuccin-macchiato .navbar.is-light .navbar-end>a.navbar-item:hover,html.theme--catppuccin-macchiato .navbar.is-light .navbar-end>a.navbar-item.is-active,html.theme--catppuccin-macchiato .navbar.is-light .navbar-end .navbar-link:focus,html.theme--catppuccin-macchiato .navbar.is-light .navbar-end .navbar-link:hover,html.theme--catppuccin-macchiato .navbar.is-light .navbar-end .navbar-link.is-active{background-color:#e8e8e8;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .navbar.is-light .navbar-start .navbar-link::after,html.theme--catppuccin-macchiato .navbar.is-light .navbar-end .navbar-link::after{border-color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .navbar.is-light .navbar-item.has-dropdown:focus .navbar-link,html.theme--catppuccin-macchiato .navbar.is-light .navbar-item.has-dropdown:hover .navbar-link,html.theme--catppuccin-macchiato .navbar.is-light .navbar-item.has-dropdown.is-active .navbar-link{background-color:#e8e8e8;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .navbar.is-light .navbar-dropdown a.navbar-item.is-active{background-color:#f5f5f5;color:rgba(0,0,0,0.7)}}html.theme--catppuccin-macchiato .navbar.is-dark,html.theme--catppuccin-macchiato .content kbd.navbar{background-color:#363a4f;color:#fff}html.theme--catppuccin-macchiato .navbar.is-dark .navbar-brand>.navbar-item,html.theme--catppuccin-macchiato .content kbd.navbar .navbar-brand>.navbar-item,html.theme--catppuccin-macchiato .navbar.is-dark .navbar-brand .navbar-link,html.theme--catppuccin-macchiato .content kbd.navbar .navbar-brand .navbar-link{color:#fff}html.theme--catppuccin-macchiato .navbar.is-dark .navbar-brand>a.navbar-item:focus,html.theme--catppuccin-macchiato .content kbd.navbar .navbar-brand>a.navbar-item:focus,html.theme--catppuccin-macchiato .navbar.is-dark .navbar-brand>a.navbar-item:hover,html.theme--catppuccin-macchiato .content kbd.navbar .navbar-brand>a.navbar-item:hover,html.theme--catppuccin-macchiato .navbar.is-dark .navbar-brand>a.navbar-item.is-active,html.theme--catppuccin-macchiato .content kbd.navbar .navbar-brand>a.navbar-item.is-active,html.theme--catppuccin-macchiato .navbar.is-dark .navbar-brand .navbar-link:focus,html.theme--catppuccin-macchiato .content kbd.navbar .navbar-brand .navbar-link:focus,html.theme--catppuccin-macchiato .navbar.is-dark .navbar-brand .navbar-link:hover,html.theme--catppuccin-macchiato .content kbd.navbar .navbar-brand .navbar-link:hover,html.theme--catppuccin-macchiato .navbar.is-dark .navbar-brand .navbar-link.is-active,html.theme--catppuccin-macchiato .content kbd.navbar .navbar-brand .navbar-link.is-active{background-color:#2c2f40;color:#fff}html.theme--catppuccin-macchiato .navbar.is-dark .navbar-brand .navbar-link::after,html.theme--catppuccin-macchiato .content kbd.navbar .navbar-brand .navbar-link::after{border-color:#fff}html.theme--catppuccin-macchiato .navbar.is-dark .navbar-burger,html.theme--catppuccin-macchiato .content kbd.navbar .navbar-burger{color:#fff}@media screen and (min-width: 1056px){html.theme--catppuccin-macchiato .navbar.is-dark .navbar-start>.navbar-item,html.theme--catppuccin-macchiato .content kbd.navbar .navbar-start>.navbar-item,html.theme--catppuccin-macchiato .navbar.is-dark .navbar-start .navbar-link,html.theme--catppuccin-macchiato .content kbd.navbar .navbar-start .navbar-link,html.theme--catppuccin-macchiato .navbar.is-dark .navbar-end>.navbar-item,html.theme--catppuccin-macchiato .content kbd.navbar .navbar-end>.navbar-item,html.theme--catppuccin-macchiato .navbar.is-dark .navbar-end .navbar-link,html.theme--catppuccin-macchiato .content kbd.navbar .navbar-end .navbar-link{color:#fff}html.theme--catppuccin-macchiato .navbar.is-dark .navbar-start>a.navbar-item:focus,html.theme--catppuccin-macchiato .content kbd.navbar .navbar-start>a.navbar-item:focus,html.theme--catppuccin-macchiato .navbar.is-dark .navbar-start>a.navbar-item:hover,html.theme--catppuccin-macchiato .content kbd.navbar .navbar-start>a.navbar-item:hover,html.theme--catppuccin-macchiato .navbar.is-dark .navbar-start>a.navbar-item.is-active,html.theme--catppuccin-macchiato .content kbd.navbar .navbar-start>a.navbar-item.is-active,html.theme--catppuccin-macchiato .navbar.is-dark .navbar-start .navbar-link:focus,html.theme--catppuccin-macchiato .content kbd.navbar .navbar-start .navbar-link:focus,html.theme--catppuccin-macchiato .navbar.is-dark .navbar-start .navbar-link:hover,html.theme--catppuccin-macchiato .content kbd.navbar .navbar-start .navbar-link:hover,html.theme--catppuccin-macchiato .navbar.is-dark .navbar-start .navbar-link.is-active,html.theme--catppuccin-macchiato .content kbd.navbar .navbar-start .navbar-link.is-active,html.theme--catppuccin-macchiato .navbar.is-dark .navbar-end>a.navbar-item:focus,html.theme--catppuccin-macchiato .content kbd.navbar .navbar-end>a.navbar-item:focus,html.theme--catppuccin-macchiato .navbar.is-dark .navbar-end>a.navbar-item:hover,html.theme--catppuccin-macchiato .content kbd.navbar .navbar-end>a.navbar-item:hover,html.theme--catppuccin-macchiato .navbar.is-dark .navbar-end>a.navbar-item.is-active,html.theme--catppuccin-macchiato .content kbd.navbar .navbar-end>a.navbar-item.is-active,html.theme--catppuccin-macchiato .navbar.is-dark .navbar-end .navbar-link:focus,html.theme--catppuccin-macchiato .content kbd.navbar .navbar-end .navbar-link:focus,html.theme--catppuccin-macchiato .navbar.is-dark .navbar-end .navbar-link:hover,html.theme--catppuccin-macchiato .content kbd.navbar .navbar-end .navbar-link:hover,html.theme--catppuccin-macchiato .navbar.is-dark .navbar-end .navbar-link.is-active,html.theme--catppuccin-macchiato .content kbd.navbar .navbar-end .navbar-link.is-active{background-color:#2c2f40;color:#fff}html.theme--catppuccin-macchiato .navbar.is-dark .navbar-start .navbar-link::after,html.theme--catppuccin-macchiato .content kbd.navbar .navbar-start .navbar-link::after,html.theme--catppuccin-macchiato .navbar.is-dark .navbar-end .navbar-link::after,html.theme--catppuccin-macchiato .content kbd.navbar .navbar-end .navbar-link::after{border-color:#fff}html.theme--catppuccin-macchiato .navbar.is-dark .navbar-item.has-dropdown:focus .navbar-link,html.theme--catppuccin-macchiato .content kbd.navbar .navbar-item.has-dropdown:focus .navbar-link,html.theme--catppuccin-macchiato .navbar.is-dark .navbar-item.has-dropdown:hover .navbar-link,html.theme--catppuccin-macchiato .content kbd.navbar .navbar-item.has-dropdown:hover .navbar-link,html.theme--catppuccin-macchiato .navbar.is-dark .navbar-item.has-dropdown.is-active .navbar-link,html.theme--catppuccin-macchiato .content kbd.navbar .navbar-item.has-dropdown.is-active .navbar-link{background-color:#2c2f40;color:#fff}html.theme--catppuccin-macchiato .navbar.is-dark .navbar-dropdown a.navbar-item.is-active,html.theme--catppuccin-macchiato .content kbd.navbar .navbar-dropdown a.navbar-item.is-active{background-color:#363a4f;color:#fff}}html.theme--catppuccin-macchiato .navbar.is-primary,html.theme--catppuccin-macchiato .docstring>section>a.navbar.docs-sourcelink{background-color:#8aadf4;color:#fff}html.theme--catppuccin-macchiato .navbar.is-primary .navbar-brand>.navbar-item,html.theme--catppuccin-macchiato .docstring>section>a.navbar.docs-sourcelink .navbar-brand>.navbar-item,html.theme--catppuccin-macchiato .navbar.is-primary .navbar-brand .navbar-link,html.theme--catppuccin-macchiato .docstring>section>a.navbar.docs-sourcelink .navbar-brand .navbar-link{color:#fff}html.theme--catppuccin-macchiato .navbar.is-primary .navbar-brand>a.navbar-item:focus,html.theme--catppuccin-macchiato .docstring>section>a.navbar.docs-sourcelink .navbar-brand>a.navbar-item:focus,html.theme--catppuccin-macchiato .navbar.is-primary .navbar-brand>a.navbar-item:hover,html.theme--catppuccin-macchiato .docstring>section>a.navbar.docs-sourcelink .navbar-brand>a.navbar-item:hover,html.theme--catppuccin-macchiato .navbar.is-primary .navbar-brand>a.navbar-item.is-active,html.theme--catppuccin-macchiato .docstring>section>a.navbar.docs-sourcelink .navbar-brand>a.navbar-item.is-active,html.theme--catppuccin-macchiato .navbar.is-primary .navbar-brand .navbar-link:focus,html.theme--catppuccin-macchiato .docstring>section>a.navbar.docs-sourcelink .navbar-brand .navbar-link:focus,html.theme--catppuccin-macchiato .navbar.is-primary .navbar-brand .navbar-link:hover,html.theme--catppuccin-macchiato .docstring>section>a.navbar.docs-sourcelink .navbar-brand .navbar-link:hover,html.theme--catppuccin-macchiato .navbar.is-primary .navbar-brand .navbar-link.is-active,html.theme--catppuccin-macchiato .docstring>section>a.navbar.docs-sourcelink .navbar-brand .navbar-link.is-active{background-color:#739df2;color:#fff}html.theme--catppuccin-macchiato .navbar.is-primary .navbar-brand .navbar-link::after,html.theme--catppuccin-macchiato .docstring>section>a.navbar.docs-sourcelink .navbar-brand .navbar-link::after{border-color:#fff}html.theme--catppuccin-macchiato .navbar.is-primary .navbar-burger,html.theme--catppuccin-macchiato .docstring>section>a.navbar.docs-sourcelink .navbar-burger{color:#fff}@media screen and (min-width: 1056px){html.theme--catppuccin-macchiato .navbar.is-primary .navbar-start>.navbar-item,html.theme--catppuccin-macchiato .docstring>section>a.navbar.docs-sourcelink .navbar-start>.navbar-item,html.theme--catppuccin-macchiato .navbar.is-primary .navbar-start .navbar-link,html.theme--catppuccin-macchiato .docstring>section>a.navbar.docs-sourcelink .navbar-start .navbar-link,html.theme--catppuccin-macchiato .navbar.is-primary .navbar-end>.navbar-item,html.theme--catppuccin-macchiato .docstring>section>a.navbar.docs-sourcelink .navbar-end>.navbar-item,html.theme--catppuccin-macchiato .navbar.is-primary .navbar-end .navbar-link,html.theme--catppuccin-macchiato .docstring>section>a.navbar.docs-sourcelink .navbar-end .navbar-link{color:#fff}html.theme--catppuccin-macchiato .navbar.is-primary .navbar-start>a.navbar-item:focus,html.theme--catppuccin-macchiato .docstring>section>a.navbar.docs-sourcelink .navbar-start>a.navbar-item:focus,html.theme--catppuccin-macchiato .navbar.is-primary .navbar-start>a.navbar-item:hover,html.theme--catppuccin-macchiato .docstring>section>a.navbar.docs-sourcelink .navbar-start>a.navbar-item:hover,html.theme--catppuccin-macchiato .navbar.is-primary .navbar-start>a.navbar-item.is-active,html.theme--catppuccin-macchiato .docstring>section>a.navbar.docs-sourcelink .navbar-start>a.navbar-item.is-active,html.theme--catppuccin-macchiato .navbar.is-primary .navbar-start .navbar-link:focus,html.theme--catppuccin-macchiato .docstring>section>a.navbar.docs-sourcelink .navbar-start .navbar-link:focus,html.theme--catppuccin-macchiato .navbar.is-primary .navbar-start .navbar-link:hover,html.theme--catppuccin-macchiato .docstring>section>a.navbar.docs-sourcelink .navbar-start .navbar-link:hover,html.theme--catppuccin-macchiato .navbar.is-primary .navbar-start .navbar-link.is-active,html.theme--catppuccin-macchiato .docstring>section>a.navbar.docs-sourcelink .navbar-start .navbar-link.is-active,html.theme--catppuccin-macchiato .navbar.is-primary .navbar-end>a.navbar-item:focus,html.theme--catppuccin-macchiato .docstring>section>a.navbar.docs-sourcelink .navbar-end>a.navbar-item:focus,html.theme--catppuccin-macchiato .navbar.is-primary .navbar-end>a.navbar-item:hover,html.theme--catppuccin-macchiato .docstring>section>a.navbar.docs-sourcelink .navbar-end>a.navbar-item:hover,html.theme--catppuccin-macchiato .navbar.is-primary .navbar-end>a.navbar-item.is-active,html.theme--catppuccin-macchiato .docstring>section>a.navbar.docs-sourcelink .navbar-end>a.navbar-item.is-active,html.theme--catppuccin-macchiato .navbar.is-primary .navbar-end .navbar-link:focus,html.theme--catppuccin-macchiato .docstring>section>a.navbar.docs-sourcelink .navbar-end .navbar-link:focus,html.theme--catppuccin-macchiato .navbar.is-primary .navbar-end .navbar-link:hover,html.theme--catppuccin-macchiato .docstring>section>a.navbar.docs-sourcelink .navbar-end .navbar-link:hover,html.theme--catppuccin-macchiato .navbar.is-primary .navbar-end .navbar-link.is-active,html.theme--catppuccin-macchiato .docstring>section>a.navbar.docs-sourcelink .navbar-end .navbar-link.is-active{background-color:#739df2;color:#fff}html.theme--catppuccin-macchiato .navbar.is-primary .navbar-start .navbar-link::after,html.theme--catppuccin-macchiato .docstring>section>a.navbar.docs-sourcelink .navbar-start .navbar-link::after,html.theme--catppuccin-macchiato .navbar.is-primary .navbar-end .navbar-link::after,html.theme--catppuccin-macchiato .docstring>section>a.navbar.docs-sourcelink .navbar-end .navbar-link::after{border-color:#fff}html.theme--catppuccin-macchiato .navbar.is-primary .navbar-item.has-dropdown:focus .navbar-link,html.theme--catppuccin-macchiato .docstring>section>a.navbar.docs-sourcelink .navbar-item.has-dropdown:focus .navbar-link,html.theme--catppuccin-macchiato .navbar.is-primary .navbar-item.has-dropdown:hover .navbar-link,html.theme--catppuccin-macchiato .docstring>section>a.navbar.docs-sourcelink .navbar-item.has-dropdown:hover .navbar-link,html.theme--catppuccin-macchiato .navbar.is-primary .navbar-item.has-dropdown.is-active .navbar-link,html.theme--catppuccin-macchiato .docstring>section>a.navbar.docs-sourcelink .navbar-item.has-dropdown.is-active .navbar-link{background-color:#739df2;color:#fff}html.theme--catppuccin-macchiato .navbar.is-primary .navbar-dropdown a.navbar-item.is-active,html.theme--catppuccin-macchiato .docstring>section>a.navbar.docs-sourcelink .navbar-dropdown a.navbar-item.is-active{background-color:#8aadf4;color:#fff}}html.theme--catppuccin-macchiato .navbar.is-link{background-color:#8aadf4;color:#fff}html.theme--catppuccin-macchiato .navbar.is-link .navbar-brand>.navbar-item,html.theme--catppuccin-macchiato .navbar.is-link .navbar-brand .navbar-link{color:#fff}html.theme--catppuccin-macchiato .navbar.is-link .navbar-brand>a.navbar-item:focus,html.theme--catppuccin-macchiato .navbar.is-link .navbar-brand>a.navbar-item:hover,html.theme--catppuccin-macchiato .navbar.is-link .navbar-brand>a.navbar-item.is-active,html.theme--catppuccin-macchiato .navbar.is-link .navbar-brand .navbar-link:focus,html.theme--catppuccin-macchiato .navbar.is-link .navbar-brand .navbar-link:hover,html.theme--catppuccin-macchiato .navbar.is-link .navbar-brand .navbar-link.is-active{background-color:#739df2;color:#fff}html.theme--catppuccin-macchiato .navbar.is-link .navbar-brand .navbar-link::after{border-color:#fff}html.theme--catppuccin-macchiato .navbar.is-link .navbar-burger{color:#fff}@media screen and (min-width: 1056px){html.theme--catppuccin-macchiato .navbar.is-link .navbar-start>.navbar-item,html.theme--catppuccin-macchiato .navbar.is-link .navbar-start .navbar-link,html.theme--catppuccin-macchiato .navbar.is-link .navbar-end>.navbar-item,html.theme--catppuccin-macchiato .navbar.is-link .navbar-end .navbar-link{color:#fff}html.theme--catppuccin-macchiato .navbar.is-link .navbar-start>a.navbar-item:focus,html.theme--catppuccin-macchiato .navbar.is-link .navbar-start>a.navbar-item:hover,html.theme--catppuccin-macchiato .navbar.is-link .navbar-start>a.navbar-item.is-active,html.theme--catppuccin-macchiato .navbar.is-link .navbar-start .navbar-link:focus,html.theme--catppuccin-macchiato .navbar.is-link .navbar-start .navbar-link:hover,html.theme--catppuccin-macchiato .navbar.is-link .navbar-start .navbar-link.is-active,html.theme--catppuccin-macchiato .navbar.is-link .navbar-end>a.navbar-item:focus,html.theme--catppuccin-macchiato .navbar.is-link .navbar-end>a.navbar-item:hover,html.theme--catppuccin-macchiato .navbar.is-link .navbar-end>a.navbar-item.is-active,html.theme--catppuccin-macchiato .navbar.is-link .navbar-end .navbar-link:focus,html.theme--catppuccin-macchiato .navbar.is-link .navbar-end .navbar-link:hover,html.theme--catppuccin-macchiato .navbar.is-link .navbar-end .navbar-link.is-active{background-color:#739df2;color:#fff}html.theme--catppuccin-macchiato .navbar.is-link .navbar-start .navbar-link::after,html.theme--catppuccin-macchiato .navbar.is-link .navbar-end .navbar-link::after{border-color:#fff}html.theme--catppuccin-macchiato .navbar.is-link .navbar-item.has-dropdown:focus .navbar-link,html.theme--catppuccin-macchiato .navbar.is-link .navbar-item.has-dropdown:hover .navbar-link,html.theme--catppuccin-macchiato .navbar.is-link .navbar-item.has-dropdown.is-active .navbar-link{background-color:#739df2;color:#fff}html.theme--catppuccin-macchiato .navbar.is-link .navbar-dropdown a.navbar-item.is-active{background-color:#8aadf4;color:#fff}}html.theme--catppuccin-macchiato .navbar.is-info{background-color:#8bd5ca;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .navbar.is-info .navbar-brand>.navbar-item,html.theme--catppuccin-macchiato .navbar.is-info .navbar-brand .navbar-link{color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .navbar.is-info .navbar-brand>a.navbar-item:focus,html.theme--catppuccin-macchiato .navbar.is-info .navbar-brand>a.navbar-item:hover,html.theme--catppuccin-macchiato .navbar.is-info .navbar-brand>a.navbar-item.is-active,html.theme--catppuccin-macchiato .navbar.is-info .navbar-brand .navbar-link:focus,html.theme--catppuccin-macchiato .navbar.is-info .navbar-brand .navbar-link:hover,html.theme--catppuccin-macchiato .navbar.is-info .navbar-brand .navbar-link.is-active{background-color:#78cec1;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .navbar.is-info .navbar-brand .navbar-link::after{border-color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .navbar.is-info .navbar-burger{color:rgba(0,0,0,0.7)}@media screen and (min-width: 1056px){html.theme--catppuccin-macchiato .navbar.is-info .navbar-start>.navbar-item,html.theme--catppuccin-macchiato .navbar.is-info .navbar-start .navbar-link,html.theme--catppuccin-macchiato .navbar.is-info .navbar-end>.navbar-item,html.theme--catppuccin-macchiato .navbar.is-info .navbar-end .navbar-link{color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .navbar.is-info .navbar-start>a.navbar-item:focus,html.theme--catppuccin-macchiato .navbar.is-info .navbar-start>a.navbar-item:hover,html.theme--catppuccin-macchiato .navbar.is-info .navbar-start>a.navbar-item.is-active,html.theme--catppuccin-macchiato .navbar.is-info .navbar-start .navbar-link:focus,html.theme--catppuccin-macchiato .navbar.is-info .navbar-start .navbar-link:hover,html.theme--catppuccin-macchiato .navbar.is-info .navbar-start .navbar-link.is-active,html.theme--catppuccin-macchiato .navbar.is-info .navbar-end>a.navbar-item:focus,html.theme--catppuccin-macchiato .navbar.is-info .navbar-end>a.navbar-item:hover,html.theme--catppuccin-macchiato .navbar.is-info .navbar-end>a.navbar-item.is-active,html.theme--catppuccin-macchiato .navbar.is-info .navbar-end .navbar-link:focus,html.theme--catppuccin-macchiato .navbar.is-info .navbar-end .navbar-link:hover,html.theme--catppuccin-macchiato .navbar.is-info .navbar-end .navbar-link.is-active{background-color:#78cec1;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .navbar.is-info .navbar-start .navbar-link::after,html.theme--catppuccin-macchiato .navbar.is-info .navbar-end .navbar-link::after{border-color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .navbar.is-info .navbar-item.has-dropdown:focus .navbar-link,html.theme--catppuccin-macchiato .navbar.is-info .navbar-item.has-dropdown:hover .navbar-link,html.theme--catppuccin-macchiato .navbar.is-info .navbar-item.has-dropdown.is-active .navbar-link{background-color:#78cec1;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .navbar.is-info .navbar-dropdown a.navbar-item.is-active{background-color:#8bd5ca;color:rgba(0,0,0,0.7)}}html.theme--catppuccin-macchiato .navbar.is-success{background-color:#a6da95;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .navbar.is-success .navbar-brand>.navbar-item,html.theme--catppuccin-macchiato .navbar.is-success .navbar-brand .navbar-link{color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .navbar.is-success .navbar-brand>a.navbar-item:focus,html.theme--catppuccin-macchiato .navbar.is-success .navbar-brand>a.navbar-item:hover,html.theme--catppuccin-macchiato .navbar.is-success .navbar-brand>a.navbar-item.is-active,html.theme--catppuccin-macchiato .navbar.is-success .navbar-brand .navbar-link:focus,html.theme--catppuccin-macchiato .navbar.is-success .navbar-brand .navbar-link:hover,html.theme--catppuccin-macchiato .navbar.is-success .navbar-brand .navbar-link.is-active{background-color:#96d382;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .navbar.is-success .navbar-brand .navbar-link::after{border-color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .navbar.is-success .navbar-burger{color:rgba(0,0,0,0.7)}@media screen and (min-width: 1056px){html.theme--catppuccin-macchiato .navbar.is-success .navbar-start>.navbar-item,html.theme--catppuccin-macchiato .navbar.is-success .navbar-start .navbar-link,html.theme--catppuccin-macchiato .navbar.is-success .navbar-end>.navbar-item,html.theme--catppuccin-macchiato .navbar.is-success .navbar-end .navbar-link{color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .navbar.is-success .navbar-start>a.navbar-item:focus,html.theme--catppuccin-macchiato .navbar.is-success .navbar-start>a.navbar-item:hover,html.theme--catppuccin-macchiato .navbar.is-success .navbar-start>a.navbar-item.is-active,html.theme--catppuccin-macchiato .navbar.is-success .navbar-start .navbar-link:focus,html.theme--catppuccin-macchiato .navbar.is-success .navbar-start .navbar-link:hover,html.theme--catppuccin-macchiato .navbar.is-success .navbar-start .navbar-link.is-active,html.theme--catppuccin-macchiato .navbar.is-success .navbar-end>a.navbar-item:focus,html.theme--catppuccin-macchiato .navbar.is-success .navbar-end>a.navbar-item:hover,html.theme--catppuccin-macchiato .navbar.is-success .navbar-end>a.navbar-item.is-active,html.theme--catppuccin-macchiato .navbar.is-success .navbar-end .navbar-link:focus,html.theme--catppuccin-macchiato .navbar.is-success .navbar-end .navbar-link:hover,html.theme--catppuccin-macchiato .navbar.is-success .navbar-end .navbar-link.is-active{background-color:#96d382;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .navbar.is-success .navbar-start .navbar-link::after,html.theme--catppuccin-macchiato .navbar.is-success .navbar-end .navbar-link::after{border-color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .navbar.is-success .navbar-item.has-dropdown:focus .navbar-link,html.theme--catppuccin-macchiato .navbar.is-success .navbar-item.has-dropdown:hover .navbar-link,html.theme--catppuccin-macchiato .navbar.is-success .navbar-item.has-dropdown.is-active .navbar-link{background-color:#96d382;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .navbar.is-success .navbar-dropdown a.navbar-item.is-active{background-color:#a6da95;color:rgba(0,0,0,0.7)}}html.theme--catppuccin-macchiato .navbar.is-warning{background-color:#eed49f;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .navbar.is-warning .navbar-brand>.navbar-item,html.theme--catppuccin-macchiato .navbar.is-warning .navbar-brand .navbar-link{color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .navbar.is-warning .navbar-brand>a.navbar-item:focus,html.theme--catppuccin-macchiato .navbar.is-warning .navbar-brand>a.navbar-item:hover,html.theme--catppuccin-macchiato .navbar.is-warning .navbar-brand>a.navbar-item.is-active,html.theme--catppuccin-macchiato .navbar.is-warning .navbar-brand .navbar-link:focus,html.theme--catppuccin-macchiato .navbar.is-warning .navbar-brand .navbar-link:hover,html.theme--catppuccin-macchiato .navbar.is-warning .navbar-brand .navbar-link.is-active{background-color:#eaca89;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .navbar.is-warning .navbar-brand .navbar-link::after{border-color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .navbar.is-warning .navbar-burger{color:rgba(0,0,0,0.7)}@media screen and (min-width: 1056px){html.theme--catppuccin-macchiato .navbar.is-warning .navbar-start>.navbar-item,html.theme--catppuccin-macchiato .navbar.is-warning .navbar-start .navbar-link,html.theme--catppuccin-macchiato .navbar.is-warning .navbar-end>.navbar-item,html.theme--catppuccin-macchiato .navbar.is-warning .navbar-end .navbar-link{color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .navbar.is-warning .navbar-start>a.navbar-item:focus,html.theme--catppuccin-macchiato .navbar.is-warning .navbar-start>a.navbar-item:hover,html.theme--catppuccin-macchiato .navbar.is-warning .navbar-start>a.navbar-item.is-active,html.theme--catppuccin-macchiato .navbar.is-warning .navbar-start .navbar-link:focus,html.theme--catppuccin-macchiato .navbar.is-warning .navbar-start .navbar-link:hover,html.theme--catppuccin-macchiato .navbar.is-warning .navbar-start .navbar-link.is-active,html.theme--catppuccin-macchiato .navbar.is-warning .navbar-end>a.navbar-item:focus,html.theme--catppuccin-macchiato .navbar.is-warning .navbar-end>a.navbar-item:hover,html.theme--catppuccin-macchiato .navbar.is-warning .navbar-end>a.navbar-item.is-active,html.theme--catppuccin-macchiato .navbar.is-warning .navbar-end .navbar-link:focus,html.theme--catppuccin-macchiato .navbar.is-warning .navbar-end .navbar-link:hover,html.theme--catppuccin-macchiato .navbar.is-warning .navbar-end .navbar-link.is-active{background-color:#eaca89;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .navbar.is-warning .navbar-start .navbar-link::after,html.theme--catppuccin-macchiato .navbar.is-warning .navbar-end .navbar-link::after{border-color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .navbar.is-warning .navbar-item.has-dropdown:focus .navbar-link,html.theme--catppuccin-macchiato .navbar.is-warning .navbar-item.has-dropdown:hover .navbar-link,html.theme--catppuccin-macchiato .navbar.is-warning .navbar-item.has-dropdown.is-active .navbar-link{background-color:#eaca89;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .navbar.is-warning .navbar-dropdown a.navbar-item.is-active{background-color:#eed49f;color:rgba(0,0,0,0.7)}}html.theme--catppuccin-macchiato .navbar.is-danger{background-color:#ed8796;color:#fff}html.theme--catppuccin-macchiato .navbar.is-danger .navbar-brand>.navbar-item,html.theme--catppuccin-macchiato .navbar.is-danger .navbar-brand .navbar-link{color:#fff}html.theme--catppuccin-macchiato .navbar.is-danger .navbar-brand>a.navbar-item:focus,html.theme--catppuccin-macchiato .navbar.is-danger .navbar-brand>a.navbar-item:hover,html.theme--catppuccin-macchiato .navbar.is-danger .navbar-brand>a.navbar-item.is-active,html.theme--catppuccin-macchiato .navbar.is-danger .navbar-brand .navbar-link:focus,html.theme--catppuccin-macchiato .navbar.is-danger .navbar-brand .navbar-link:hover,html.theme--catppuccin-macchiato .navbar.is-danger .navbar-brand .navbar-link.is-active{background-color:#ea7183;color:#fff}html.theme--catppuccin-macchiato .navbar.is-danger .navbar-brand .navbar-link::after{border-color:#fff}html.theme--catppuccin-macchiato .navbar.is-danger .navbar-burger{color:#fff}@media screen and (min-width: 1056px){html.theme--catppuccin-macchiato .navbar.is-danger .navbar-start>.navbar-item,html.theme--catppuccin-macchiato .navbar.is-danger .navbar-start .navbar-link,html.theme--catppuccin-macchiato .navbar.is-danger .navbar-end>.navbar-item,html.theme--catppuccin-macchiato .navbar.is-danger .navbar-end .navbar-link{color:#fff}html.theme--catppuccin-macchiato .navbar.is-danger .navbar-start>a.navbar-item:focus,html.theme--catppuccin-macchiato .navbar.is-danger .navbar-start>a.navbar-item:hover,html.theme--catppuccin-macchiato .navbar.is-danger .navbar-start>a.navbar-item.is-active,html.theme--catppuccin-macchiato .navbar.is-danger .navbar-start .navbar-link:focus,html.theme--catppuccin-macchiato .navbar.is-danger .navbar-start .navbar-link:hover,html.theme--catppuccin-macchiato .navbar.is-danger .navbar-start .navbar-link.is-active,html.theme--catppuccin-macchiato .navbar.is-danger .navbar-end>a.navbar-item:focus,html.theme--catppuccin-macchiato .navbar.is-danger .navbar-end>a.navbar-item:hover,html.theme--catppuccin-macchiato .navbar.is-danger .navbar-end>a.navbar-item.is-active,html.theme--catppuccin-macchiato .navbar.is-danger .navbar-end .navbar-link:focus,html.theme--catppuccin-macchiato .navbar.is-danger .navbar-end .navbar-link:hover,html.theme--catppuccin-macchiato .navbar.is-danger .navbar-end .navbar-link.is-active{background-color:#ea7183;color:#fff}html.theme--catppuccin-macchiato .navbar.is-danger .navbar-start .navbar-link::after,html.theme--catppuccin-macchiato .navbar.is-danger .navbar-end .navbar-link::after{border-color:#fff}html.theme--catppuccin-macchiato .navbar.is-danger .navbar-item.has-dropdown:focus .navbar-link,html.theme--catppuccin-macchiato .navbar.is-danger .navbar-item.has-dropdown:hover .navbar-link,html.theme--catppuccin-macchiato .navbar.is-danger .navbar-item.has-dropdown.is-active .navbar-link{background-color:#ea7183;color:#fff}html.theme--catppuccin-macchiato .navbar.is-danger .navbar-dropdown a.navbar-item.is-active{background-color:#ed8796;color:#fff}}html.theme--catppuccin-macchiato .navbar>.container{align-items:stretch;display:flex;min-height:4rem;width:100%}html.theme--catppuccin-macchiato .navbar.has-shadow{box-shadow:0 2px 0 0 #1e2030}html.theme--catppuccin-macchiato .navbar.is-fixed-bottom,html.theme--catppuccin-macchiato .navbar.is-fixed-top{left:0;position:fixed;right:0;z-index:30}html.theme--catppuccin-macchiato .navbar.is-fixed-bottom{bottom:0}html.theme--catppuccin-macchiato .navbar.is-fixed-bottom.has-shadow{box-shadow:0 -2px 0 0 #1e2030}html.theme--catppuccin-macchiato .navbar.is-fixed-top{top:0}html.theme--catppuccin-macchiato html.has-navbar-fixed-top,html.theme--catppuccin-macchiato body.has-navbar-fixed-top{padding-top:4rem}html.theme--catppuccin-macchiato html.has-navbar-fixed-bottom,html.theme--catppuccin-macchiato body.has-navbar-fixed-bottom{padding-bottom:4rem}html.theme--catppuccin-macchiato .navbar-brand,html.theme--catppuccin-macchiato .navbar-tabs{align-items:stretch;display:flex;flex-shrink:0;min-height:4rem}html.theme--catppuccin-macchiato .navbar-brand a.navbar-item:focus,html.theme--catppuccin-macchiato .navbar-brand a.navbar-item:hover{background-color:transparent}html.theme--catppuccin-macchiato .navbar-tabs{-webkit-overflow-scrolling:touch;max-width:100vw;overflow-x:auto;overflow-y:hidden}html.theme--catppuccin-macchiato .navbar-burger{color:#cad3f5;-moz-appearance:none;-webkit-appearance:none;appearance:none;background:none;border:none;cursor:pointer;display:block;height:4rem;position:relative;width:4rem;margin-left:auto}html.theme--catppuccin-macchiato .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--catppuccin-macchiato .navbar-burger span:nth-child(1){top:calc(50% - 6px)}html.theme--catppuccin-macchiato .navbar-burger span:nth-child(2){top:calc(50% - 1px)}html.theme--catppuccin-macchiato .navbar-burger span:nth-child(3){top:calc(50% + 4px)}html.theme--catppuccin-macchiato .navbar-burger:hover{background-color:rgba(0,0,0,0.05)}html.theme--catppuccin-macchiato .navbar-burger.is-active span:nth-child(1){transform:translateY(5px) rotate(45deg)}html.theme--catppuccin-macchiato .navbar-burger.is-active span:nth-child(2){opacity:0}html.theme--catppuccin-macchiato .navbar-burger.is-active span:nth-child(3){transform:translateY(-5px) rotate(-45deg)}html.theme--catppuccin-macchiato .navbar-menu{display:none}html.theme--catppuccin-macchiato .navbar-item,html.theme--catppuccin-macchiato .navbar-link{color:#cad3f5;display:block;line-height:1.5;padding:0.5rem 0.75rem;position:relative}html.theme--catppuccin-macchiato .navbar-item .icon:only-child,html.theme--catppuccin-macchiato .navbar-link .icon:only-child{margin-left:-0.25rem;margin-right:-0.25rem}html.theme--catppuccin-macchiato a.navbar-item,html.theme--catppuccin-macchiato .navbar-link{cursor:pointer}html.theme--catppuccin-macchiato a.navbar-item:focus,html.theme--catppuccin-macchiato a.navbar-item:focus-within,html.theme--catppuccin-macchiato a.navbar-item:hover,html.theme--catppuccin-macchiato a.navbar-item.is-active,html.theme--catppuccin-macchiato .navbar-link:focus,html.theme--catppuccin-macchiato .navbar-link:focus-within,html.theme--catppuccin-macchiato .navbar-link:hover,html.theme--catppuccin-macchiato .navbar-link.is-active{background-color:rgba(0,0,0,0);color:#8aadf4}html.theme--catppuccin-macchiato .navbar-item{flex-grow:0;flex-shrink:0}html.theme--catppuccin-macchiato .navbar-item img{max-height:1.75rem}html.theme--catppuccin-macchiato .navbar-item.has-dropdown{padding:0}html.theme--catppuccin-macchiato .navbar-item.is-expanded{flex-grow:1;flex-shrink:1}html.theme--catppuccin-macchiato .navbar-item.is-tab{border-bottom:1px solid transparent;min-height:4rem;padding-bottom:calc(0.5rem - 1px)}html.theme--catppuccin-macchiato .navbar-item.is-tab:focus,html.theme--catppuccin-macchiato .navbar-item.is-tab:hover{background-color:rgba(0,0,0,0);border-bottom-color:#8aadf4}html.theme--catppuccin-macchiato .navbar-item.is-tab.is-active{background-color:rgba(0,0,0,0);border-bottom-color:#8aadf4;border-bottom-style:solid;border-bottom-width:3px;color:#8aadf4;padding-bottom:calc(0.5rem - 3px)}html.theme--catppuccin-macchiato .navbar-content{flex-grow:1;flex-shrink:1}html.theme--catppuccin-macchiato .navbar-link:not(.is-arrowless){padding-right:2.5em}html.theme--catppuccin-macchiato .navbar-link:not(.is-arrowless)::after{border-color:#fff;margin-top:-0.375em;right:1.125em}html.theme--catppuccin-macchiato .navbar-dropdown{font-size:0.875rem;padding-bottom:0.5rem;padding-top:0.5rem}html.theme--catppuccin-macchiato .navbar-dropdown .navbar-item{padding-left:1.5rem;padding-right:1.5rem}html.theme--catppuccin-macchiato .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--catppuccin-macchiato .navbar>.container{display:block}html.theme--catppuccin-macchiato .navbar-brand .navbar-item,html.theme--catppuccin-macchiato .navbar-tabs .navbar-item{align-items:center;display:flex}html.theme--catppuccin-macchiato .navbar-link::after{display:none}html.theme--catppuccin-macchiato .navbar-menu{background-color:#8aadf4;box-shadow:0 8px 16px rgba(10,10,10,0.1);padding:0.5rem 0}html.theme--catppuccin-macchiato .navbar-menu.is-active{display:block}html.theme--catppuccin-macchiato .navbar.is-fixed-bottom-touch,html.theme--catppuccin-macchiato .navbar.is-fixed-top-touch{left:0;position:fixed;right:0;z-index:30}html.theme--catppuccin-macchiato .navbar.is-fixed-bottom-touch{bottom:0}html.theme--catppuccin-macchiato .navbar.is-fixed-bottom-touch.has-shadow{box-shadow:0 -2px 3px rgba(10,10,10,0.1)}html.theme--catppuccin-macchiato .navbar.is-fixed-top-touch{top:0}html.theme--catppuccin-macchiato .navbar.is-fixed-top .navbar-menu,html.theme--catppuccin-macchiato .navbar.is-fixed-top-touch .navbar-menu{-webkit-overflow-scrolling:touch;max-height:calc(100vh - 4rem);overflow:auto}html.theme--catppuccin-macchiato html.has-navbar-fixed-top-touch,html.theme--catppuccin-macchiato body.has-navbar-fixed-top-touch{padding-top:4rem}html.theme--catppuccin-macchiato html.has-navbar-fixed-bottom-touch,html.theme--catppuccin-macchiato body.has-navbar-fixed-bottom-touch{padding-bottom:4rem}}@media screen and (min-width: 1056px){html.theme--catppuccin-macchiato .navbar,html.theme--catppuccin-macchiato .navbar-menu,html.theme--catppuccin-macchiato .navbar-start,html.theme--catppuccin-macchiato .navbar-end{align-items:stretch;display:flex}html.theme--catppuccin-macchiato .navbar{min-height:4rem}html.theme--catppuccin-macchiato .navbar.is-spaced{padding:1rem 2rem}html.theme--catppuccin-macchiato .navbar.is-spaced .navbar-start,html.theme--catppuccin-macchiato .navbar.is-spaced .navbar-end{align-items:center}html.theme--catppuccin-macchiato .navbar.is-spaced a.navbar-item,html.theme--catppuccin-macchiato .navbar.is-spaced .navbar-link{border-radius:.4em}html.theme--catppuccin-macchiato .navbar.is-transparent a.navbar-item:focus,html.theme--catppuccin-macchiato .navbar.is-transparent a.navbar-item:hover,html.theme--catppuccin-macchiato .navbar.is-transparent a.navbar-item.is-active,html.theme--catppuccin-macchiato .navbar.is-transparent .navbar-link:focus,html.theme--catppuccin-macchiato .navbar.is-transparent .navbar-link:hover,html.theme--catppuccin-macchiato .navbar.is-transparent .navbar-link.is-active{background-color:transparent !important}html.theme--catppuccin-macchiato .navbar.is-transparent .navbar-item.has-dropdown.is-active .navbar-link,html.theme--catppuccin-macchiato .navbar.is-transparent .navbar-item.has-dropdown.is-hoverable:focus .navbar-link,html.theme--catppuccin-macchiato .navbar.is-transparent .navbar-item.has-dropdown.is-hoverable:focus-within .navbar-link,html.theme--catppuccin-macchiato .navbar.is-transparent .navbar-item.has-dropdown.is-hoverable:hover .navbar-link{background-color:transparent !important}html.theme--catppuccin-macchiato .navbar.is-transparent .navbar-dropdown a.navbar-item:focus,html.theme--catppuccin-macchiato .navbar.is-transparent .navbar-dropdown a.navbar-item:hover{background-color:rgba(0,0,0,0);color:#8087a2}html.theme--catppuccin-macchiato .navbar.is-transparent .navbar-dropdown a.navbar-item.is-active{background-color:rgba(0,0,0,0);color:#8aadf4}html.theme--catppuccin-macchiato .navbar-burger{display:none}html.theme--catppuccin-macchiato .navbar-item,html.theme--catppuccin-macchiato .navbar-link{align-items:center;display:flex}html.theme--catppuccin-macchiato .navbar-item.has-dropdown{align-items:stretch}html.theme--catppuccin-macchiato .navbar-item.has-dropdown-up .navbar-link::after{transform:rotate(135deg) translate(0.25em, -0.25em)}html.theme--catppuccin-macchiato .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--catppuccin-macchiato .navbar-item.is-active .navbar-dropdown,html.theme--catppuccin-macchiato .navbar-item.is-hoverable:focus .navbar-dropdown,html.theme--catppuccin-macchiato .navbar-item.is-hoverable:focus-within .navbar-dropdown,html.theme--catppuccin-macchiato .navbar-item.is-hoverable:hover .navbar-dropdown{display:block}.navbar.is-spaced html.theme--catppuccin-macchiato .navbar-item.is-active .navbar-dropdown,html.theme--catppuccin-macchiato .navbar-item.is-active .navbar-dropdown.is-boxed,.navbar.is-spaced html.theme--catppuccin-macchiato .navbar-item.is-hoverable:focus .navbar-dropdown,html.theme--catppuccin-macchiato .navbar-item.is-hoverable:focus .navbar-dropdown.is-boxed,.navbar.is-spaced html.theme--catppuccin-macchiato .navbar-item.is-hoverable:focus-within .navbar-dropdown,html.theme--catppuccin-macchiato .navbar-item.is-hoverable:focus-within .navbar-dropdown.is-boxed,.navbar.is-spaced html.theme--catppuccin-macchiato .navbar-item.is-hoverable:hover .navbar-dropdown,html.theme--catppuccin-macchiato .navbar-item.is-hoverable:hover .navbar-dropdown.is-boxed{opacity:1;pointer-events:auto;transform:translateY(0)}html.theme--catppuccin-macchiato .navbar-menu{flex-grow:1;flex-shrink:0}html.theme--catppuccin-macchiato .navbar-start{justify-content:flex-start;margin-right:auto}html.theme--catppuccin-macchiato .navbar-end{justify-content:flex-end;margin-left:auto}html.theme--catppuccin-macchiato .navbar-dropdown{background-color:#8aadf4;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--catppuccin-macchiato .navbar-dropdown .navbar-item{padding:0.375rem 1rem;white-space:nowrap}html.theme--catppuccin-macchiato .navbar-dropdown a.navbar-item{padding-right:3rem}html.theme--catppuccin-macchiato .navbar-dropdown a.navbar-item:focus,html.theme--catppuccin-macchiato .navbar-dropdown a.navbar-item:hover{background-color:rgba(0,0,0,0);color:#8087a2}html.theme--catppuccin-macchiato .navbar-dropdown a.navbar-item.is-active{background-color:rgba(0,0,0,0);color:#8aadf4}.navbar.is-spaced html.theme--catppuccin-macchiato .navbar-dropdown,html.theme--catppuccin-macchiato .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--catppuccin-macchiato .navbar-dropdown.is-right{left:auto;right:0}html.theme--catppuccin-macchiato .navbar-divider{display:block}html.theme--catppuccin-macchiato .navbar>.container .navbar-brand,html.theme--catppuccin-macchiato .container>.navbar .navbar-brand{margin-left:-.75rem}html.theme--catppuccin-macchiato .navbar>.container .navbar-menu,html.theme--catppuccin-macchiato .container>.navbar .navbar-menu{margin-right:-.75rem}html.theme--catppuccin-macchiato .navbar.is-fixed-bottom-desktop,html.theme--catppuccin-macchiato .navbar.is-fixed-top-desktop{left:0;position:fixed;right:0;z-index:30}html.theme--catppuccin-macchiato .navbar.is-fixed-bottom-desktop{bottom:0}html.theme--catppuccin-macchiato .navbar.is-fixed-bottom-desktop.has-shadow{box-shadow:0 -2px 3px rgba(10,10,10,0.1)}html.theme--catppuccin-macchiato .navbar.is-fixed-top-desktop{top:0}html.theme--catppuccin-macchiato html.has-navbar-fixed-top-desktop,html.theme--catppuccin-macchiato body.has-navbar-fixed-top-desktop{padding-top:4rem}html.theme--catppuccin-macchiato html.has-navbar-fixed-bottom-desktop,html.theme--catppuccin-macchiato body.has-navbar-fixed-bottom-desktop{padding-bottom:4rem}html.theme--catppuccin-macchiato html.has-spaced-navbar-fixed-top,html.theme--catppuccin-macchiato body.has-spaced-navbar-fixed-top{padding-top:6rem}html.theme--catppuccin-macchiato html.has-spaced-navbar-fixed-bottom,html.theme--catppuccin-macchiato body.has-spaced-navbar-fixed-bottom{padding-bottom:6rem}html.theme--catppuccin-macchiato a.navbar-item.is-active,html.theme--catppuccin-macchiato .navbar-link.is-active{color:#8aadf4}html.theme--catppuccin-macchiato a.navbar-item.is-active:not(:focus):not(:hover),html.theme--catppuccin-macchiato .navbar-link.is-active:not(:focus):not(:hover){background-color:rgba(0,0,0,0)}html.theme--catppuccin-macchiato .navbar-item.has-dropdown:focus .navbar-link,html.theme--catppuccin-macchiato .navbar-item.has-dropdown:hover .navbar-link,html.theme--catppuccin-macchiato .navbar-item.has-dropdown.is-active .navbar-link{background-color:rgba(0,0,0,0)}}html.theme--catppuccin-macchiato .hero.is-fullheight-with-navbar{min-height:calc(100vh - 4rem)}html.theme--catppuccin-macchiato .pagination{font-size:1rem;margin:-.25rem}html.theme--catppuccin-macchiato .pagination.is-small,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.pagination{font-size:.75rem}html.theme--catppuccin-macchiato .pagination.is-medium{font-size:1.25rem}html.theme--catppuccin-macchiato .pagination.is-large{font-size:1.5rem}html.theme--catppuccin-macchiato .pagination.is-rounded .pagination-previous,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.pagination .pagination-previous,html.theme--catppuccin-macchiato .pagination.is-rounded .pagination-next,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.pagination .pagination-next{padding-left:1em;padding-right:1em;border-radius:9999px}html.theme--catppuccin-macchiato .pagination.is-rounded .pagination-link,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.pagination .pagination-link{border-radius:9999px}html.theme--catppuccin-macchiato .pagination,html.theme--catppuccin-macchiato .pagination-list{align-items:center;display:flex;justify-content:center;text-align:center}html.theme--catppuccin-macchiato .pagination-previous,html.theme--catppuccin-macchiato .pagination-next,html.theme--catppuccin-macchiato .pagination-link,html.theme--catppuccin-macchiato .pagination-ellipsis{font-size:1em;justify-content:center;margin:.25rem;padding-left:.5em;padding-right:.5em;text-align:center}html.theme--catppuccin-macchiato .pagination-previous,html.theme--catppuccin-macchiato .pagination-next,html.theme--catppuccin-macchiato .pagination-link{border-color:#5b6078;color:#8aadf4;min-width:2.5em}html.theme--catppuccin-macchiato .pagination-previous:hover,html.theme--catppuccin-macchiato .pagination-next:hover,html.theme--catppuccin-macchiato .pagination-link:hover{border-color:#6e738d;color:#91d7e3}html.theme--catppuccin-macchiato .pagination-previous:focus,html.theme--catppuccin-macchiato .pagination-next:focus,html.theme--catppuccin-macchiato .pagination-link:focus{border-color:#6e738d}html.theme--catppuccin-macchiato .pagination-previous:active,html.theme--catppuccin-macchiato .pagination-next:active,html.theme--catppuccin-macchiato .pagination-link:active{box-shadow:inset 0 1px 2px rgba(10,10,10,0.2)}html.theme--catppuccin-macchiato .pagination-previous[disabled],html.theme--catppuccin-macchiato .pagination-previous.is-disabled,html.theme--catppuccin-macchiato .pagination-next[disabled],html.theme--catppuccin-macchiato .pagination-next.is-disabled,html.theme--catppuccin-macchiato .pagination-link[disabled],html.theme--catppuccin-macchiato .pagination-link.is-disabled{background-color:#5b6078;border-color:#5b6078;box-shadow:none;color:#f5f7fd;opacity:0.5}html.theme--catppuccin-macchiato .pagination-previous,html.theme--catppuccin-macchiato .pagination-next{padding-left:.75em;padding-right:.75em;white-space:nowrap}html.theme--catppuccin-macchiato .pagination-link.is-current{background-color:#8aadf4;border-color:#8aadf4;color:#fff}html.theme--catppuccin-macchiato .pagination-ellipsis{color:#6e738d;pointer-events:none}html.theme--catppuccin-macchiato .pagination-list{flex-wrap:wrap}html.theme--catppuccin-macchiato .pagination-list li{list-style:none}@media screen and (max-width: 768px){html.theme--catppuccin-macchiato .pagination{flex-wrap:wrap}html.theme--catppuccin-macchiato .pagination-previous,html.theme--catppuccin-macchiato .pagination-next{flex-grow:1;flex-shrink:1}html.theme--catppuccin-macchiato .pagination-list li{flex-grow:1;flex-shrink:1}}@media screen and (min-width: 769px),print{html.theme--catppuccin-macchiato .pagination-list{flex-grow:1;flex-shrink:1;justify-content:flex-start;order:1}html.theme--catppuccin-macchiato .pagination-previous,html.theme--catppuccin-macchiato .pagination-next,html.theme--catppuccin-macchiato .pagination-link,html.theme--catppuccin-macchiato .pagination-ellipsis{margin-bottom:0;margin-top:0}html.theme--catppuccin-macchiato .pagination-previous{order:2}html.theme--catppuccin-macchiato .pagination-next{order:3}html.theme--catppuccin-macchiato .pagination{justify-content:space-between;margin-bottom:0;margin-top:0}html.theme--catppuccin-macchiato .pagination.is-centered .pagination-previous{order:1}html.theme--catppuccin-macchiato .pagination.is-centered .pagination-list{justify-content:center;order:2}html.theme--catppuccin-macchiato .pagination.is-centered .pagination-next{order:3}html.theme--catppuccin-macchiato .pagination.is-right .pagination-previous{order:1}html.theme--catppuccin-macchiato .pagination.is-right .pagination-next{order:2}html.theme--catppuccin-macchiato .pagination.is-right .pagination-list{justify-content:flex-end;order:3}}html.theme--catppuccin-macchiato .panel{border-radius:8px;box-shadow:#171717;font-size:1rem}html.theme--catppuccin-macchiato .panel:not(:last-child){margin-bottom:1.5rem}html.theme--catppuccin-macchiato .panel.is-white .panel-heading{background-color:#fff;color:#0a0a0a}html.theme--catppuccin-macchiato .panel.is-white .panel-tabs a.is-active{border-bottom-color:#fff}html.theme--catppuccin-macchiato .panel.is-white .panel-block.is-active .panel-icon{color:#fff}html.theme--catppuccin-macchiato .panel.is-black .panel-heading{background-color:#0a0a0a;color:#fff}html.theme--catppuccin-macchiato .panel.is-black .panel-tabs a.is-active{border-bottom-color:#0a0a0a}html.theme--catppuccin-macchiato .panel.is-black .panel-block.is-active .panel-icon{color:#0a0a0a}html.theme--catppuccin-macchiato .panel.is-light .panel-heading{background-color:#f5f5f5;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .panel.is-light .panel-tabs a.is-active{border-bottom-color:#f5f5f5}html.theme--catppuccin-macchiato .panel.is-light .panel-block.is-active .panel-icon{color:#f5f5f5}html.theme--catppuccin-macchiato .panel.is-dark .panel-heading,html.theme--catppuccin-macchiato .content kbd.panel .panel-heading{background-color:#363a4f;color:#fff}html.theme--catppuccin-macchiato .panel.is-dark .panel-tabs a.is-active,html.theme--catppuccin-macchiato .content kbd.panel .panel-tabs a.is-active{border-bottom-color:#363a4f}html.theme--catppuccin-macchiato .panel.is-dark .panel-block.is-active .panel-icon,html.theme--catppuccin-macchiato .content kbd.panel .panel-block.is-active .panel-icon{color:#363a4f}html.theme--catppuccin-macchiato .panel.is-primary .panel-heading,html.theme--catppuccin-macchiato .docstring>section>a.panel.docs-sourcelink .panel-heading{background-color:#8aadf4;color:#fff}html.theme--catppuccin-macchiato .panel.is-primary .panel-tabs a.is-active,html.theme--catppuccin-macchiato .docstring>section>a.panel.docs-sourcelink .panel-tabs a.is-active{border-bottom-color:#8aadf4}html.theme--catppuccin-macchiato .panel.is-primary .panel-block.is-active .panel-icon,html.theme--catppuccin-macchiato .docstring>section>a.panel.docs-sourcelink .panel-block.is-active .panel-icon{color:#8aadf4}html.theme--catppuccin-macchiato .panel.is-link .panel-heading{background-color:#8aadf4;color:#fff}html.theme--catppuccin-macchiato .panel.is-link .panel-tabs a.is-active{border-bottom-color:#8aadf4}html.theme--catppuccin-macchiato .panel.is-link .panel-block.is-active .panel-icon{color:#8aadf4}html.theme--catppuccin-macchiato .panel.is-info .panel-heading{background-color:#8bd5ca;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .panel.is-info .panel-tabs a.is-active{border-bottom-color:#8bd5ca}html.theme--catppuccin-macchiato .panel.is-info .panel-block.is-active .panel-icon{color:#8bd5ca}html.theme--catppuccin-macchiato .panel.is-success .panel-heading{background-color:#a6da95;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .panel.is-success .panel-tabs a.is-active{border-bottom-color:#a6da95}html.theme--catppuccin-macchiato .panel.is-success .panel-block.is-active .panel-icon{color:#a6da95}html.theme--catppuccin-macchiato .panel.is-warning .panel-heading{background-color:#eed49f;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .panel.is-warning .panel-tabs a.is-active{border-bottom-color:#eed49f}html.theme--catppuccin-macchiato .panel.is-warning .panel-block.is-active .panel-icon{color:#eed49f}html.theme--catppuccin-macchiato .panel.is-danger .panel-heading{background-color:#ed8796;color:#fff}html.theme--catppuccin-macchiato .panel.is-danger .panel-tabs a.is-active{border-bottom-color:#ed8796}html.theme--catppuccin-macchiato .panel.is-danger .panel-block.is-active .panel-icon{color:#ed8796}html.theme--catppuccin-macchiato .panel-tabs:not(:last-child),html.theme--catppuccin-macchiato .panel-block:not(:last-child){border-bottom:1px solid #ededed}html.theme--catppuccin-macchiato .panel-heading{background-color:#494d64;border-radius:8px 8px 0 0;color:#b5c1f1;font-size:1.25em;font-weight:700;line-height:1.25;padding:0.75em 1em}html.theme--catppuccin-macchiato .panel-tabs{align-items:flex-end;display:flex;font-size:.875em;justify-content:center}html.theme--catppuccin-macchiato .panel-tabs a{border-bottom:1px solid #5b6078;margin-bottom:-1px;padding:0.5em}html.theme--catppuccin-macchiato .panel-tabs a.is-active{border-bottom-color:#494d64;color:#739df2}html.theme--catppuccin-macchiato .panel-list a{color:#cad3f5}html.theme--catppuccin-macchiato .panel-list a:hover{color:#8aadf4}html.theme--catppuccin-macchiato .panel-block{align-items:center;color:#b5c1f1;display:flex;justify-content:flex-start;padding:0.5em 0.75em}html.theme--catppuccin-macchiato .panel-block input[type="checkbox"]{margin-right:.75em}html.theme--catppuccin-macchiato .panel-block>.control{flex-grow:1;flex-shrink:1;width:100%}html.theme--catppuccin-macchiato .panel-block.is-wrapped{flex-wrap:wrap}html.theme--catppuccin-macchiato .panel-block.is-active{border-left-color:#8aadf4;color:#739df2}html.theme--catppuccin-macchiato .panel-block.is-active .panel-icon{color:#8aadf4}html.theme--catppuccin-macchiato .panel-block:last-child{border-bottom-left-radius:8px;border-bottom-right-radius:8px}html.theme--catppuccin-macchiato a.panel-block,html.theme--catppuccin-macchiato label.panel-block{cursor:pointer}html.theme--catppuccin-macchiato a.panel-block:hover,html.theme--catppuccin-macchiato label.panel-block:hover{background-color:#1e2030}html.theme--catppuccin-macchiato .panel-icon{display:inline-block;font-size:14px;height:1em;line-height:1em;text-align:center;vertical-align:top;width:1em;color:#f5f7fd;margin-right:.75em}html.theme--catppuccin-macchiato .panel-icon .fa{font-size:inherit;line-height:inherit}html.theme--catppuccin-macchiato .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}html.theme--catppuccin-macchiato .tabs a{align-items:center;border-bottom-color:#5b6078;border-bottom-style:solid;border-bottom-width:1px;color:#cad3f5;display:flex;justify-content:center;margin-bottom:-1px;padding:0.5em 1em;vertical-align:top}html.theme--catppuccin-macchiato .tabs a:hover{border-bottom-color:#b5c1f1;color:#b5c1f1}html.theme--catppuccin-macchiato .tabs li{display:block}html.theme--catppuccin-macchiato .tabs li.is-active a{border-bottom-color:#8aadf4;color:#8aadf4}html.theme--catppuccin-macchiato .tabs ul{align-items:center;border-bottom-color:#5b6078;border-bottom-style:solid;border-bottom-width:1px;display:flex;flex-grow:1;flex-shrink:0;justify-content:flex-start}html.theme--catppuccin-macchiato .tabs ul.is-left{padding-right:0.75em}html.theme--catppuccin-macchiato .tabs ul.is-center{flex:none;justify-content:center;padding-left:0.75em;padding-right:0.75em}html.theme--catppuccin-macchiato .tabs ul.is-right{justify-content:flex-end;padding-left:0.75em}html.theme--catppuccin-macchiato .tabs .icon:first-child{margin-right:.5em}html.theme--catppuccin-macchiato .tabs .icon:last-child{margin-left:.5em}html.theme--catppuccin-macchiato .tabs.is-centered ul{justify-content:center}html.theme--catppuccin-macchiato .tabs.is-right ul{justify-content:flex-end}html.theme--catppuccin-macchiato .tabs.is-boxed a{border:1px solid transparent;border-radius:.4em .4em 0 0}html.theme--catppuccin-macchiato .tabs.is-boxed a:hover{background-color:#1e2030;border-bottom-color:#5b6078}html.theme--catppuccin-macchiato .tabs.is-boxed li.is-active a{background-color:#fff;border-color:#5b6078;border-bottom-color:rgba(0,0,0,0) !important}html.theme--catppuccin-macchiato .tabs.is-fullwidth li{flex-grow:1;flex-shrink:0}html.theme--catppuccin-macchiato .tabs.is-toggle a{border-color:#5b6078;border-style:solid;border-width:1px;margin-bottom:0;position:relative}html.theme--catppuccin-macchiato .tabs.is-toggle a:hover{background-color:#1e2030;border-color:#6e738d;z-index:2}html.theme--catppuccin-macchiato .tabs.is-toggle li+li{margin-left:-1px}html.theme--catppuccin-macchiato .tabs.is-toggle li:first-child a{border-top-left-radius:.4em;border-bottom-left-radius:.4em}html.theme--catppuccin-macchiato .tabs.is-toggle li:last-child a{border-top-right-radius:.4em;border-bottom-right-radius:.4em}html.theme--catppuccin-macchiato .tabs.is-toggle li.is-active a{background-color:#8aadf4;border-color:#8aadf4;color:#fff;z-index:1}html.theme--catppuccin-macchiato .tabs.is-toggle ul{border-bottom:none}html.theme--catppuccin-macchiato .tabs.is-toggle.is-toggle-rounded li:first-child a{border-bottom-left-radius:9999px;border-top-left-radius:9999px;padding-left:1.25em}html.theme--catppuccin-macchiato .tabs.is-toggle.is-toggle-rounded li:last-child a{border-bottom-right-radius:9999px;border-top-right-radius:9999px;padding-right:1.25em}html.theme--catppuccin-macchiato .tabs.is-small,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.tabs{font-size:.75rem}html.theme--catppuccin-macchiato .tabs.is-medium{font-size:1.25rem}html.theme--catppuccin-macchiato .tabs.is-large{font-size:1.5rem}html.theme--catppuccin-macchiato .column{display:block;flex-basis:0;flex-grow:1;flex-shrink:1;padding:.75rem}.columns.is-mobile>html.theme--catppuccin-macchiato .column.is-narrow{flex:none;width:unset}.columns.is-mobile>html.theme--catppuccin-macchiato .column.is-full{flex:none;width:100%}.columns.is-mobile>html.theme--catppuccin-macchiato .column.is-three-quarters{flex:none;width:75%}.columns.is-mobile>html.theme--catppuccin-macchiato .column.is-two-thirds{flex:none;width:66.6666%}.columns.is-mobile>html.theme--catppuccin-macchiato .column.is-half{flex:none;width:50%}.columns.is-mobile>html.theme--catppuccin-macchiato .column.is-one-third{flex:none;width:33.3333%}.columns.is-mobile>html.theme--catppuccin-macchiato .column.is-one-quarter{flex:none;width:25%}.columns.is-mobile>html.theme--catppuccin-macchiato .column.is-one-fifth{flex:none;width:20%}.columns.is-mobile>html.theme--catppuccin-macchiato .column.is-two-fifths{flex:none;width:40%}.columns.is-mobile>html.theme--catppuccin-macchiato .column.is-three-fifths{flex:none;width:60%}.columns.is-mobile>html.theme--catppuccin-macchiato .column.is-four-fifths{flex:none;width:80%}.columns.is-mobile>html.theme--catppuccin-macchiato .column.is-offset-three-quarters{margin-left:75%}.columns.is-mobile>html.theme--catppuccin-macchiato .column.is-offset-two-thirds{margin-left:66.6666%}.columns.is-mobile>html.theme--catppuccin-macchiato .column.is-offset-half{margin-left:50%}.columns.is-mobile>html.theme--catppuccin-macchiato .column.is-offset-one-third{margin-left:33.3333%}.columns.is-mobile>html.theme--catppuccin-macchiato .column.is-offset-one-quarter{margin-left:25%}.columns.is-mobile>html.theme--catppuccin-macchiato .column.is-offset-one-fifth{margin-left:20%}.columns.is-mobile>html.theme--catppuccin-macchiato .column.is-offset-two-fifths{margin-left:40%}.columns.is-mobile>html.theme--catppuccin-macchiato .column.is-offset-three-fifths{margin-left:60%}.columns.is-mobile>html.theme--catppuccin-macchiato .column.is-offset-four-fifths{margin-left:80%}.columns.is-mobile>html.theme--catppuccin-macchiato .column.is-0{flex:none;width:0%}.columns.is-mobile>html.theme--catppuccin-macchiato .column.is-offset-0{margin-left:0%}.columns.is-mobile>html.theme--catppuccin-macchiato .column.is-1{flex:none;width:8.33333337%}.columns.is-mobile>html.theme--catppuccin-macchiato .column.is-offset-1{margin-left:8.33333337%}.columns.is-mobile>html.theme--catppuccin-macchiato .column.is-2{flex:none;width:16.66666674%}.columns.is-mobile>html.theme--catppuccin-macchiato .column.is-offset-2{margin-left:16.66666674%}.columns.is-mobile>html.theme--catppuccin-macchiato .column.is-3{flex:none;width:25%}.columns.is-mobile>html.theme--catppuccin-macchiato .column.is-offset-3{margin-left:25%}.columns.is-mobile>html.theme--catppuccin-macchiato .column.is-4{flex:none;width:33.33333337%}.columns.is-mobile>html.theme--catppuccin-macchiato .column.is-offset-4{margin-left:33.33333337%}.columns.is-mobile>html.theme--catppuccin-macchiato .column.is-5{flex:none;width:41.66666674%}.columns.is-mobile>html.theme--catppuccin-macchiato .column.is-offset-5{margin-left:41.66666674%}.columns.is-mobile>html.theme--catppuccin-macchiato .column.is-6{flex:none;width:50%}.columns.is-mobile>html.theme--catppuccin-macchiato .column.is-offset-6{margin-left:50%}.columns.is-mobile>html.theme--catppuccin-macchiato .column.is-7{flex:none;width:58.33333337%}.columns.is-mobile>html.theme--catppuccin-macchiato .column.is-offset-7{margin-left:58.33333337%}.columns.is-mobile>html.theme--catppuccin-macchiato .column.is-8{flex:none;width:66.66666674%}.columns.is-mobile>html.theme--catppuccin-macchiato .column.is-offset-8{margin-left:66.66666674%}.columns.is-mobile>html.theme--catppuccin-macchiato .column.is-9{flex:none;width:75%}.columns.is-mobile>html.theme--catppuccin-macchiato .column.is-offset-9{margin-left:75%}.columns.is-mobile>html.theme--catppuccin-macchiato .column.is-10{flex:none;width:83.33333337%}.columns.is-mobile>html.theme--catppuccin-macchiato .column.is-offset-10{margin-left:83.33333337%}.columns.is-mobile>html.theme--catppuccin-macchiato .column.is-11{flex:none;width:91.66666674%}.columns.is-mobile>html.theme--catppuccin-macchiato .column.is-offset-11{margin-left:91.66666674%}.columns.is-mobile>html.theme--catppuccin-macchiato .column.is-12{flex:none;width:100%}.columns.is-mobile>html.theme--catppuccin-macchiato .column.is-offset-12{margin-left:100%}@media screen and (max-width: 768px){html.theme--catppuccin-macchiato .column.is-narrow-mobile{flex:none;width:unset}html.theme--catppuccin-macchiato .column.is-full-mobile{flex:none;width:100%}html.theme--catppuccin-macchiato .column.is-three-quarters-mobile{flex:none;width:75%}html.theme--catppuccin-macchiato .column.is-two-thirds-mobile{flex:none;width:66.6666%}html.theme--catppuccin-macchiato .column.is-half-mobile{flex:none;width:50%}html.theme--catppuccin-macchiato .column.is-one-third-mobile{flex:none;width:33.3333%}html.theme--catppuccin-macchiato .column.is-one-quarter-mobile{flex:none;width:25%}html.theme--catppuccin-macchiato .column.is-one-fifth-mobile{flex:none;width:20%}html.theme--catppuccin-macchiato .column.is-two-fifths-mobile{flex:none;width:40%}html.theme--catppuccin-macchiato .column.is-three-fifths-mobile{flex:none;width:60%}html.theme--catppuccin-macchiato .column.is-four-fifths-mobile{flex:none;width:80%}html.theme--catppuccin-macchiato .column.is-offset-three-quarters-mobile{margin-left:75%}html.theme--catppuccin-macchiato .column.is-offset-two-thirds-mobile{margin-left:66.6666%}html.theme--catppuccin-macchiato .column.is-offset-half-mobile{margin-left:50%}html.theme--catppuccin-macchiato .column.is-offset-one-third-mobile{margin-left:33.3333%}html.theme--catppuccin-macchiato .column.is-offset-one-quarter-mobile{margin-left:25%}html.theme--catppuccin-macchiato .column.is-offset-one-fifth-mobile{margin-left:20%}html.theme--catppuccin-macchiato .column.is-offset-two-fifths-mobile{margin-left:40%}html.theme--catppuccin-macchiato .column.is-offset-three-fifths-mobile{margin-left:60%}html.theme--catppuccin-macchiato .column.is-offset-four-fifths-mobile{margin-left:80%}html.theme--catppuccin-macchiato .column.is-0-mobile{flex:none;width:0%}html.theme--catppuccin-macchiato .column.is-offset-0-mobile{margin-left:0%}html.theme--catppuccin-macchiato .column.is-1-mobile{flex:none;width:8.33333337%}html.theme--catppuccin-macchiato .column.is-offset-1-mobile{margin-left:8.33333337%}html.theme--catppuccin-macchiato .column.is-2-mobile{flex:none;width:16.66666674%}html.theme--catppuccin-macchiato .column.is-offset-2-mobile{margin-left:16.66666674%}html.theme--catppuccin-macchiato .column.is-3-mobile{flex:none;width:25%}html.theme--catppuccin-macchiato .column.is-offset-3-mobile{margin-left:25%}html.theme--catppuccin-macchiato .column.is-4-mobile{flex:none;width:33.33333337%}html.theme--catppuccin-macchiato .column.is-offset-4-mobile{margin-left:33.33333337%}html.theme--catppuccin-macchiato .column.is-5-mobile{flex:none;width:41.66666674%}html.theme--catppuccin-macchiato .column.is-offset-5-mobile{margin-left:41.66666674%}html.theme--catppuccin-macchiato .column.is-6-mobile{flex:none;width:50%}html.theme--catppuccin-macchiato .column.is-offset-6-mobile{margin-left:50%}html.theme--catppuccin-macchiato .column.is-7-mobile{flex:none;width:58.33333337%}html.theme--catppuccin-macchiato .column.is-offset-7-mobile{margin-left:58.33333337%}html.theme--catppuccin-macchiato .column.is-8-mobile{flex:none;width:66.66666674%}html.theme--catppuccin-macchiato .column.is-offset-8-mobile{margin-left:66.66666674%}html.theme--catppuccin-macchiato .column.is-9-mobile{flex:none;width:75%}html.theme--catppuccin-macchiato .column.is-offset-9-mobile{margin-left:75%}html.theme--catppuccin-macchiato .column.is-10-mobile{flex:none;width:83.33333337%}html.theme--catppuccin-macchiato .column.is-offset-10-mobile{margin-left:83.33333337%}html.theme--catppuccin-macchiato .column.is-11-mobile{flex:none;width:91.66666674%}html.theme--catppuccin-macchiato .column.is-offset-11-mobile{margin-left:91.66666674%}html.theme--catppuccin-macchiato .column.is-12-mobile{flex:none;width:100%}html.theme--catppuccin-macchiato .column.is-offset-12-mobile{margin-left:100%}}@media screen and (min-width: 769px),print{html.theme--catppuccin-macchiato .column.is-narrow,html.theme--catppuccin-macchiato .column.is-narrow-tablet{flex:none;width:unset}html.theme--catppuccin-macchiato .column.is-full,html.theme--catppuccin-macchiato .column.is-full-tablet{flex:none;width:100%}html.theme--catppuccin-macchiato .column.is-three-quarters,html.theme--catppuccin-macchiato .column.is-three-quarters-tablet{flex:none;width:75%}html.theme--catppuccin-macchiato .column.is-two-thirds,html.theme--catppuccin-macchiato .column.is-two-thirds-tablet{flex:none;width:66.6666%}html.theme--catppuccin-macchiato .column.is-half,html.theme--catppuccin-macchiato .column.is-half-tablet{flex:none;width:50%}html.theme--catppuccin-macchiato .column.is-one-third,html.theme--catppuccin-macchiato .column.is-one-third-tablet{flex:none;width:33.3333%}html.theme--catppuccin-macchiato .column.is-one-quarter,html.theme--catppuccin-macchiato .column.is-one-quarter-tablet{flex:none;width:25%}html.theme--catppuccin-macchiato .column.is-one-fifth,html.theme--catppuccin-macchiato .column.is-one-fifth-tablet{flex:none;width:20%}html.theme--catppuccin-macchiato .column.is-two-fifths,html.theme--catppuccin-macchiato .column.is-two-fifths-tablet{flex:none;width:40%}html.theme--catppuccin-macchiato .column.is-three-fifths,html.theme--catppuccin-macchiato .column.is-three-fifths-tablet{flex:none;width:60%}html.theme--catppuccin-macchiato .column.is-four-fifths,html.theme--catppuccin-macchiato .column.is-four-fifths-tablet{flex:none;width:80%}html.theme--catppuccin-macchiato .column.is-offset-three-quarters,html.theme--catppuccin-macchiato .column.is-offset-three-quarters-tablet{margin-left:75%}html.theme--catppuccin-macchiato .column.is-offset-two-thirds,html.theme--catppuccin-macchiato .column.is-offset-two-thirds-tablet{margin-left:66.6666%}html.theme--catppuccin-macchiato .column.is-offset-half,html.theme--catppuccin-macchiato .column.is-offset-half-tablet{margin-left:50%}html.theme--catppuccin-macchiato .column.is-offset-one-third,html.theme--catppuccin-macchiato .column.is-offset-one-third-tablet{margin-left:33.3333%}html.theme--catppuccin-macchiato .column.is-offset-one-quarter,html.theme--catppuccin-macchiato .column.is-offset-one-quarter-tablet{margin-left:25%}html.theme--catppuccin-macchiato .column.is-offset-one-fifth,html.theme--catppuccin-macchiato .column.is-offset-one-fifth-tablet{margin-left:20%}html.theme--catppuccin-macchiato .column.is-offset-two-fifths,html.theme--catppuccin-macchiato .column.is-offset-two-fifths-tablet{margin-left:40%}html.theme--catppuccin-macchiato .column.is-offset-three-fifths,html.theme--catppuccin-macchiato .column.is-offset-three-fifths-tablet{margin-left:60%}html.theme--catppuccin-macchiato .column.is-offset-four-fifths,html.theme--catppuccin-macchiato .column.is-offset-four-fifths-tablet{margin-left:80%}html.theme--catppuccin-macchiato .column.is-0,html.theme--catppuccin-macchiato .column.is-0-tablet{flex:none;width:0%}html.theme--catppuccin-macchiato .column.is-offset-0,html.theme--catppuccin-macchiato .column.is-offset-0-tablet{margin-left:0%}html.theme--catppuccin-macchiato .column.is-1,html.theme--catppuccin-macchiato .column.is-1-tablet{flex:none;width:8.33333337%}html.theme--catppuccin-macchiato .column.is-offset-1,html.theme--catppuccin-macchiato .column.is-offset-1-tablet{margin-left:8.33333337%}html.theme--catppuccin-macchiato .column.is-2,html.theme--catppuccin-macchiato .column.is-2-tablet{flex:none;width:16.66666674%}html.theme--catppuccin-macchiato .column.is-offset-2,html.theme--catppuccin-macchiato .column.is-offset-2-tablet{margin-left:16.66666674%}html.theme--catppuccin-macchiato .column.is-3,html.theme--catppuccin-macchiato .column.is-3-tablet{flex:none;width:25%}html.theme--catppuccin-macchiato .column.is-offset-3,html.theme--catppuccin-macchiato .column.is-offset-3-tablet{margin-left:25%}html.theme--catppuccin-macchiato .column.is-4,html.theme--catppuccin-macchiato .column.is-4-tablet{flex:none;width:33.33333337%}html.theme--catppuccin-macchiato .column.is-offset-4,html.theme--catppuccin-macchiato .column.is-offset-4-tablet{margin-left:33.33333337%}html.theme--catppuccin-macchiato .column.is-5,html.theme--catppuccin-macchiato .column.is-5-tablet{flex:none;width:41.66666674%}html.theme--catppuccin-macchiato .column.is-offset-5,html.theme--catppuccin-macchiato .column.is-offset-5-tablet{margin-left:41.66666674%}html.theme--catppuccin-macchiato .column.is-6,html.theme--catppuccin-macchiato .column.is-6-tablet{flex:none;width:50%}html.theme--catppuccin-macchiato .column.is-offset-6,html.theme--catppuccin-macchiato .column.is-offset-6-tablet{margin-left:50%}html.theme--catppuccin-macchiato .column.is-7,html.theme--catppuccin-macchiato .column.is-7-tablet{flex:none;width:58.33333337%}html.theme--catppuccin-macchiato .column.is-offset-7,html.theme--catppuccin-macchiato .column.is-offset-7-tablet{margin-left:58.33333337%}html.theme--catppuccin-macchiato .column.is-8,html.theme--catppuccin-macchiato .column.is-8-tablet{flex:none;width:66.66666674%}html.theme--catppuccin-macchiato .column.is-offset-8,html.theme--catppuccin-macchiato .column.is-offset-8-tablet{margin-left:66.66666674%}html.theme--catppuccin-macchiato .column.is-9,html.theme--catppuccin-macchiato .column.is-9-tablet{flex:none;width:75%}html.theme--catppuccin-macchiato .column.is-offset-9,html.theme--catppuccin-macchiato .column.is-offset-9-tablet{margin-left:75%}html.theme--catppuccin-macchiato .column.is-10,html.theme--catppuccin-macchiato .column.is-10-tablet{flex:none;width:83.33333337%}html.theme--catppuccin-macchiato .column.is-offset-10,html.theme--catppuccin-macchiato .column.is-offset-10-tablet{margin-left:83.33333337%}html.theme--catppuccin-macchiato .column.is-11,html.theme--catppuccin-macchiato .column.is-11-tablet{flex:none;width:91.66666674%}html.theme--catppuccin-macchiato .column.is-offset-11,html.theme--catppuccin-macchiato .column.is-offset-11-tablet{margin-left:91.66666674%}html.theme--catppuccin-macchiato .column.is-12,html.theme--catppuccin-macchiato .column.is-12-tablet{flex:none;width:100%}html.theme--catppuccin-macchiato .column.is-offset-12,html.theme--catppuccin-macchiato .column.is-offset-12-tablet{margin-left:100%}}@media screen and (max-width: 1055px){html.theme--catppuccin-macchiato .column.is-narrow-touch{flex:none;width:unset}html.theme--catppuccin-macchiato .column.is-full-touch{flex:none;width:100%}html.theme--catppuccin-macchiato .column.is-three-quarters-touch{flex:none;width:75%}html.theme--catppuccin-macchiato .column.is-two-thirds-touch{flex:none;width:66.6666%}html.theme--catppuccin-macchiato .column.is-half-touch{flex:none;width:50%}html.theme--catppuccin-macchiato .column.is-one-third-touch{flex:none;width:33.3333%}html.theme--catppuccin-macchiato .column.is-one-quarter-touch{flex:none;width:25%}html.theme--catppuccin-macchiato .column.is-one-fifth-touch{flex:none;width:20%}html.theme--catppuccin-macchiato .column.is-two-fifths-touch{flex:none;width:40%}html.theme--catppuccin-macchiato .column.is-three-fifths-touch{flex:none;width:60%}html.theme--catppuccin-macchiato .column.is-four-fifths-touch{flex:none;width:80%}html.theme--catppuccin-macchiato .column.is-offset-three-quarters-touch{margin-left:75%}html.theme--catppuccin-macchiato .column.is-offset-two-thirds-touch{margin-left:66.6666%}html.theme--catppuccin-macchiato .column.is-offset-half-touch{margin-left:50%}html.theme--catppuccin-macchiato .column.is-offset-one-third-touch{margin-left:33.3333%}html.theme--catppuccin-macchiato .column.is-offset-one-quarter-touch{margin-left:25%}html.theme--catppuccin-macchiato .column.is-offset-one-fifth-touch{margin-left:20%}html.theme--catppuccin-macchiato .column.is-offset-two-fifths-touch{margin-left:40%}html.theme--catppuccin-macchiato .column.is-offset-three-fifths-touch{margin-left:60%}html.theme--catppuccin-macchiato .column.is-offset-four-fifths-touch{margin-left:80%}html.theme--catppuccin-macchiato .column.is-0-touch{flex:none;width:0%}html.theme--catppuccin-macchiato .column.is-offset-0-touch{margin-left:0%}html.theme--catppuccin-macchiato .column.is-1-touch{flex:none;width:8.33333337%}html.theme--catppuccin-macchiato .column.is-offset-1-touch{margin-left:8.33333337%}html.theme--catppuccin-macchiato .column.is-2-touch{flex:none;width:16.66666674%}html.theme--catppuccin-macchiato .column.is-offset-2-touch{margin-left:16.66666674%}html.theme--catppuccin-macchiato .column.is-3-touch{flex:none;width:25%}html.theme--catppuccin-macchiato .column.is-offset-3-touch{margin-left:25%}html.theme--catppuccin-macchiato .column.is-4-touch{flex:none;width:33.33333337%}html.theme--catppuccin-macchiato .column.is-offset-4-touch{margin-left:33.33333337%}html.theme--catppuccin-macchiato .column.is-5-touch{flex:none;width:41.66666674%}html.theme--catppuccin-macchiato .column.is-offset-5-touch{margin-left:41.66666674%}html.theme--catppuccin-macchiato .column.is-6-touch{flex:none;width:50%}html.theme--catppuccin-macchiato .column.is-offset-6-touch{margin-left:50%}html.theme--catppuccin-macchiato .column.is-7-touch{flex:none;width:58.33333337%}html.theme--catppuccin-macchiato .column.is-offset-7-touch{margin-left:58.33333337%}html.theme--catppuccin-macchiato .column.is-8-touch{flex:none;width:66.66666674%}html.theme--catppuccin-macchiato .column.is-offset-8-touch{margin-left:66.66666674%}html.theme--catppuccin-macchiato .column.is-9-touch{flex:none;width:75%}html.theme--catppuccin-macchiato .column.is-offset-9-touch{margin-left:75%}html.theme--catppuccin-macchiato .column.is-10-touch{flex:none;width:83.33333337%}html.theme--catppuccin-macchiato .column.is-offset-10-touch{margin-left:83.33333337%}html.theme--catppuccin-macchiato .column.is-11-touch{flex:none;width:91.66666674%}html.theme--catppuccin-macchiato .column.is-offset-11-touch{margin-left:91.66666674%}html.theme--catppuccin-macchiato .column.is-12-touch{flex:none;width:100%}html.theme--catppuccin-macchiato .column.is-offset-12-touch{margin-left:100%}}@media screen and (min-width: 1056px){html.theme--catppuccin-macchiato .column.is-narrow-desktop{flex:none;width:unset}html.theme--catppuccin-macchiato .column.is-full-desktop{flex:none;width:100%}html.theme--catppuccin-macchiato .column.is-three-quarters-desktop{flex:none;width:75%}html.theme--catppuccin-macchiato .column.is-two-thirds-desktop{flex:none;width:66.6666%}html.theme--catppuccin-macchiato .column.is-half-desktop{flex:none;width:50%}html.theme--catppuccin-macchiato .column.is-one-third-desktop{flex:none;width:33.3333%}html.theme--catppuccin-macchiato .column.is-one-quarter-desktop{flex:none;width:25%}html.theme--catppuccin-macchiato .column.is-one-fifth-desktop{flex:none;width:20%}html.theme--catppuccin-macchiato .column.is-two-fifths-desktop{flex:none;width:40%}html.theme--catppuccin-macchiato .column.is-three-fifths-desktop{flex:none;width:60%}html.theme--catppuccin-macchiato .column.is-four-fifths-desktop{flex:none;width:80%}html.theme--catppuccin-macchiato .column.is-offset-three-quarters-desktop{margin-left:75%}html.theme--catppuccin-macchiato .column.is-offset-two-thirds-desktop{margin-left:66.6666%}html.theme--catppuccin-macchiato .column.is-offset-half-desktop{margin-left:50%}html.theme--catppuccin-macchiato .column.is-offset-one-third-desktop{margin-left:33.3333%}html.theme--catppuccin-macchiato .column.is-offset-one-quarter-desktop{margin-left:25%}html.theme--catppuccin-macchiato .column.is-offset-one-fifth-desktop{margin-left:20%}html.theme--catppuccin-macchiato .column.is-offset-two-fifths-desktop{margin-left:40%}html.theme--catppuccin-macchiato .column.is-offset-three-fifths-desktop{margin-left:60%}html.theme--catppuccin-macchiato .column.is-offset-four-fifths-desktop{margin-left:80%}html.theme--catppuccin-macchiato .column.is-0-desktop{flex:none;width:0%}html.theme--catppuccin-macchiato .column.is-offset-0-desktop{margin-left:0%}html.theme--catppuccin-macchiato .column.is-1-desktop{flex:none;width:8.33333337%}html.theme--catppuccin-macchiato .column.is-offset-1-desktop{margin-left:8.33333337%}html.theme--catppuccin-macchiato .column.is-2-desktop{flex:none;width:16.66666674%}html.theme--catppuccin-macchiato .column.is-offset-2-desktop{margin-left:16.66666674%}html.theme--catppuccin-macchiato .column.is-3-desktop{flex:none;width:25%}html.theme--catppuccin-macchiato .column.is-offset-3-desktop{margin-left:25%}html.theme--catppuccin-macchiato .column.is-4-desktop{flex:none;width:33.33333337%}html.theme--catppuccin-macchiato .column.is-offset-4-desktop{margin-left:33.33333337%}html.theme--catppuccin-macchiato .column.is-5-desktop{flex:none;width:41.66666674%}html.theme--catppuccin-macchiato .column.is-offset-5-desktop{margin-left:41.66666674%}html.theme--catppuccin-macchiato .column.is-6-desktop{flex:none;width:50%}html.theme--catppuccin-macchiato .column.is-offset-6-desktop{margin-left:50%}html.theme--catppuccin-macchiato .column.is-7-desktop{flex:none;width:58.33333337%}html.theme--catppuccin-macchiato .column.is-offset-7-desktop{margin-left:58.33333337%}html.theme--catppuccin-macchiato .column.is-8-desktop{flex:none;width:66.66666674%}html.theme--catppuccin-macchiato .column.is-offset-8-desktop{margin-left:66.66666674%}html.theme--catppuccin-macchiato .column.is-9-desktop{flex:none;width:75%}html.theme--catppuccin-macchiato .column.is-offset-9-desktop{margin-left:75%}html.theme--catppuccin-macchiato .column.is-10-desktop{flex:none;width:83.33333337%}html.theme--catppuccin-macchiato .column.is-offset-10-desktop{margin-left:83.33333337%}html.theme--catppuccin-macchiato .column.is-11-desktop{flex:none;width:91.66666674%}html.theme--catppuccin-macchiato .column.is-offset-11-desktop{margin-left:91.66666674%}html.theme--catppuccin-macchiato .column.is-12-desktop{flex:none;width:100%}html.theme--catppuccin-macchiato .column.is-offset-12-desktop{margin-left:100%}}@media screen and (min-width: 1216px){html.theme--catppuccin-macchiato .column.is-narrow-widescreen{flex:none;width:unset}html.theme--catppuccin-macchiato .column.is-full-widescreen{flex:none;width:100%}html.theme--catppuccin-macchiato .column.is-three-quarters-widescreen{flex:none;width:75%}html.theme--catppuccin-macchiato .column.is-two-thirds-widescreen{flex:none;width:66.6666%}html.theme--catppuccin-macchiato .column.is-half-widescreen{flex:none;width:50%}html.theme--catppuccin-macchiato .column.is-one-third-widescreen{flex:none;width:33.3333%}html.theme--catppuccin-macchiato .column.is-one-quarter-widescreen{flex:none;width:25%}html.theme--catppuccin-macchiato .column.is-one-fifth-widescreen{flex:none;width:20%}html.theme--catppuccin-macchiato .column.is-two-fifths-widescreen{flex:none;width:40%}html.theme--catppuccin-macchiato .column.is-three-fifths-widescreen{flex:none;width:60%}html.theme--catppuccin-macchiato .column.is-four-fifths-widescreen{flex:none;width:80%}html.theme--catppuccin-macchiato .column.is-offset-three-quarters-widescreen{margin-left:75%}html.theme--catppuccin-macchiato .column.is-offset-two-thirds-widescreen{margin-left:66.6666%}html.theme--catppuccin-macchiato .column.is-offset-half-widescreen{margin-left:50%}html.theme--catppuccin-macchiato .column.is-offset-one-third-widescreen{margin-left:33.3333%}html.theme--catppuccin-macchiato .column.is-offset-one-quarter-widescreen{margin-left:25%}html.theme--catppuccin-macchiato .column.is-offset-one-fifth-widescreen{margin-left:20%}html.theme--catppuccin-macchiato .column.is-offset-two-fifths-widescreen{margin-left:40%}html.theme--catppuccin-macchiato .column.is-offset-three-fifths-widescreen{margin-left:60%}html.theme--catppuccin-macchiato .column.is-offset-four-fifths-widescreen{margin-left:80%}html.theme--catppuccin-macchiato .column.is-0-widescreen{flex:none;width:0%}html.theme--catppuccin-macchiato .column.is-offset-0-widescreen{margin-left:0%}html.theme--catppuccin-macchiato .column.is-1-widescreen{flex:none;width:8.33333337%}html.theme--catppuccin-macchiato .column.is-offset-1-widescreen{margin-left:8.33333337%}html.theme--catppuccin-macchiato .column.is-2-widescreen{flex:none;width:16.66666674%}html.theme--catppuccin-macchiato .column.is-offset-2-widescreen{margin-left:16.66666674%}html.theme--catppuccin-macchiato .column.is-3-widescreen{flex:none;width:25%}html.theme--catppuccin-macchiato .column.is-offset-3-widescreen{margin-left:25%}html.theme--catppuccin-macchiato .column.is-4-widescreen{flex:none;width:33.33333337%}html.theme--catppuccin-macchiato .column.is-offset-4-widescreen{margin-left:33.33333337%}html.theme--catppuccin-macchiato .column.is-5-widescreen{flex:none;width:41.66666674%}html.theme--catppuccin-macchiato .column.is-offset-5-widescreen{margin-left:41.66666674%}html.theme--catppuccin-macchiato .column.is-6-widescreen{flex:none;width:50%}html.theme--catppuccin-macchiato .column.is-offset-6-widescreen{margin-left:50%}html.theme--catppuccin-macchiato .column.is-7-widescreen{flex:none;width:58.33333337%}html.theme--catppuccin-macchiato .column.is-offset-7-widescreen{margin-left:58.33333337%}html.theme--catppuccin-macchiato .column.is-8-widescreen{flex:none;width:66.66666674%}html.theme--catppuccin-macchiato .column.is-offset-8-widescreen{margin-left:66.66666674%}html.theme--catppuccin-macchiato .column.is-9-widescreen{flex:none;width:75%}html.theme--catppuccin-macchiato .column.is-offset-9-widescreen{margin-left:75%}html.theme--catppuccin-macchiato .column.is-10-widescreen{flex:none;width:83.33333337%}html.theme--catppuccin-macchiato .column.is-offset-10-widescreen{margin-left:83.33333337%}html.theme--catppuccin-macchiato .column.is-11-widescreen{flex:none;width:91.66666674%}html.theme--catppuccin-macchiato .column.is-offset-11-widescreen{margin-left:91.66666674%}html.theme--catppuccin-macchiato .column.is-12-widescreen{flex:none;width:100%}html.theme--catppuccin-macchiato .column.is-offset-12-widescreen{margin-left:100%}}@media screen and (min-width: 1408px){html.theme--catppuccin-macchiato .column.is-narrow-fullhd{flex:none;width:unset}html.theme--catppuccin-macchiato .column.is-full-fullhd{flex:none;width:100%}html.theme--catppuccin-macchiato .column.is-three-quarters-fullhd{flex:none;width:75%}html.theme--catppuccin-macchiato .column.is-two-thirds-fullhd{flex:none;width:66.6666%}html.theme--catppuccin-macchiato .column.is-half-fullhd{flex:none;width:50%}html.theme--catppuccin-macchiato .column.is-one-third-fullhd{flex:none;width:33.3333%}html.theme--catppuccin-macchiato .column.is-one-quarter-fullhd{flex:none;width:25%}html.theme--catppuccin-macchiato .column.is-one-fifth-fullhd{flex:none;width:20%}html.theme--catppuccin-macchiato .column.is-two-fifths-fullhd{flex:none;width:40%}html.theme--catppuccin-macchiato .column.is-three-fifths-fullhd{flex:none;width:60%}html.theme--catppuccin-macchiato .column.is-four-fifths-fullhd{flex:none;width:80%}html.theme--catppuccin-macchiato .column.is-offset-three-quarters-fullhd{margin-left:75%}html.theme--catppuccin-macchiato .column.is-offset-two-thirds-fullhd{margin-left:66.6666%}html.theme--catppuccin-macchiato .column.is-offset-half-fullhd{margin-left:50%}html.theme--catppuccin-macchiato .column.is-offset-one-third-fullhd{margin-left:33.3333%}html.theme--catppuccin-macchiato .column.is-offset-one-quarter-fullhd{margin-left:25%}html.theme--catppuccin-macchiato .column.is-offset-one-fifth-fullhd{margin-left:20%}html.theme--catppuccin-macchiato .column.is-offset-two-fifths-fullhd{margin-left:40%}html.theme--catppuccin-macchiato .column.is-offset-three-fifths-fullhd{margin-left:60%}html.theme--catppuccin-macchiato .column.is-offset-four-fifths-fullhd{margin-left:80%}html.theme--catppuccin-macchiato .column.is-0-fullhd{flex:none;width:0%}html.theme--catppuccin-macchiato .column.is-offset-0-fullhd{margin-left:0%}html.theme--catppuccin-macchiato .column.is-1-fullhd{flex:none;width:8.33333337%}html.theme--catppuccin-macchiato .column.is-offset-1-fullhd{margin-left:8.33333337%}html.theme--catppuccin-macchiato .column.is-2-fullhd{flex:none;width:16.66666674%}html.theme--catppuccin-macchiato .column.is-offset-2-fullhd{margin-left:16.66666674%}html.theme--catppuccin-macchiato .column.is-3-fullhd{flex:none;width:25%}html.theme--catppuccin-macchiato .column.is-offset-3-fullhd{margin-left:25%}html.theme--catppuccin-macchiato .column.is-4-fullhd{flex:none;width:33.33333337%}html.theme--catppuccin-macchiato .column.is-offset-4-fullhd{margin-left:33.33333337%}html.theme--catppuccin-macchiato .column.is-5-fullhd{flex:none;width:41.66666674%}html.theme--catppuccin-macchiato .column.is-offset-5-fullhd{margin-left:41.66666674%}html.theme--catppuccin-macchiato .column.is-6-fullhd{flex:none;width:50%}html.theme--catppuccin-macchiato .column.is-offset-6-fullhd{margin-left:50%}html.theme--catppuccin-macchiato .column.is-7-fullhd{flex:none;width:58.33333337%}html.theme--catppuccin-macchiato .column.is-offset-7-fullhd{margin-left:58.33333337%}html.theme--catppuccin-macchiato .column.is-8-fullhd{flex:none;width:66.66666674%}html.theme--catppuccin-macchiato .column.is-offset-8-fullhd{margin-left:66.66666674%}html.theme--catppuccin-macchiato .column.is-9-fullhd{flex:none;width:75%}html.theme--catppuccin-macchiato .column.is-offset-9-fullhd{margin-left:75%}html.theme--catppuccin-macchiato .column.is-10-fullhd{flex:none;width:83.33333337%}html.theme--catppuccin-macchiato .column.is-offset-10-fullhd{margin-left:83.33333337%}html.theme--catppuccin-macchiato .column.is-11-fullhd{flex:none;width:91.66666674%}html.theme--catppuccin-macchiato .column.is-offset-11-fullhd{margin-left:91.66666674%}html.theme--catppuccin-macchiato .column.is-12-fullhd{flex:none;width:100%}html.theme--catppuccin-macchiato .column.is-offset-12-fullhd{margin-left:100%}}html.theme--catppuccin-macchiato .columns{margin-left:-.75rem;margin-right:-.75rem;margin-top:-.75rem}html.theme--catppuccin-macchiato .columns:last-child{margin-bottom:-.75rem}html.theme--catppuccin-macchiato .columns:not(:last-child){margin-bottom:calc(1.5rem - .75rem)}html.theme--catppuccin-macchiato .columns.is-centered{justify-content:center}html.theme--catppuccin-macchiato .columns.is-gapless{margin-left:0;margin-right:0;margin-top:0}html.theme--catppuccin-macchiato .columns.is-gapless>.column{margin:0;padding:0 !important}html.theme--catppuccin-macchiato .columns.is-gapless:not(:last-child){margin-bottom:1.5rem}html.theme--catppuccin-macchiato .columns.is-gapless:last-child{margin-bottom:0}html.theme--catppuccin-macchiato .columns.is-mobile{display:flex}html.theme--catppuccin-macchiato .columns.is-multiline{flex-wrap:wrap}html.theme--catppuccin-macchiato .columns.is-vcentered{align-items:center}@media screen and (min-width: 769px),print{html.theme--catppuccin-macchiato .columns:not(.is-desktop){display:flex}}@media screen and (min-width: 1056px){html.theme--catppuccin-macchiato .columns.is-desktop{display:flex}}html.theme--catppuccin-macchiato .columns.is-variable{--columnGap: 0.75rem;margin-left:calc(-1 * var(--columnGap));margin-right:calc(-1 * var(--columnGap))}html.theme--catppuccin-macchiato .columns.is-variable>.column{padding-left:var(--columnGap);padding-right:var(--columnGap)}html.theme--catppuccin-macchiato .columns.is-variable.is-0{--columnGap: 0rem}@media screen and (max-width: 768px){html.theme--catppuccin-macchiato .columns.is-variable.is-0-mobile{--columnGap: 0rem}}@media screen and (min-width: 769px),print{html.theme--catppuccin-macchiato .columns.is-variable.is-0-tablet{--columnGap: 0rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--catppuccin-macchiato .columns.is-variable.is-0-tablet-only{--columnGap: 0rem}}@media screen and (max-width: 1055px){html.theme--catppuccin-macchiato .columns.is-variable.is-0-touch{--columnGap: 0rem}}@media screen and (min-width: 1056px){html.theme--catppuccin-macchiato .columns.is-variable.is-0-desktop{--columnGap: 0rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){html.theme--catppuccin-macchiato .columns.is-variable.is-0-desktop-only{--columnGap: 0rem}}@media screen and (min-width: 1216px){html.theme--catppuccin-macchiato .columns.is-variable.is-0-widescreen{--columnGap: 0rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){html.theme--catppuccin-macchiato .columns.is-variable.is-0-widescreen-only{--columnGap: 0rem}}@media screen and (min-width: 1408px){html.theme--catppuccin-macchiato .columns.is-variable.is-0-fullhd{--columnGap: 0rem}}html.theme--catppuccin-macchiato .columns.is-variable.is-1{--columnGap: .25rem}@media screen and (max-width: 768px){html.theme--catppuccin-macchiato .columns.is-variable.is-1-mobile{--columnGap: .25rem}}@media screen and (min-width: 769px),print{html.theme--catppuccin-macchiato .columns.is-variable.is-1-tablet{--columnGap: .25rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--catppuccin-macchiato .columns.is-variable.is-1-tablet-only{--columnGap: .25rem}}@media screen and (max-width: 1055px){html.theme--catppuccin-macchiato .columns.is-variable.is-1-touch{--columnGap: .25rem}}@media screen and (min-width: 1056px){html.theme--catppuccin-macchiato .columns.is-variable.is-1-desktop{--columnGap: .25rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){html.theme--catppuccin-macchiato .columns.is-variable.is-1-desktop-only{--columnGap: .25rem}}@media screen and (min-width: 1216px){html.theme--catppuccin-macchiato .columns.is-variable.is-1-widescreen{--columnGap: .25rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){html.theme--catppuccin-macchiato .columns.is-variable.is-1-widescreen-only{--columnGap: .25rem}}@media screen and (min-width: 1408px){html.theme--catppuccin-macchiato .columns.is-variable.is-1-fullhd{--columnGap: .25rem}}html.theme--catppuccin-macchiato .columns.is-variable.is-2{--columnGap: .5rem}@media screen and (max-width: 768px){html.theme--catppuccin-macchiato .columns.is-variable.is-2-mobile{--columnGap: .5rem}}@media screen and (min-width: 769px),print{html.theme--catppuccin-macchiato .columns.is-variable.is-2-tablet{--columnGap: .5rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--catppuccin-macchiato .columns.is-variable.is-2-tablet-only{--columnGap: .5rem}}@media screen and (max-width: 1055px){html.theme--catppuccin-macchiato .columns.is-variable.is-2-touch{--columnGap: .5rem}}@media screen and (min-width: 1056px){html.theme--catppuccin-macchiato .columns.is-variable.is-2-desktop{--columnGap: .5rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){html.theme--catppuccin-macchiato .columns.is-variable.is-2-desktop-only{--columnGap: .5rem}}@media screen and (min-width: 1216px){html.theme--catppuccin-macchiato .columns.is-variable.is-2-widescreen{--columnGap: .5rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){html.theme--catppuccin-macchiato .columns.is-variable.is-2-widescreen-only{--columnGap: .5rem}}@media screen and (min-width: 1408px){html.theme--catppuccin-macchiato .columns.is-variable.is-2-fullhd{--columnGap: .5rem}}html.theme--catppuccin-macchiato .columns.is-variable.is-3{--columnGap: .75rem}@media screen and (max-width: 768px){html.theme--catppuccin-macchiato .columns.is-variable.is-3-mobile{--columnGap: .75rem}}@media screen and (min-width: 769px),print{html.theme--catppuccin-macchiato .columns.is-variable.is-3-tablet{--columnGap: .75rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--catppuccin-macchiato .columns.is-variable.is-3-tablet-only{--columnGap: .75rem}}@media screen and (max-width: 1055px){html.theme--catppuccin-macchiato .columns.is-variable.is-3-touch{--columnGap: .75rem}}@media screen and (min-width: 1056px){html.theme--catppuccin-macchiato .columns.is-variable.is-3-desktop{--columnGap: .75rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){html.theme--catppuccin-macchiato .columns.is-variable.is-3-desktop-only{--columnGap: .75rem}}@media screen and (min-width: 1216px){html.theme--catppuccin-macchiato .columns.is-variable.is-3-widescreen{--columnGap: .75rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){html.theme--catppuccin-macchiato .columns.is-variable.is-3-widescreen-only{--columnGap: .75rem}}@media screen and (min-width: 1408px){html.theme--catppuccin-macchiato .columns.is-variable.is-3-fullhd{--columnGap: .75rem}}html.theme--catppuccin-macchiato .columns.is-variable.is-4{--columnGap: 1rem}@media screen and (max-width: 768px){html.theme--catppuccin-macchiato .columns.is-variable.is-4-mobile{--columnGap: 1rem}}@media screen and (min-width: 769px),print{html.theme--catppuccin-macchiato .columns.is-variable.is-4-tablet{--columnGap: 1rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--catppuccin-macchiato .columns.is-variable.is-4-tablet-only{--columnGap: 1rem}}@media screen and (max-width: 1055px){html.theme--catppuccin-macchiato .columns.is-variable.is-4-touch{--columnGap: 1rem}}@media screen and (min-width: 1056px){html.theme--catppuccin-macchiato .columns.is-variable.is-4-desktop{--columnGap: 1rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){html.theme--catppuccin-macchiato .columns.is-variable.is-4-desktop-only{--columnGap: 1rem}}@media screen and (min-width: 1216px){html.theme--catppuccin-macchiato .columns.is-variable.is-4-widescreen{--columnGap: 1rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){html.theme--catppuccin-macchiato .columns.is-variable.is-4-widescreen-only{--columnGap: 1rem}}@media screen and (min-width: 1408px){html.theme--catppuccin-macchiato .columns.is-variable.is-4-fullhd{--columnGap: 1rem}}html.theme--catppuccin-macchiato .columns.is-variable.is-5{--columnGap: 1.25rem}@media screen and (max-width: 768px){html.theme--catppuccin-macchiato .columns.is-variable.is-5-mobile{--columnGap: 1.25rem}}@media screen and (min-width: 769px),print{html.theme--catppuccin-macchiato .columns.is-variable.is-5-tablet{--columnGap: 1.25rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--catppuccin-macchiato .columns.is-variable.is-5-tablet-only{--columnGap: 1.25rem}}@media screen and (max-width: 1055px){html.theme--catppuccin-macchiato .columns.is-variable.is-5-touch{--columnGap: 1.25rem}}@media screen and (min-width: 1056px){html.theme--catppuccin-macchiato .columns.is-variable.is-5-desktop{--columnGap: 1.25rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){html.theme--catppuccin-macchiato .columns.is-variable.is-5-desktop-only{--columnGap: 1.25rem}}@media screen and (min-width: 1216px){html.theme--catppuccin-macchiato .columns.is-variable.is-5-widescreen{--columnGap: 1.25rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){html.theme--catppuccin-macchiato .columns.is-variable.is-5-widescreen-only{--columnGap: 1.25rem}}@media screen and (min-width: 1408px){html.theme--catppuccin-macchiato .columns.is-variable.is-5-fullhd{--columnGap: 1.25rem}}html.theme--catppuccin-macchiato .columns.is-variable.is-6{--columnGap: 1.5rem}@media screen and (max-width: 768px){html.theme--catppuccin-macchiato .columns.is-variable.is-6-mobile{--columnGap: 1.5rem}}@media screen and (min-width: 769px),print{html.theme--catppuccin-macchiato .columns.is-variable.is-6-tablet{--columnGap: 1.5rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--catppuccin-macchiato .columns.is-variable.is-6-tablet-only{--columnGap: 1.5rem}}@media screen and (max-width: 1055px){html.theme--catppuccin-macchiato .columns.is-variable.is-6-touch{--columnGap: 1.5rem}}@media screen and (min-width: 1056px){html.theme--catppuccin-macchiato .columns.is-variable.is-6-desktop{--columnGap: 1.5rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){html.theme--catppuccin-macchiato .columns.is-variable.is-6-desktop-only{--columnGap: 1.5rem}}@media screen and (min-width: 1216px){html.theme--catppuccin-macchiato .columns.is-variable.is-6-widescreen{--columnGap: 1.5rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){html.theme--catppuccin-macchiato .columns.is-variable.is-6-widescreen-only{--columnGap: 1.5rem}}@media screen and (min-width: 1408px){html.theme--catppuccin-macchiato .columns.is-variable.is-6-fullhd{--columnGap: 1.5rem}}html.theme--catppuccin-macchiato .columns.is-variable.is-7{--columnGap: 1.75rem}@media screen and (max-width: 768px){html.theme--catppuccin-macchiato .columns.is-variable.is-7-mobile{--columnGap: 1.75rem}}@media screen and (min-width: 769px),print{html.theme--catppuccin-macchiato .columns.is-variable.is-7-tablet{--columnGap: 1.75rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--catppuccin-macchiato .columns.is-variable.is-7-tablet-only{--columnGap: 1.75rem}}@media screen and (max-width: 1055px){html.theme--catppuccin-macchiato .columns.is-variable.is-7-touch{--columnGap: 1.75rem}}@media screen and (min-width: 1056px){html.theme--catppuccin-macchiato .columns.is-variable.is-7-desktop{--columnGap: 1.75rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){html.theme--catppuccin-macchiato .columns.is-variable.is-7-desktop-only{--columnGap: 1.75rem}}@media screen and (min-width: 1216px){html.theme--catppuccin-macchiato .columns.is-variable.is-7-widescreen{--columnGap: 1.75rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){html.theme--catppuccin-macchiato .columns.is-variable.is-7-widescreen-only{--columnGap: 1.75rem}}@media screen and (min-width: 1408px){html.theme--catppuccin-macchiato .columns.is-variable.is-7-fullhd{--columnGap: 1.75rem}}html.theme--catppuccin-macchiato .columns.is-variable.is-8{--columnGap: 2rem}@media screen and (max-width: 768px){html.theme--catppuccin-macchiato .columns.is-variable.is-8-mobile{--columnGap: 2rem}}@media screen and (min-width: 769px),print{html.theme--catppuccin-macchiato .columns.is-variable.is-8-tablet{--columnGap: 2rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--catppuccin-macchiato .columns.is-variable.is-8-tablet-only{--columnGap: 2rem}}@media screen and (max-width: 1055px){html.theme--catppuccin-macchiato .columns.is-variable.is-8-touch{--columnGap: 2rem}}@media screen and (min-width: 1056px){html.theme--catppuccin-macchiato .columns.is-variable.is-8-desktop{--columnGap: 2rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){html.theme--catppuccin-macchiato .columns.is-variable.is-8-desktop-only{--columnGap: 2rem}}@media screen and (min-width: 1216px){html.theme--catppuccin-macchiato .columns.is-variable.is-8-widescreen{--columnGap: 2rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){html.theme--catppuccin-macchiato .columns.is-variable.is-8-widescreen-only{--columnGap: 2rem}}@media screen and (min-width: 1408px){html.theme--catppuccin-macchiato .columns.is-variable.is-8-fullhd{--columnGap: 2rem}}html.theme--catppuccin-macchiato .tile{align-items:stretch;display:block;flex-basis:0;flex-grow:1;flex-shrink:1;min-height:min-content}html.theme--catppuccin-macchiato .tile.is-ancestor{margin-left:-.75rem;margin-right:-.75rem;margin-top:-.75rem}html.theme--catppuccin-macchiato .tile.is-ancestor:last-child{margin-bottom:-.75rem}html.theme--catppuccin-macchiato .tile.is-ancestor:not(:last-child){margin-bottom:.75rem}html.theme--catppuccin-macchiato .tile.is-child{margin:0 !important}html.theme--catppuccin-macchiato .tile.is-parent{padding:.75rem}html.theme--catppuccin-macchiato .tile.is-vertical{flex-direction:column}html.theme--catppuccin-macchiato .tile.is-vertical>.tile.is-child:not(:last-child){margin-bottom:1.5rem !important}@media screen and (min-width: 769px),print{html.theme--catppuccin-macchiato .tile:not(.is-child){display:flex}html.theme--catppuccin-macchiato .tile.is-1{flex:none;width:8.33333337%}html.theme--catppuccin-macchiato .tile.is-2{flex:none;width:16.66666674%}html.theme--catppuccin-macchiato .tile.is-3{flex:none;width:25%}html.theme--catppuccin-macchiato .tile.is-4{flex:none;width:33.33333337%}html.theme--catppuccin-macchiato .tile.is-5{flex:none;width:41.66666674%}html.theme--catppuccin-macchiato .tile.is-6{flex:none;width:50%}html.theme--catppuccin-macchiato .tile.is-7{flex:none;width:58.33333337%}html.theme--catppuccin-macchiato .tile.is-8{flex:none;width:66.66666674%}html.theme--catppuccin-macchiato .tile.is-9{flex:none;width:75%}html.theme--catppuccin-macchiato .tile.is-10{flex:none;width:83.33333337%}html.theme--catppuccin-macchiato .tile.is-11{flex:none;width:91.66666674%}html.theme--catppuccin-macchiato .tile.is-12{flex:none;width:100%}}html.theme--catppuccin-macchiato .hero{align-items:stretch;display:flex;flex-direction:column;justify-content:space-between}html.theme--catppuccin-macchiato .hero .navbar{background:none}html.theme--catppuccin-macchiato .hero .tabs ul{border-bottom:none}html.theme--catppuccin-macchiato .hero.is-white{background-color:#fff;color:#0a0a0a}html.theme--catppuccin-macchiato .hero.is-white a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--catppuccin-macchiato .hero.is-white strong{color:inherit}html.theme--catppuccin-macchiato .hero.is-white .title{color:#0a0a0a}html.theme--catppuccin-macchiato .hero.is-white .subtitle{color:rgba(10,10,10,0.9)}html.theme--catppuccin-macchiato .hero.is-white .subtitle a:not(.button),html.theme--catppuccin-macchiato .hero.is-white .subtitle strong{color:#0a0a0a}@media screen and (max-width: 1055px){html.theme--catppuccin-macchiato .hero.is-white .navbar-menu{background-color:#fff}}html.theme--catppuccin-macchiato .hero.is-white .navbar-item,html.theme--catppuccin-macchiato .hero.is-white .navbar-link{color:rgba(10,10,10,0.7)}html.theme--catppuccin-macchiato .hero.is-white a.navbar-item:hover,html.theme--catppuccin-macchiato .hero.is-white a.navbar-item.is-active,html.theme--catppuccin-macchiato .hero.is-white .navbar-link:hover,html.theme--catppuccin-macchiato .hero.is-white .navbar-link.is-active{background-color:#f2f2f2;color:#0a0a0a}html.theme--catppuccin-macchiato .hero.is-white .tabs a{color:#0a0a0a;opacity:0.9}html.theme--catppuccin-macchiato .hero.is-white .tabs a:hover{opacity:1}html.theme--catppuccin-macchiato .hero.is-white .tabs li.is-active a{color:#fff !important;opacity:1}html.theme--catppuccin-macchiato .hero.is-white .tabs.is-boxed a,html.theme--catppuccin-macchiato .hero.is-white .tabs.is-toggle a{color:#0a0a0a}html.theme--catppuccin-macchiato .hero.is-white .tabs.is-boxed a:hover,html.theme--catppuccin-macchiato .hero.is-white .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--catppuccin-macchiato .hero.is-white .tabs.is-boxed li.is-active a,html.theme--catppuccin-macchiato .hero.is-white .tabs.is-boxed li.is-active a:hover,html.theme--catppuccin-macchiato .hero.is-white .tabs.is-toggle li.is-active a,html.theme--catppuccin-macchiato .hero.is-white .tabs.is-toggle li.is-active a:hover{background-color:#0a0a0a;border-color:#0a0a0a;color:#fff}html.theme--catppuccin-macchiato .hero.is-white.is-bold{background-image:linear-gradient(141deg, #e8e3e4 0%, #fff 71%, #fff 100%)}@media screen and (max-width: 768px){html.theme--catppuccin-macchiato .hero.is-white.is-bold .navbar-menu{background-image:linear-gradient(141deg, #e8e3e4 0%, #fff 71%, #fff 100%)}}html.theme--catppuccin-macchiato .hero.is-black{background-color:#0a0a0a;color:#fff}html.theme--catppuccin-macchiato .hero.is-black a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--catppuccin-macchiato .hero.is-black strong{color:inherit}html.theme--catppuccin-macchiato .hero.is-black .title{color:#fff}html.theme--catppuccin-macchiato .hero.is-black .subtitle{color:rgba(255,255,255,0.9)}html.theme--catppuccin-macchiato .hero.is-black .subtitle a:not(.button),html.theme--catppuccin-macchiato .hero.is-black .subtitle strong{color:#fff}@media screen and (max-width: 1055px){html.theme--catppuccin-macchiato .hero.is-black .navbar-menu{background-color:#0a0a0a}}html.theme--catppuccin-macchiato .hero.is-black .navbar-item,html.theme--catppuccin-macchiato .hero.is-black .navbar-link{color:rgba(255,255,255,0.7)}html.theme--catppuccin-macchiato .hero.is-black a.navbar-item:hover,html.theme--catppuccin-macchiato .hero.is-black a.navbar-item.is-active,html.theme--catppuccin-macchiato .hero.is-black .navbar-link:hover,html.theme--catppuccin-macchiato .hero.is-black .navbar-link.is-active{background-color:#000;color:#fff}html.theme--catppuccin-macchiato .hero.is-black .tabs a{color:#fff;opacity:0.9}html.theme--catppuccin-macchiato .hero.is-black .tabs a:hover{opacity:1}html.theme--catppuccin-macchiato .hero.is-black .tabs li.is-active a{color:#0a0a0a !important;opacity:1}html.theme--catppuccin-macchiato .hero.is-black .tabs.is-boxed a,html.theme--catppuccin-macchiato .hero.is-black .tabs.is-toggle a{color:#fff}html.theme--catppuccin-macchiato .hero.is-black .tabs.is-boxed a:hover,html.theme--catppuccin-macchiato .hero.is-black .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--catppuccin-macchiato .hero.is-black .tabs.is-boxed li.is-active a,html.theme--catppuccin-macchiato .hero.is-black .tabs.is-boxed li.is-active a:hover,html.theme--catppuccin-macchiato .hero.is-black .tabs.is-toggle li.is-active a,html.theme--catppuccin-macchiato .hero.is-black .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#0a0a0a}html.theme--catppuccin-macchiato .hero.is-black.is-bold{background-image:linear-gradient(141deg, #000 0%, #0a0a0a 71%, #181616 100%)}@media screen and (max-width: 768px){html.theme--catppuccin-macchiato .hero.is-black.is-bold .navbar-menu{background-image:linear-gradient(141deg, #000 0%, #0a0a0a 71%, #181616 100%)}}html.theme--catppuccin-macchiato .hero.is-light{background-color:#f5f5f5;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .hero.is-light a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--catppuccin-macchiato .hero.is-light strong{color:inherit}html.theme--catppuccin-macchiato .hero.is-light .title{color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .hero.is-light .subtitle{color:rgba(0,0,0,0.9)}html.theme--catppuccin-macchiato .hero.is-light .subtitle a:not(.button),html.theme--catppuccin-macchiato .hero.is-light .subtitle strong{color:rgba(0,0,0,0.7)}@media screen and (max-width: 1055px){html.theme--catppuccin-macchiato .hero.is-light .navbar-menu{background-color:#f5f5f5}}html.theme--catppuccin-macchiato .hero.is-light .navbar-item,html.theme--catppuccin-macchiato .hero.is-light .navbar-link{color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .hero.is-light a.navbar-item:hover,html.theme--catppuccin-macchiato .hero.is-light a.navbar-item.is-active,html.theme--catppuccin-macchiato .hero.is-light .navbar-link:hover,html.theme--catppuccin-macchiato .hero.is-light .navbar-link.is-active{background-color:#e8e8e8;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .hero.is-light .tabs a{color:rgba(0,0,0,0.7);opacity:0.9}html.theme--catppuccin-macchiato .hero.is-light .tabs a:hover{opacity:1}html.theme--catppuccin-macchiato .hero.is-light .tabs li.is-active a{color:#f5f5f5 !important;opacity:1}html.theme--catppuccin-macchiato .hero.is-light .tabs.is-boxed a,html.theme--catppuccin-macchiato .hero.is-light .tabs.is-toggle a{color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .hero.is-light .tabs.is-boxed a:hover,html.theme--catppuccin-macchiato .hero.is-light .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--catppuccin-macchiato .hero.is-light .tabs.is-boxed li.is-active a,html.theme--catppuccin-macchiato .hero.is-light .tabs.is-boxed li.is-active a:hover,html.theme--catppuccin-macchiato .hero.is-light .tabs.is-toggle li.is-active a,html.theme--catppuccin-macchiato .hero.is-light .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:#f5f5f5}html.theme--catppuccin-macchiato .hero.is-light.is-bold{background-image:linear-gradient(141deg, #dfd8d9 0%, #f5f5f5 71%, #fff 100%)}@media screen and (max-width: 768px){html.theme--catppuccin-macchiato .hero.is-light.is-bold .navbar-menu{background-image:linear-gradient(141deg, #dfd8d9 0%, #f5f5f5 71%, #fff 100%)}}html.theme--catppuccin-macchiato .hero.is-dark,html.theme--catppuccin-macchiato .content kbd.hero{background-color:#363a4f;color:#fff}html.theme--catppuccin-macchiato .hero.is-dark a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--catppuccin-macchiato .content kbd.hero a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--catppuccin-macchiato .hero.is-dark strong,html.theme--catppuccin-macchiato .content kbd.hero strong{color:inherit}html.theme--catppuccin-macchiato .hero.is-dark .title,html.theme--catppuccin-macchiato .content kbd.hero .title{color:#fff}html.theme--catppuccin-macchiato .hero.is-dark .subtitle,html.theme--catppuccin-macchiato .content kbd.hero .subtitle{color:rgba(255,255,255,0.9)}html.theme--catppuccin-macchiato .hero.is-dark .subtitle a:not(.button),html.theme--catppuccin-macchiato .content kbd.hero .subtitle a:not(.button),html.theme--catppuccin-macchiato .hero.is-dark .subtitle strong,html.theme--catppuccin-macchiato .content kbd.hero .subtitle strong{color:#fff}@media screen and (max-width: 1055px){html.theme--catppuccin-macchiato .hero.is-dark .navbar-menu,html.theme--catppuccin-macchiato .content kbd.hero .navbar-menu{background-color:#363a4f}}html.theme--catppuccin-macchiato .hero.is-dark .navbar-item,html.theme--catppuccin-macchiato .content kbd.hero .navbar-item,html.theme--catppuccin-macchiato .hero.is-dark .navbar-link,html.theme--catppuccin-macchiato .content kbd.hero .navbar-link{color:rgba(255,255,255,0.7)}html.theme--catppuccin-macchiato .hero.is-dark a.navbar-item:hover,html.theme--catppuccin-macchiato .content kbd.hero a.navbar-item:hover,html.theme--catppuccin-macchiato .hero.is-dark a.navbar-item.is-active,html.theme--catppuccin-macchiato .content kbd.hero a.navbar-item.is-active,html.theme--catppuccin-macchiato .hero.is-dark .navbar-link:hover,html.theme--catppuccin-macchiato .content kbd.hero .navbar-link:hover,html.theme--catppuccin-macchiato .hero.is-dark .navbar-link.is-active,html.theme--catppuccin-macchiato .content kbd.hero .navbar-link.is-active{background-color:#2c2f40;color:#fff}html.theme--catppuccin-macchiato .hero.is-dark .tabs a,html.theme--catppuccin-macchiato .content kbd.hero .tabs a{color:#fff;opacity:0.9}html.theme--catppuccin-macchiato .hero.is-dark .tabs a:hover,html.theme--catppuccin-macchiato .content kbd.hero .tabs a:hover{opacity:1}html.theme--catppuccin-macchiato .hero.is-dark .tabs li.is-active a,html.theme--catppuccin-macchiato .content kbd.hero .tabs li.is-active a{color:#363a4f !important;opacity:1}html.theme--catppuccin-macchiato .hero.is-dark .tabs.is-boxed a,html.theme--catppuccin-macchiato .content kbd.hero .tabs.is-boxed a,html.theme--catppuccin-macchiato .hero.is-dark .tabs.is-toggle a,html.theme--catppuccin-macchiato .content kbd.hero .tabs.is-toggle a{color:#fff}html.theme--catppuccin-macchiato .hero.is-dark .tabs.is-boxed a:hover,html.theme--catppuccin-macchiato .content kbd.hero .tabs.is-boxed a:hover,html.theme--catppuccin-macchiato .hero.is-dark .tabs.is-toggle a:hover,html.theme--catppuccin-macchiato .content kbd.hero .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--catppuccin-macchiato .hero.is-dark .tabs.is-boxed li.is-active a,html.theme--catppuccin-macchiato .content kbd.hero .tabs.is-boxed li.is-active a,html.theme--catppuccin-macchiato .hero.is-dark .tabs.is-boxed li.is-active a:hover,html.theme--catppuccin-macchiato .hero.is-dark .tabs.is-toggle li.is-active a,html.theme--catppuccin-macchiato .content kbd.hero .tabs.is-toggle li.is-active a,html.theme--catppuccin-macchiato .hero.is-dark .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#363a4f}html.theme--catppuccin-macchiato .hero.is-dark.is-bold,html.theme--catppuccin-macchiato .content kbd.hero.is-bold{background-image:linear-gradient(141deg, #1d2535 0%, #363a4f 71%, #3d3c62 100%)}@media screen and (max-width: 768px){html.theme--catppuccin-macchiato .hero.is-dark.is-bold .navbar-menu,html.theme--catppuccin-macchiato .content kbd.hero.is-bold .navbar-menu{background-image:linear-gradient(141deg, #1d2535 0%, #363a4f 71%, #3d3c62 100%)}}html.theme--catppuccin-macchiato .hero.is-primary,html.theme--catppuccin-macchiato .docstring>section>a.hero.docs-sourcelink{background-color:#8aadf4;color:#fff}html.theme--catppuccin-macchiato .hero.is-primary a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--catppuccin-macchiato .docstring>section>a.hero.docs-sourcelink a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--catppuccin-macchiato .hero.is-primary strong,html.theme--catppuccin-macchiato .docstring>section>a.hero.docs-sourcelink strong{color:inherit}html.theme--catppuccin-macchiato .hero.is-primary .title,html.theme--catppuccin-macchiato .docstring>section>a.hero.docs-sourcelink .title{color:#fff}html.theme--catppuccin-macchiato .hero.is-primary .subtitle,html.theme--catppuccin-macchiato .docstring>section>a.hero.docs-sourcelink .subtitle{color:rgba(255,255,255,0.9)}html.theme--catppuccin-macchiato .hero.is-primary .subtitle a:not(.button),html.theme--catppuccin-macchiato .docstring>section>a.hero.docs-sourcelink .subtitle a:not(.button),html.theme--catppuccin-macchiato .hero.is-primary .subtitle strong,html.theme--catppuccin-macchiato .docstring>section>a.hero.docs-sourcelink .subtitle strong{color:#fff}@media screen and (max-width: 1055px){html.theme--catppuccin-macchiato .hero.is-primary .navbar-menu,html.theme--catppuccin-macchiato .docstring>section>a.hero.docs-sourcelink .navbar-menu{background-color:#8aadf4}}html.theme--catppuccin-macchiato .hero.is-primary .navbar-item,html.theme--catppuccin-macchiato .docstring>section>a.hero.docs-sourcelink .navbar-item,html.theme--catppuccin-macchiato .hero.is-primary .navbar-link,html.theme--catppuccin-macchiato .docstring>section>a.hero.docs-sourcelink .navbar-link{color:rgba(255,255,255,0.7)}html.theme--catppuccin-macchiato .hero.is-primary a.navbar-item:hover,html.theme--catppuccin-macchiato .docstring>section>a.hero.docs-sourcelink a.navbar-item:hover,html.theme--catppuccin-macchiato .hero.is-primary a.navbar-item.is-active,html.theme--catppuccin-macchiato .docstring>section>a.hero.docs-sourcelink a.navbar-item.is-active,html.theme--catppuccin-macchiato .hero.is-primary .navbar-link:hover,html.theme--catppuccin-macchiato .docstring>section>a.hero.docs-sourcelink .navbar-link:hover,html.theme--catppuccin-macchiato .hero.is-primary .navbar-link.is-active,html.theme--catppuccin-macchiato .docstring>section>a.hero.docs-sourcelink .navbar-link.is-active{background-color:#739df2;color:#fff}html.theme--catppuccin-macchiato .hero.is-primary .tabs a,html.theme--catppuccin-macchiato .docstring>section>a.hero.docs-sourcelink .tabs a{color:#fff;opacity:0.9}html.theme--catppuccin-macchiato .hero.is-primary .tabs a:hover,html.theme--catppuccin-macchiato .docstring>section>a.hero.docs-sourcelink .tabs a:hover{opacity:1}html.theme--catppuccin-macchiato .hero.is-primary .tabs li.is-active a,html.theme--catppuccin-macchiato .docstring>section>a.hero.docs-sourcelink .tabs li.is-active a{color:#8aadf4 !important;opacity:1}html.theme--catppuccin-macchiato .hero.is-primary .tabs.is-boxed a,html.theme--catppuccin-macchiato .docstring>section>a.hero.docs-sourcelink .tabs.is-boxed a,html.theme--catppuccin-macchiato .hero.is-primary .tabs.is-toggle a,html.theme--catppuccin-macchiato .docstring>section>a.hero.docs-sourcelink .tabs.is-toggle a{color:#fff}html.theme--catppuccin-macchiato .hero.is-primary .tabs.is-boxed a:hover,html.theme--catppuccin-macchiato .docstring>section>a.hero.docs-sourcelink .tabs.is-boxed a:hover,html.theme--catppuccin-macchiato .hero.is-primary .tabs.is-toggle a:hover,html.theme--catppuccin-macchiato .docstring>section>a.hero.docs-sourcelink .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--catppuccin-macchiato .hero.is-primary .tabs.is-boxed li.is-active a,html.theme--catppuccin-macchiato .docstring>section>a.hero.docs-sourcelink .tabs.is-boxed li.is-active a,html.theme--catppuccin-macchiato .hero.is-primary .tabs.is-boxed li.is-active a:hover,html.theme--catppuccin-macchiato .hero.is-primary .tabs.is-toggle li.is-active a,html.theme--catppuccin-macchiato .docstring>section>a.hero.docs-sourcelink .tabs.is-toggle li.is-active a,html.theme--catppuccin-macchiato .hero.is-primary .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#8aadf4}html.theme--catppuccin-macchiato .hero.is-primary.is-bold,html.theme--catppuccin-macchiato .docstring>section>a.hero.is-bold.docs-sourcelink{background-image:linear-gradient(141deg, #52a5f9 0%, #8aadf4 71%, #9fadf9 100%)}@media screen and (max-width: 768px){html.theme--catppuccin-macchiato .hero.is-primary.is-bold .navbar-menu,html.theme--catppuccin-macchiato .docstring>section>a.hero.is-bold.docs-sourcelink .navbar-menu{background-image:linear-gradient(141deg, #52a5f9 0%, #8aadf4 71%, #9fadf9 100%)}}html.theme--catppuccin-macchiato .hero.is-link{background-color:#8aadf4;color:#fff}html.theme--catppuccin-macchiato .hero.is-link a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--catppuccin-macchiato .hero.is-link strong{color:inherit}html.theme--catppuccin-macchiato .hero.is-link .title{color:#fff}html.theme--catppuccin-macchiato .hero.is-link .subtitle{color:rgba(255,255,255,0.9)}html.theme--catppuccin-macchiato .hero.is-link .subtitle a:not(.button),html.theme--catppuccin-macchiato .hero.is-link .subtitle strong{color:#fff}@media screen and (max-width: 1055px){html.theme--catppuccin-macchiato .hero.is-link .navbar-menu{background-color:#8aadf4}}html.theme--catppuccin-macchiato .hero.is-link .navbar-item,html.theme--catppuccin-macchiato .hero.is-link .navbar-link{color:rgba(255,255,255,0.7)}html.theme--catppuccin-macchiato .hero.is-link a.navbar-item:hover,html.theme--catppuccin-macchiato .hero.is-link a.navbar-item.is-active,html.theme--catppuccin-macchiato .hero.is-link .navbar-link:hover,html.theme--catppuccin-macchiato .hero.is-link .navbar-link.is-active{background-color:#739df2;color:#fff}html.theme--catppuccin-macchiato .hero.is-link .tabs a{color:#fff;opacity:0.9}html.theme--catppuccin-macchiato .hero.is-link .tabs a:hover{opacity:1}html.theme--catppuccin-macchiato .hero.is-link .tabs li.is-active a{color:#8aadf4 !important;opacity:1}html.theme--catppuccin-macchiato .hero.is-link .tabs.is-boxed a,html.theme--catppuccin-macchiato .hero.is-link .tabs.is-toggle a{color:#fff}html.theme--catppuccin-macchiato .hero.is-link .tabs.is-boxed a:hover,html.theme--catppuccin-macchiato .hero.is-link .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--catppuccin-macchiato .hero.is-link .tabs.is-boxed li.is-active a,html.theme--catppuccin-macchiato .hero.is-link .tabs.is-boxed li.is-active a:hover,html.theme--catppuccin-macchiato .hero.is-link .tabs.is-toggle li.is-active a,html.theme--catppuccin-macchiato .hero.is-link .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#8aadf4}html.theme--catppuccin-macchiato .hero.is-link.is-bold{background-image:linear-gradient(141deg, #52a5f9 0%, #8aadf4 71%, #9fadf9 100%)}@media screen and (max-width: 768px){html.theme--catppuccin-macchiato .hero.is-link.is-bold .navbar-menu{background-image:linear-gradient(141deg, #52a5f9 0%, #8aadf4 71%, #9fadf9 100%)}}html.theme--catppuccin-macchiato .hero.is-info{background-color:#8bd5ca;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .hero.is-info a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--catppuccin-macchiato .hero.is-info strong{color:inherit}html.theme--catppuccin-macchiato .hero.is-info .title{color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .hero.is-info .subtitle{color:rgba(0,0,0,0.9)}html.theme--catppuccin-macchiato .hero.is-info .subtitle a:not(.button),html.theme--catppuccin-macchiato .hero.is-info .subtitle strong{color:rgba(0,0,0,0.7)}@media screen and (max-width: 1055px){html.theme--catppuccin-macchiato .hero.is-info .navbar-menu{background-color:#8bd5ca}}html.theme--catppuccin-macchiato .hero.is-info .navbar-item,html.theme--catppuccin-macchiato .hero.is-info .navbar-link{color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .hero.is-info a.navbar-item:hover,html.theme--catppuccin-macchiato .hero.is-info a.navbar-item.is-active,html.theme--catppuccin-macchiato .hero.is-info .navbar-link:hover,html.theme--catppuccin-macchiato .hero.is-info .navbar-link.is-active{background-color:#78cec1;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .hero.is-info .tabs a{color:rgba(0,0,0,0.7);opacity:0.9}html.theme--catppuccin-macchiato .hero.is-info .tabs a:hover{opacity:1}html.theme--catppuccin-macchiato .hero.is-info .tabs li.is-active a{color:#8bd5ca !important;opacity:1}html.theme--catppuccin-macchiato .hero.is-info .tabs.is-boxed a,html.theme--catppuccin-macchiato .hero.is-info .tabs.is-toggle a{color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .hero.is-info .tabs.is-boxed a:hover,html.theme--catppuccin-macchiato .hero.is-info .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--catppuccin-macchiato .hero.is-info .tabs.is-boxed li.is-active a,html.theme--catppuccin-macchiato .hero.is-info .tabs.is-boxed li.is-active a:hover,html.theme--catppuccin-macchiato .hero.is-info .tabs.is-toggle li.is-active a,html.theme--catppuccin-macchiato .hero.is-info .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:#8bd5ca}html.theme--catppuccin-macchiato .hero.is-info.is-bold{background-image:linear-gradient(141deg, #5bd2ac 0%, #8bd5ca 71%, #9adedf 100%)}@media screen and (max-width: 768px){html.theme--catppuccin-macchiato .hero.is-info.is-bold .navbar-menu{background-image:linear-gradient(141deg, #5bd2ac 0%, #8bd5ca 71%, #9adedf 100%)}}html.theme--catppuccin-macchiato .hero.is-success{background-color:#a6da95;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .hero.is-success a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--catppuccin-macchiato .hero.is-success strong{color:inherit}html.theme--catppuccin-macchiato .hero.is-success .title{color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .hero.is-success .subtitle{color:rgba(0,0,0,0.9)}html.theme--catppuccin-macchiato .hero.is-success .subtitle a:not(.button),html.theme--catppuccin-macchiato .hero.is-success .subtitle strong{color:rgba(0,0,0,0.7)}@media screen and (max-width: 1055px){html.theme--catppuccin-macchiato .hero.is-success .navbar-menu{background-color:#a6da95}}html.theme--catppuccin-macchiato .hero.is-success .navbar-item,html.theme--catppuccin-macchiato .hero.is-success .navbar-link{color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .hero.is-success a.navbar-item:hover,html.theme--catppuccin-macchiato .hero.is-success a.navbar-item.is-active,html.theme--catppuccin-macchiato .hero.is-success .navbar-link:hover,html.theme--catppuccin-macchiato .hero.is-success .navbar-link.is-active{background-color:#96d382;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .hero.is-success .tabs a{color:rgba(0,0,0,0.7);opacity:0.9}html.theme--catppuccin-macchiato .hero.is-success .tabs a:hover{opacity:1}html.theme--catppuccin-macchiato .hero.is-success .tabs li.is-active a{color:#a6da95 !important;opacity:1}html.theme--catppuccin-macchiato .hero.is-success .tabs.is-boxed a,html.theme--catppuccin-macchiato .hero.is-success .tabs.is-toggle a{color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .hero.is-success .tabs.is-boxed a:hover,html.theme--catppuccin-macchiato .hero.is-success .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--catppuccin-macchiato .hero.is-success .tabs.is-boxed li.is-active a,html.theme--catppuccin-macchiato .hero.is-success .tabs.is-boxed li.is-active a:hover,html.theme--catppuccin-macchiato .hero.is-success .tabs.is-toggle li.is-active a,html.theme--catppuccin-macchiato .hero.is-success .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:#a6da95}html.theme--catppuccin-macchiato .hero.is-success.is-bold{background-image:linear-gradient(141deg, #94d765 0%, #a6da95 71%, #aae4a5 100%)}@media screen and (max-width: 768px){html.theme--catppuccin-macchiato .hero.is-success.is-bold .navbar-menu{background-image:linear-gradient(141deg, #94d765 0%, #a6da95 71%, #aae4a5 100%)}}html.theme--catppuccin-macchiato .hero.is-warning{background-color:#eed49f;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .hero.is-warning a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--catppuccin-macchiato .hero.is-warning strong{color:inherit}html.theme--catppuccin-macchiato .hero.is-warning .title{color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .hero.is-warning .subtitle{color:rgba(0,0,0,0.9)}html.theme--catppuccin-macchiato .hero.is-warning .subtitle a:not(.button),html.theme--catppuccin-macchiato .hero.is-warning .subtitle strong{color:rgba(0,0,0,0.7)}@media screen and (max-width: 1055px){html.theme--catppuccin-macchiato .hero.is-warning .navbar-menu{background-color:#eed49f}}html.theme--catppuccin-macchiato .hero.is-warning .navbar-item,html.theme--catppuccin-macchiato .hero.is-warning .navbar-link{color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .hero.is-warning a.navbar-item:hover,html.theme--catppuccin-macchiato .hero.is-warning a.navbar-item.is-active,html.theme--catppuccin-macchiato .hero.is-warning .navbar-link:hover,html.theme--catppuccin-macchiato .hero.is-warning .navbar-link.is-active{background-color:#eaca89;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .hero.is-warning .tabs a{color:rgba(0,0,0,0.7);opacity:0.9}html.theme--catppuccin-macchiato .hero.is-warning .tabs a:hover{opacity:1}html.theme--catppuccin-macchiato .hero.is-warning .tabs li.is-active a{color:#eed49f !important;opacity:1}html.theme--catppuccin-macchiato .hero.is-warning .tabs.is-boxed a,html.theme--catppuccin-macchiato .hero.is-warning .tabs.is-toggle a{color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .hero.is-warning .tabs.is-boxed a:hover,html.theme--catppuccin-macchiato .hero.is-warning .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--catppuccin-macchiato .hero.is-warning .tabs.is-boxed li.is-active a,html.theme--catppuccin-macchiato .hero.is-warning .tabs.is-boxed li.is-active a:hover,html.theme--catppuccin-macchiato .hero.is-warning .tabs.is-toggle li.is-active a,html.theme--catppuccin-macchiato .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:#eed49f}html.theme--catppuccin-macchiato .hero.is-warning.is-bold{background-image:linear-gradient(141deg, #efae6b 0%, #eed49f 71%, #f4e9b2 100%)}@media screen and (max-width: 768px){html.theme--catppuccin-macchiato .hero.is-warning.is-bold .navbar-menu{background-image:linear-gradient(141deg, #efae6b 0%, #eed49f 71%, #f4e9b2 100%)}}html.theme--catppuccin-macchiato .hero.is-danger{background-color:#ed8796;color:#fff}html.theme--catppuccin-macchiato .hero.is-danger a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--catppuccin-macchiato .hero.is-danger strong{color:inherit}html.theme--catppuccin-macchiato .hero.is-danger .title{color:#fff}html.theme--catppuccin-macchiato .hero.is-danger .subtitle{color:rgba(255,255,255,0.9)}html.theme--catppuccin-macchiato .hero.is-danger .subtitle a:not(.button),html.theme--catppuccin-macchiato .hero.is-danger .subtitle strong{color:#fff}@media screen and (max-width: 1055px){html.theme--catppuccin-macchiato .hero.is-danger .navbar-menu{background-color:#ed8796}}html.theme--catppuccin-macchiato .hero.is-danger .navbar-item,html.theme--catppuccin-macchiato .hero.is-danger .navbar-link{color:rgba(255,255,255,0.7)}html.theme--catppuccin-macchiato .hero.is-danger a.navbar-item:hover,html.theme--catppuccin-macchiato .hero.is-danger a.navbar-item.is-active,html.theme--catppuccin-macchiato .hero.is-danger .navbar-link:hover,html.theme--catppuccin-macchiato .hero.is-danger .navbar-link.is-active{background-color:#ea7183;color:#fff}html.theme--catppuccin-macchiato .hero.is-danger .tabs a{color:#fff;opacity:0.9}html.theme--catppuccin-macchiato .hero.is-danger .tabs a:hover{opacity:1}html.theme--catppuccin-macchiato .hero.is-danger .tabs li.is-active a{color:#ed8796 !important;opacity:1}html.theme--catppuccin-macchiato .hero.is-danger .tabs.is-boxed a,html.theme--catppuccin-macchiato .hero.is-danger .tabs.is-toggle a{color:#fff}html.theme--catppuccin-macchiato .hero.is-danger .tabs.is-boxed a:hover,html.theme--catppuccin-macchiato .hero.is-danger .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--catppuccin-macchiato .hero.is-danger .tabs.is-boxed li.is-active a,html.theme--catppuccin-macchiato .hero.is-danger .tabs.is-boxed li.is-active a:hover,html.theme--catppuccin-macchiato .hero.is-danger .tabs.is-toggle li.is-active a,html.theme--catppuccin-macchiato .hero.is-danger .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#ed8796}html.theme--catppuccin-macchiato .hero.is-danger.is-bold{background-image:linear-gradient(141deg, #f05183 0%, #ed8796 71%, #f39c9a 100%)}@media screen and (max-width: 768px){html.theme--catppuccin-macchiato .hero.is-danger.is-bold .navbar-menu{background-image:linear-gradient(141deg, #f05183 0%, #ed8796 71%, #f39c9a 100%)}}html.theme--catppuccin-macchiato .hero.is-small .hero-body,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.hero .hero-body{padding:1.5rem}@media screen and (min-width: 769px),print{html.theme--catppuccin-macchiato .hero.is-medium .hero-body{padding:9rem 4.5rem}}@media screen and (min-width: 769px),print{html.theme--catppuccin-macchiato .hero.is-large .hero-body{padding:18rem 6rem}}html.theme--catppuccin-macchiato .hero.is-halfheight .hero-body,html.theme--catppuccin-macchiato .hero.is-fullheight .hero-body,html.theme--catppuccin-macchiato .hero.is-fullheight-with-navbar .hero-body{align-items:center;display:flex}html.theme--catppuccin-macchiato .hero.is-halfheight .hero-body>.container,html.theme--catppuccin-macchiato .hero.is-fullheight .hero-body>.container,html.theme--catppuccin-macchiato .hero.is-fullheight-with-navbar .hero-body>.container{flex-grow:1;flex-shrink:1}html.theme--catppuccin-macchiato .hero.is-halfheight{min-height:50vh}html.theme--catppuccin-macchiato .hero.is-fullheight{min-height:100vh}html.theme--catppuccin-macchiato .hero-video{overflow:hidden}html.theme--catppuccin-macchiato .hero-video video{left:50%;min-height:100%;min-width:100%;position:absolute;top:50%;transform:translate3d(-50%, -50%, 0)}html.theme--catppuccin-macchiato .hero-video.is-transparent{opacity:0.3}@media screen and (max-width: 768px){html.theme--catppuccin-macchiato .hero-video{display:none}}html.theme--catppuccin-macchiato .hero-buttons{margin-top:1.5rem}@media screen and (max-width: 768px){html.theme--catppuccin-macchiato .hero-buttons .button{display:flex}html.theme--catppuccin-macchiato .hero-buttons .button:not(:last-child){margin-bottom:0.75rem}}@media screen and (min-width: 769px),print{html.theme--catppuccin-macchiato .hero-buttons{display:flex;justify-content:center}html.theme--catppuccin-macchiato .hero-buttons .button:not(:last-child){margin-right:1.5rem}}html.theme--catppuccin-macchiato .hero-head,html.theme--catppuccin-macchiato .hero-foot{flex-grow:0;flex-shrink:0}html.theme--catppuccin-macchiato .hero-body{flex-grow:1;flex-shrink:0;padding:3rem 1.5rem}@media screen and (min-width: 769px),print{html.theme--catppuccin-macchiato .hero-body{padding:3rem 3rem}}html.theme--catppuccin-macchiato .section{padding:3rem 1.5rem}@media screen and (min-width: 1056px){html.theme--catppuccin-macchiato .section{padding:3rem 3rem}html.theme--catppuccin-macchiato .section.is-medium{padding:9rem 4.5rem}html.theme--catppuccin-macchiato .section.is-large{padding:18rem 6rem}}html.theme--catppuccin-macchiato .footer{background-color:#1e2030;padding:3rem 1.5rem 6rem}html.theme--catppuccin-macchiato h1 .docs-heading-anchor,html.theme--catppuccin-macchiato h1 .docs-heading-anchor:hover,html.theme--catppuccin-macchiato h1 .docs-heading-anchor:visited,html.theme--catppuccin-macchiato h2 .docs-heading-anchor,html.theme--catppuccin-macchiato h2 .docs-heading-anchor:hover,html.theme--catppuccin-macchiato h2 .docs-heading-anchor:visited,html.theme--catppuccin-macchiato h3 .docs-heading-anchor,html.theme--catppuccin-macchiato h3 .docs-heading-anchor:hover,html.theme--catppuccin-macchiato h3 .docs-heading-anchor:visited,html.theme--catppuccin-macchiato h4 .docs-heading-anchor,html.theme--catppuccin-macchiato h4 .docs-heading-anchor:hover,html.theme--catppuccin-macchiato h4 .docs-heading-anchor:visited,html.theme--catppuccin-macchiato h5 .docs-heading-anchor,html.theme--catppuccin-macchiato h5 .docs-heading-anchor:hover,html.theme--catppuccin-macchiato h5 .docs-heading-anchor:visited,html.theme--catppuccin-macchiato h6 .docs-heading-anchor,html.theme--catppuccin-macchiato h6 .docs-heading-anchor:hover,html.theme--catppuccin-macchiato h6 .docs-heading-anchor:visited{color:#cad3f5}html.theme--catppuccin-macchiato h1 .docs-heading-anchor-permalink,html.theme--catppuccin-macchiato h2 .docs-heading-anchor-permalink,html.theme--catppuccin-macchiato h3 .docs-heading-anchor-permalink,html.theme--catppuccin-macchiato h4 .docs-heading-anchor-permalink,html.theme--catppuccin-macchiato h5 .docs-heading-anchor-permalink,html.theme--catppuccin-macchiato h6 .docs-heading-anchor-permalink{visibility:hidden;vertical-align:middle;margin-left:0.5em;font-size:0.7rem}html.theme--catppuccin-macchiato h1 .docs-heading-anchor-permalink::before,html.theme--catppuccin-macchiato h2 .docs-heading-anchor-permalink::before,html.theme--catppuccin-macchiato h3 .docs-heading-anchor-permalink::before,html.theme--catppuccin-macchiato h4 .docs-heading-anchor-permalink::before,html.theme--catppuccin-macchiato h5 .docs-heading-anchor-permalink::before,html.theme--catppuccin-macchiato h6 .docs-heading-anchor-permalink::before{font-family:"Font Awesome 6 Free";font-weight:900;content:"\f0c1"}html.theme--catppuccin-macchiato h1:hover .docs-heading-anchor-permalink,html.theme--catppuccin-macchiato h2:hover .docs-heading-anchor-permalink,html.theme--catppuccin-macchiato h3:hover .docs-heading-anchor-permalink,html.theme--catppuccin-macchiato h4:hover .docs-heading-anchor-permalink,html.theme--catppuccin-macchiato h5:hover .docs-heading-anchor-permalink,html.theme--catppuccin-macchiato h6:hover .docs-heading-anchor-permalink{visibility:visible}html.theme--catppuccin-macchiato .docs-light-only{display:none !important}html.theme--catppuccin-macchiato pre{position:relative;overflow:hidden}html.theme--catppuccin-macchiato pre code,html.theme--catppuccin-macchiato pre code.hljs{padding:0 .75rem !important;overflow:auto;display:block}html.theme--catppuccin-macchiato pre code:first-of-type,html.theme--catppuccin-macchiato pre code.hljs:first-of-type{padding-top:0.5rem !important}html.theme--catppuccin-macchiato pre code:last-of-type,html.theme--catppuccin-macchiato pre code.hljs:last-of-type{padding-bottom:0.5rem !important}html.theme--catppuccin-macchiato 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 6 Free";color:#cad3f5;cursor:pointer;text-align:center}html.theme--catppuccin-macchiato pre .copy-button:focus,html.theme--catppuccin-macchiato pre .copy-button:hover{opacity:1;background:rgba(202,211,245,0.1);color:#8aadf4}html.theme--catppuccin-macchiato pre .copy-button.success{color:#a6da95;opacity:1}html.theme--catppuccin-macchiato pre .copy-button.error{color:#ed8796;opacity:1}html.theme--catppuccin-macchiato pre:hover .copy-button{opacity:1}html.theme--catppuccin-macchiato .admonition{background-color:#1e2030;border-style:solid;border-width:2px;border-color:#b8c0e0;border-radius:4px;font-size:1rem}html.theme--catppuccin-macchiato .admonition strong{color:currentColor}html.theme--catppuccin-macchiato .admonition.is-small,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.admonition{font-size:.75rem}html.theme--catppuccin-macchiato .admonition.is-medium{font-size:1.25rem}html.theme--catppuccin-macchiato .admonition.is-large{font-size:1.5rem}html.theme--catppuccin-macchiato .admonition.is-default{background-color:#1e2030;border-color:#b8c0e0}html.theme--catppuccin-macchiato .admonition.is-default>.admonition-header{background-color:rgba(0,0,0,0);color:#b8c0e0}html.theme--catppuccin-macchiato .admonition.is-default>.admonition-body{color:#cad3f5}html.theme--catppuccin-macchiato .admonition.is-info{background-color:#1e2030;border-color:#8bd5ca}html.theme--catppuccin-macchiato .admonition.is-info>.admonition-header{background-color:rgba(0,0,0,0);color:#8bd5ca}html.theme--catppuccin-macchiato .admonition.is-info>.admonition-body{color:#cad3f5}html.theme--catppuccin-macchiato .admonition.is-success{background-color:#1e2030;border-color:#a6da95}html.theme--catppuccin-macchiato .admonition.is-success>.admonition-header{background-color:rgba(0,0,0,0);color:#a6da95}html.theme--catppuccin-macchiato .admonition.is-success>.admonition-body{color:#cad3f5}html.theme--catppuccin-macchiato .admonition.is-warning{background-color:#1e2030;border-color:#eed49f}html.theme--catppuccin-macchiato .admonition.is-warning>.admonition-header{background-color:rgba(0,0,0,0);color:#eed49f}html.theme--catppuccin-macchiato .admonition.is-warning>.admonition-body{color:#cad3f5}html.theme--catppuccin-macchiato .admonition.is-danger{background-color:#1e2030;border-color:#ed8796}html.theme--catppuccin-macchiato .admonition.is-danger>.admonition-header{background-color:rgba(0,0,0,0);color:#ed8796}html.theme--catppuccin-macchiato .admonition.is-danger>.admonition-body{color:#cad3f5}html.theme--catppuccin-macchiato .admonition.is-compat{background-color:#1e2030;border-color:#91d7e3}html.theme--catppuccin-macchiato .admonition.is-compat>.admonition-header{background-color:rgba(0,0,0,0);color:#91d7e3}html.theme--catppuccin-macchiato .admonition.is-compat>.admonition-body{color:#cad3f5}html.theme--catppuccin-macchiato .admonition.is-todo{background-color:#1e2030;border-color:#c6a0f6}html.theme--catppuccin-macchiato .admonition.is-todo>.admonition-header{background-color:rgba(0,0,0,0);color:#c6a0f6}html.theme--catppuccin-macchiato .admonition.is-todo>.admonition-body{color:#cad3f5}html.theme--catppuccin-macchiato .admonition-header{color:#b8c0e0;background-color:rgba(0,0,0,0);align-items:center;font-weight:700;justify-content:space-between;line-height:1.25;padding:0.5rem .75rem;position:relative}html.theme--catppuccin-macchiato .admonition-header:before{font-family:"Font Awesome 6 Free";font-weight:900;margin-right:.75rem;content:"\f06a"}html.theme--catppuccin-macchiato details.admonition.is-details>.admonition-header{list-style:none}html.theme--catppuccin-macchiato details.admonition.is-details>.admonition-header:before{font-family:"Font Awesome 6 Free";font-weight:900;content:"\f055"}html.theme--catppuccin-macchiato details.admonition.is-details[open]>.admonition-header:before{font-family:"Font Awesome 6 Free";font-weight:900;content:"\f056"}html.theme--catppuccin-macchiato .admonition-body{color:#cad3f5;padding:0.5rem .75rem}html.theme--catppuccin-macchiato .admonition-body pre{background-color:#1e2030}html.theme--catppuccin-macchiato .admonition-body code{background-color:#1e2030}html.theme--catppuccin-macchiato .docstring{margin-bottom:1em;background-color:rgba(0,0,0,0);border:2px solid #5b6078;border-radius:4px;box-shadow:none;max-width:100%}html.theme--catppuccin-macchiato .docstring>header{cursor:pointer;display:flex;flex-grow:1;align-items:stretch;padding:0.5rem .75rem;background-color:#1e2030;box-shadow:0 0.125em 0.25em rgba(10,10,10,0.1);box-shadow:none;border-bottom:1px solid #5b6078;overflow:auto}html.theme--catppuccin-macchiato .docstring>header code{background-color:transparent}html.theme--catppuccin-macchiato .docstring>header .docstring-article-toggle-button{min-width:1.1rem;padding:0.2rem 0.2rem 0.2rem 0}html.theme--catppuccin-macchiato .docstring>header .docstring-binding{margin-right:0.3em}html.theme--catppuccin-macchiato .docstring>header .docstring-category{margin-left:0.3em}html.theme--catppuccin-macchiato .docstring>section{position:relative;padding:.75rem .75rem;border-bottom:1px solid #5b6078}html.theme--catppuccin-macchiato .docstring>section:last-child{border-bottom:none}html.theme--catppuccin-macchiato .docstring>section>a.docs-sourcelink{transition:opacity 0.3s;opacity:0;position:absolute;right:.375rem;bottom:.375rem}html.theme--catppuccin-macchiato .docstring>section>a.docs-sourcelink:focus{opacity:1 !important}html.theme--catppuccin-macchiato .docstring:hover>section>a.docs-sourcelink{opacity:0.2}html.theme--catppuccin-macchiato .docstring:focus-within>section>a.docs-sourcelink{opacity:0.2}html.theme--catppuccin-macchiato .docstring>section:hover a.docs-sourcelink{opacity:1}html.theme--catppuccin-macchiato .documenter-example-output{background-color:#24273a}html.theme--catppuccin-macchiato .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:#1e2030;color:#cad3f5;border-bottom:3px solid rgba(0,0,0,0);padding:10px 35px;text-align:center;font-size:15px}html.theme--catppuccin-macchiato .outdated-warning-overlay .outdated-warning-closer{position:absolute;top:calc(50% - 10px);right:18px;cursor:pointer;width:12px}html.theme--catppuccin-macchiato .outdated-warning-overlay a{color:#8aadf4}html.theme--catppuccin-macchiato .outdated-warning-overlay a:hover{color:#91d7e3}html.theme--catppuccin-macchiato .content pre{border:2px solid #5b6078;border-radius:4px}html.theme--catppuccin-macchiato .content code{font-weight:inherit}html.theme--catppuccin-macchiato .content a code{color:#8aadf4}html.theme--catppuccin-macchiato .content a:hover code{color:#91d7e3}html.theme--catppuccin-macchiato .content h1 code,html.theme--catppuccin-macchiato .content h2 code,html.theme--catppuccin-macchiato .content h3 code,html.theme--catppuccin-macchiato .content h4 code,html.theme--catppuccin-macchiato .content h5 code,html.theme--catppuccin-macchiato .content h6 code{color:#cad3f5}html.theme--catppuccin-macchiato .content table{display:block;width:initial;max-width:100%;overflow-x:auto}html.theme--catppuccin-macchiato .content blockquote>ul:first-child,html.theme--catppuccin-macchiato .content blockquote>ol:first-child,html.theme--catppuccin-macchiato .content .admonition-body>ul:first-child,html.theme--catppuccin-macchiato .content .admonition-body>ol:first-child{margin-top:0}html.theme--catppuccin-macchiato pre,html.theme--catppuccin-macchiato code{font-variant-ligatures:no-contextual}html.theme--catppuccin-macchiato .breadcrumb a.is-disabled{cursor:default;pointer-events:none}html.theme--catppuccin-macchiato .breadcrumb a.is-disabled,html.theme--catppuccin-macchiato .breadcrumb a.is-disabled:hover{color:#b5c1f1}html.theme--catppuccin-macchiato .hljs{background:initial !important}html.theme--catppuccin-macchiato .katex .katex-mathml{top:0;right:0}html.theme--catppuccin-macchiato .katex-display,html.theme--catppuccin-macchiato mjx-container,html.theme--catppuccin-macchiato .MathJax_Display{margin:0.5em 0 !important}html.theme--catppuccin-macchiato html{-moz-osx-font-smoothing:auto;-webkit-font-smoothing:auto}html.theme--catppuccin-macchiato li.no-marker{list-style:none}html.theme--catppuccin-macchiato #documenter .docs-main>article{overflow-wrap:break-word}html.theme--catppuccin-macchiato #documenter .docs-main>article .math-container{overflow-x:auto;overflow-y:hidden}@media screen and (min-width: 1056px){html.theme--catppuccin-macchiato #documenter .docs-main{max-width:52rem;margin-left:20rem;padding-right:1rem}}@media screen and (max-width: 1055px){html.theme--catppuccin-macchiato #documenter .docs-main{width:100%}html.theme--catppuccin-macchiato #documenter .docs-main>article{max-width:52rem;margin-left:auto;margin-right:auto;margin-bottom:1rem;padding:0 1rem}html.theme--catppuccin-macchiato #documenter .docs-main>header,html.theme--catppuccin-macchiato #documenter .docs-main>nav{max-width:100%;width:100%;margin:0}}html.theme--catppuccin-macchiato #documenter .docs-main header.docs-navbar{background-color:#24273a;border-bottom:1px solid #5b6078;z-index:2;min-height:4rem;margin-bottom:1rem;display:flex}html.theme--catppuccin-macchiato #documenter .docs-main header.docs-navbar .breadcrumb{flex-grow:1;overflow-x:hidden}html.theme--catppuccin-macchiato #documenter .docs-main header.docs-navbar .docs-sidebar-button{display:block;font-size:1.5rem;padding-bottom:0.1rem;margin-right:1rem}html.theme--catppuccin-macchiato #documenter .docs-main header.docs-navbar .docs-right{display:flex;white-space:nowrap;gap:1rem;align-items:center}html.theme--catppuccin-macchiato #documenter .docs-main header.docs-navbar .docs-right .docs-icon,html.theme--catppuccin-macchiato #documenter .docs-main header.docs-navbar .docs-right .docs-label{display:inline-block}html.theme--catppuccin-macchiato #documenter .docs-main header.docs-navbar .docs-right .docs-label{padding:0;margin-left:0.3em}@media screen and (max-width: 1055px){html.theme--catppuccin-macchiato #documenter .docs-main header.docs-navbar .docs-right .docs-navbar-link{margin-left:0.4rem;margin-right:0.4rem}}html.theme--catppuccin-macchiato #documenter .docs-main header.docs-navbar>*{margin:auto 0}@media screen and (max-width: 1055px){html.theme--catppuccin-macchiato #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--catppuccin-macchiato #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--catppuccin-macchiato #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--catppuccin-macchiato #documenter .docs-main section.footnotes{border-top:1px solid #5b6078}html.theme--catppuccin-macchiato #documenter .docs-main section.footnotes li .tag:first-child,html.theme--catppuccin-macchiato #documenter .docs-main section.footnotes li .docstring>section>a.docs-sourcelink:first-child,html.theme--catppuccin-macchiato #documenter .docs-main section.footnotes li .content kbd:first-child,html.theme--catppuccin-macchiato .content #documenter .docs-main section.footnotes li kbd:first-child{margin-right:1em;margin-bottom:0.4em}html.theme--catppuccin-macchiato #documenter .docs-main .docs-footer{display:flex;flex-wrap:wrap;margin-left:0;margin-right:0;border-top:1px solid #5b6078;padding-top:1rem;padding-bottom:1rem}@media screen and (max-width: 1055px){html.theme--catppuccin-macchiato #documenter .docs-main .docs-footer{padding-left:1rem;padding-right:1rem}}html.theme--catppuccin-macchiato #documenter .docs-main .docs-footer .docs-footer-nextpage,html.theme--catppuccin-macchiato #documenter .docs-main .docs-footer .docs-footer-prevpage{flex-grow:1}html.theme--catppuccin-macchiato #documenter .docs-main .docs-footer .docs-footer-nextpage{text-align:right}html.theme--catppuccin-macchiato #documenter .docs-main .docs-footer .flexbox-break{flex-basis:100%;height:0}html.theme--catppuccin-macchiato #documenter .docs-main .docs-footer .footer-message{font-size:0.8em;margin:0.5em auto 0 auto;text-align:center}html.theme--catppuccin-macchiato #documenter .docs-sidebar{display:flex;flex-direction:column;color:#cad3f5;background-color:#1e2030;border-right:1px solid #5b6078;padding:0;flex:0 0 18rem;z-index:5;font-size:1rem;position:fixed;left:-18rem;width:18rem;height:100%;transition:left 0.3s}html.theme--catppuccin-macchiato #documenter .docs-sidebar.visible{left:0;box-shadow:.4rem 0rem .8rem #171717}@media screen and (min-width: 1056px){html.theme--catppuccin-macchiato #documenter .docs-sidebar.visible{box-shadow:none}}@media screen and (min-width: 1056px){html.theme--catppuccin-macchiato #documenter .docs-sidebar{left:0;top:0}}html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo{margin-top:1rem;padding:0 1rem}html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img{max-height:6rem;margin:auto}html.theme--catppuccin-macchiato #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--catppuccin-macchiato #documenter .docs-sidebar .docs-package-name .docs-autofit{max-width:16.2rem}html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-package-name a,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-package-name a:hover{color:#cad3f5}html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-version-selector{border-top:1px solid #5b6078;display:none;padding:0.5rem}html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-version-selector.visible{display:flex}html.theme--catppuccin-macchiato #documenter .docs-sidebar ul.docs-menu{flex-grow:1;user-select:none;border-top:1px solid #5b6078;padding-bottom:1.5rem}html.theme--catppuccin-macchiato #documenter .docs-sidebar ul.docs-menu>li>.tocitem{font-weight:bold}html.theme--catppuccin-macchiato #documenter .docs-sidebar ul.docs-menu>li li{font-size:.95rem;margin-left:1em;border-left:1px solid #5b6078}html.theme--catppuccin-macchiato #documenter .docs-sidebar ul.docs-menu input.collapse-toggle{display:none}html.theme--catppuccin-macchiato #documenter .docs-sidebar ul.docs-menu ul.collapsed{display:none}html.theme--catppuccin-macchiato #documenter .docs-sidebar ul.docs-menu input:checked~ul.collapsed{display:block}html.theme--catppuccin-macchiato #documenter .docs-sidebar ul.docs-menu label.tocitem{display:flex}html.theme--catppuccin-macchiato #documenter .docs-sidebar ul.docs-menu label.tocitem .docs-label{flex-grow:2}html.theme--catppuccin-macchiato #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}html.theme--catppuccin-macchiato #documenter .docs-sidebar ul.docs-menu label.tocitem .docs-chevron::before{font-family:"Font Awesome 6 Free";font-weight:900;content:"\f054"}html.theme--catppuccin-macchiato #documenter .docs-sidebar ul.docs-menu input:checked~label.tocitem .docs-chevron::before{content:"\f078"}html.theme--catppuccin-macchiato #documenter .docs-sidebar ul.docs-menu .tocitem{display:block;padding:0.5rem 0.5rem}html.theme--catppuccin-macchiato #documenter .docs-sidebar ul.docs-menu .tocitem,html.theme--catppuccin-macchiato #documenter .docs-sidebar ul.docs-menu .tocitem:hover{color:#cad3f5;background:#1e2030}html.theme--catppuccin-macchiato #documenter .docs-sidebar ul.docs-menu a.tocitem:hover,html.theme--catppuccin-macchiato #documenter .docs-sidebar ul.docs-menu label.tocitem:hover{color:#cad3f5;background-color:#26283d}html.theme--catppuccin-macchiato #documenter .docs-sidebar ul.docs-menu li.is-active{border-top:1px solid #5b6078;border-bottom:1px solid #5b6078;background-color:#181926}html.theme--catppuccin-macchiato #documenter .docs-sidebar ul.docs-menu li.is-active .tocitem,html.theme--catppuccin-macchiato #documenter .docs-sidebar ul.docs-menu li.is-active .tocitem:hover{background-color:#181926;color:#cad3f5}html.theme--catppuccin-macchiato #documenter .docs-sidebar ul.docs-menu li.is-active ul.internal .tocitem:hover{background-color:#26283d;color:#cad3f5}html.theme--catppuccin-macchiato #documenter .docs-sidebar ul.docs-menu>li.is-active:first-child{border-top:none}html.theme--catppuccin-macchiato #documenter .docs-sidebar ul.docs-menu ul.internal{margin:0 0.5rem 0.5rem;border-top:1px solid #5b6078}html.theme--catppuccin-macchiato #documenter .docs-sidebar ul.docs-menu ul.internal li{font-size:.85rem;border-left:none;margin-left:0;margin-top:0.5rem}html.theme--catppuccin-macchiato #documenter .docs-sidebar ul.docs-menu ul.internal .tocitem{width:100%;padding:0}html.theme--catppuccin-macchiato #documenter .docs-sidebar ul.docs-menu ul.internal .tocitem::before{content:"⚬";margin-right:0.4em}html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search{margin:auto;margin-top:0.5rem;margin-bottom:0.5rem}html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input{width:14.4rem}html.theme--catppuccin-macchiato #documenter .docs-sidebar #documenter-search-query{color:#868c98;width:14.4rem;box-shadow:inset 0 1px 2px rgba(10,10,10,0.1)}@media screen and (min-width: 1056px){html.theme--catppuccin-macchiato #documenter .docs-sidebar ul.docs-menu{overflow-y:auto;-webkit-overflow-scroll:touch}html.theme--catppuccin-macchiato #documenter .docs-sidebar ul.docs-menu::-webkit-scrollbar{width:.3rem;background:none}html.theme--catppuccin-macchiato #documenter .docs-sidebar ul.docs-menu::-webkit-scrollbar-thumb{border-radius:5px 0px 0px 5px;background:#2e3149}html.theme--catppuccin-macchiato #documenter .docs-sidebar ul.docs-menu::-webkit-scrollbar-thumb:hover{background:#3d4162}}@media screen and (max-width: 1055px){html.theme--catppuccin-macchiato #documenter .docs-sidebar{overflow-y:auto;-webkit-overflow-scroll:touch}html.theme--catppuccin-macchiato #documenter .docs-sidebar::-webkit-scrollbar{width:.3rem;background:none}html.theme--catppuccin-macchiato #documenter .docs-sidebar::-webkit-scrollbar-thumb{border-radius:5px 0px 0px 5px;background:#2e3149}html.theme--catppuccin-macchiato #documenter .docs-sidebar::-webkit-scrollbar-thumb:hover{background:#3d4162}}html.theme--catppuccin-macchiato kbd.search-modal-key-hints{border-radius:0.25rem;border:1px solid rgba(245,245,245,0.6);box-shadow:0 2px 0 1px rgba(245,245,245,0.6);cursor:default;font-size:0.9rem;line-height:1.5;min-width:0.75rem;text-align:center;padding:0.1rem 0.3rem;position:relative;top:-1px}html.theme--catppuccin-macchiato .search-min-width-50{min-width:50%}html.theme--catppuccin-macchiato .search-min-height-100{min-height:100%}html.theme--catppuccin-macchiato .search-modal-card-body{max-height:calc(100vh - 15rem)}html.theme--catppuccin-macchiato .search-result-link{border-radius:0.7em;transition:all 300ms}html.theme--catppuccin-macchiato .search-result-link:hover,html.theme--catppuccin-macchiato .search-result-link:focus{background-color:rgba(0,128,128,0.1)}html.theme--catppuccin-macchiato .search-result-link .property-search-result-badge,html.theme--catppuccin-macchiato .search-result-link .search-filter{transition:all 300ms}html.theme--catppuccin-macchiato .property-search-result-badge,html.theme--catppuccin-macchiato .search-filter{padding:0.15em 0.5em;font-size:0.8em;font-style:italic;text-transform:none !important;line-height:1.5;color:#f5f5f5;background-color:rgba(51,65,85,0.501961);border-radius:0.6rem}html.theme--catppuccin-macchiato .search-result-link:hover .property-search-result-badge,html.theme--catppuccin-macchiato .search-result-link:hover .search-filter,html.theme--catppuccin-macchiato .search-result-link:focus .property-search-result-badge,html.theme--catppuccin-macchiato .search-result-link:focus .search-filter{color:#333;background-color:#f1f5f9}html.theme--catppuccin-macchiato .search-filter{color:#333;background-color:#f5f5f5;transition:all 300ms}html.theme--catppuccin-macchiato .search-filter:hover,html.theme--catppuccin-macchiato .search-filter:focus{color:#333}html.theme--catppuccin-macchiato .search-filter-selected{color:#363a4f;background-color:#b7bdf8}html.theme--catppuccin-macchiato .search-filter-selected:hover,html.theme--catppuccin-macchiato .search-filter-selected:focus{color:#363a4f}html.theme--catppuccin-macchiato .search-result-highlight{background-color:#ffdd57;color:black}html.theme--catppuccin-macchiato .search-divider{border-bottom:1px solid #5b6078}html.theme--catppuccin-macchiato .search-result-title{width:85%;color:#f5f5f5}html.theme--catppuccin-macchiato .search-result-code-title{font-size:0.875rem;font-family:"JuliaMono","SFMono-Regular","Menlo","Consolas","Liberation Mono","DejaVu Sans Mono",monospace}html.theme--catppuccin-macchiato #search-modal .modal-card-body::-webkit-scrollbar,html.theme--catppuccin-macchiato #search-modal .filter-tabs::-webkit-scrollbar{height:10px;width:10px;background-color:transparent}html.theme--catppuccin-macchiato #search-modal .modal-card-body::-webkit-scrollbar-thumb,html.theme--catppuccin-macchiato #search-modal .filter-tabs::-webkit-scrollbar-thumb{background-color:gray;border-radius:1rem}html.theme--catppuccin-macchiato #search-modal .modal-card-body::-webkit-scrollbar-track,html.theme--catppuccin-macchiato #search-modal .filter-tabs::-webkit-scrollbar-track{-webkit-box-shadow:inset 0 0 6px rgba(0,0,0,0.6);background-color:transparent}html.theme--catppuccin-macchiato .w-100{width:100%}html.theme--catppuccin-macchiato .gap-2{gap:0.5rem}html.theme--catppuccin-macchiato .gap-4{gap:1rem}html.theme--catppuccin-macchiato .gap-8{gap:2rem}html.theme--catppuccin-macchiato{background-color:#24273a;font-size:16px;min-width:300px;overflow-x:auto;overflow-y:scroll;text-rendering:optimizeLegibility;text-size-adjust:100%}html.theme--catppuccin-macchiato a{transition:all 200ms ease}html.theme--catppuccin-macchiato .label{color:#cad3f5}html.theme--catppuccin-macchiato .button,html.theme--catppuccin-macchiato .control.has-icons-left .icon,html.theme--catppuccin-macchiato .control.has-icons-right .icon,html.theme--catppuccin-macchiato .input,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input,html.theme--catppuccin-macchiato .pagination-ellipsis,html.theme--catppuccin-macchiato .pagination-link,html.theme--catppuccin-macchiato .pagination-next,html.theme--catppuccin-macchiato .pagination-previous,html.theme--catppuccin-macchiato .select,html.theme--catppuccin-macchiato .select select,html.theme--catppuccin-macchiato .textarea{height:2.5em;color:#cad3f5}html.theme--catppuccin-macchiato .input,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input,html.theme--catppuccin-macchiato .textarea{transition:all 200ms ease;box-shadow:none;border-width:1px;padding-left:1em;padding-right:1em;color:#cad3f5}html.theme--catppuccin-macchiato .select:after,html.theme--catppuccin-macchiato .select select{border-width:1px}html.theme--catppuccin-macchiato .menu-list a{transition:all 300ms ease}html.theme--catppuccin-macchiato .modal-card-foot,html.theme--catppuccin-macchiato .modal-card-head{border-color:#5b6078}html.theme--catppuccin-macchiato .navbar{border-radius:.4em}html.theme--catppuccin-macchiato .navbar.is-transparent{background:none}html.theme--catppuccin-macchiato .navbar.is-primary .navbar-dropdown a.navbar-item.is-active,html.theme--catppuccin-macchiato .docstring>section>a.navbar.docs-sourcelink .navbar-dropdown a.navbar-item.is-active{background-color:#8aadf4}@media screen and (max-width: 1055px){html.theme--catppuccin-macchiato .navbar .navbar-menu{background-color:#8aadf4;border-radius:0 0 .4em .4em}}html.theme--catppuccin-macchiato .docstring>section>a.docs-sourcelink:not(body){color:#363a4f}html.theme--catppuccin-macchiato .tag.is-link:not(body),html.theme--catppuccin-macchiato .docstring>section>a.is-link.docs-sourcelink:not(body),html.theme--catppuccin-macchiato .content kbd.is-link:not(body){color:#363a4f}html.theme--catppuccin-macchiato .ansi span.sgr1{font-weight:bolder}html.theme--catppuccin-macchiato .ansi span.sgr2{font-weight:lighter}html.theme--catppuccin-macchiato .ansi span.sgr3{font-style:italic}html.theme--catppuccin-macchiato .ansi span.sgr4{text-decoration:underline}html.theme--catppuccin-macchiato .ansi span.sgr7{color:#24273a;background-color:#cad3f5}html.theme--catppuccin-macchiato .ansi span.sgr8{color:transparent}html.theme--catppuccin-macchiato .ansi span.sgr8 span{color:transparent}html.theme--catppuccin-macchiato .ansi span.sgr9{text-decoration:line-through}html.theme--catppuccin-macchiato .ansi span.sgr30{color:#494d64}html.theme--catppuccin-macchiato .ansi span.sgr31{color:#ed8796}html.theme--catppuccin-macchiato .ansi span.sgr32{color:#a6da95}html.theme--catppuccin-macchiato .ansi span.sgr33{color:#eed49f}html.theme--catppuccin-macchiato .ansi span.sgr34{color:#8aadf4}html.theme--catppuccin-macchiato .ansi span.sgr35{color:#f5bde6}html.theme--catppuccin-macchiato .ansi span.sgr36{color:#8bd5ca}html.theme--catppuccin-macchiato .ansi span.sgr37{color:#b8c0e0}html.theme--catppuccin-macchiato .ansi span.sgr40{background-color:#494d64}html.theme--catppuccin-macchiato .ansi span.sgr41{background-color:#ed8796}html.theme--catppuccin-macchiato .ansi span.sgr42{background-color:#a6da95}html.theme--catppuccin-macchiato .ansi span.sgr43{background-color:#eed49f}html.theme--catppuccin-macchiato .ansi span.sgr44{background-color:#8aadf4}html.theme--catppuccin-macchiato .ansi span.sgr45{background-color:#f5bde6}html.theme--catppuccin-macchiato .ansi span.sgr46{background-color:#8bd5ca}html.theme--catppuccin-macchiato .ansi span.sgr47{background-color:#b8c0e0}html.theme--catppuccin-macchiato .ansi span.sgr90{color:#5b6078}html.theme--catppuccin-macchiato .ansi span.sgr91{color:#ed8796}html.theme--catppuccin-macchiato .ansi span.sgr92{color:#a6da95}html.theme--catppuccin-macchiato .ansi span.sgr93{color:#eed49f}html.theme--catppuccin-macchiato .ansi span.sgr94{color:#8aadf4}html.theme--catppuccin-macchiato .ansi span.sgr95{color:#f5bde6}html.theme--catppuccin-macchiato .ansi span.sgr96{color:#8bd5ca}html.theme--catppuccin-macchiato .ansi span.sgr97{color:#a5adcb}html.theme--catppuccin-macchiato .ansi span.sgr100{background-color:#5b6078}html.theme--catppuccin-macchiato .ansi span.sgr101{background-color:#ed8796}html.theme--catppuccin-macchiato .ansi span.sgr102{background-color:#a6da95}html.theme--catppuccin-macchiato .ansi span.sgr103{background-color:#eed49f}html.theme--catppuccin-macchiato .ansi span.sgr104{background-color:#8aadf4}html.theme--catppuccin-macchiato .ansi span.sgr105{background-color:#f5bde6}html.theme--catppuccin-macchiato .ansi span.sgr106{background-color:#8bd5ca}html.theme--catppuccin-macchiato .ansi span.sgr107{background-color:#a5adcb}html.theme--catppuccin-macchiato code.language-julia-repl>span.hljs-meta{color:#a6da95;font-weight:bolder}html.theme--catppuccin-macchiato code .hljs{color:#cad3f5;background:#24273a}html.theme--catppuccin-macchiato code .hljs-keyword{color:#c6a0f6}html.theme--catppuccin-macchiato code .hljs-built_in{color:#ed8796}html.theme--catppuccin-macchiato code .hljs-type{color:#eed49f}html.theme--catppuccin-macchiato code .hljs-literal{color:#f5a97f}html.theme--catppuccin-macchiato code .hljs-number{color:#f5a97f}html.theme--catppuccin-macchiato code .hljs-operator{color:#8bd5ca}html.theme--catppuccin-macchiato code .hljs-punctuation{color:#b8c0e0}html.theme--catppuccin-macchiato code .hljs-property{color:#8bd5ca}html.theme--catppuccin-macchiato code .hljs-regexp{color:#f5bde6}html.theme--catppuccin-macchiato code .hljs-string{color:#a6da95}html.theme--catppuccin-macchiato code .hljs-char.escape_{color:#a6da95}html.theme--catppuccin-macchiato code .hljs-subst{color:#a5adcb}html.theme--catppuccin-macchiato code .hljs-symbol{color:#f0c6c6}html.theme--catppuccin-macchiato code .hljs-variable{color:#c6a0f6}html.theme--catppuccin-macchiato code .hljs-variable.language_{color:#c6a0f6}html.theme--catppuccin-macchiato code .hljs-variable.constant_{color:#f5a97f}html.theme--catppuccin-macchiato code .hljs-title{color:#8aadf4}html.theme--catppuccin-macchiato code .hljs-title.class_{color:#eed49f}html.theme--catppuccin-macchiato code .hljs-title.function_{color:#8aadf4}html.theme--catppuccin-macchiato code .hljs-params{color:#cad3f5}html.theme--catppuccin-macchiato code .hljs-comment{color:#5b6078}html.theme--catppuccin-macchiato code .hljs-doctag{color:#ed8796}html.theme--catppuccin-macchiato code .hljs-meta{color:#f5a97f}html.theme--catppuccin-macchiato code .hljs-section{color:#8aadf4}html.theme--catppuccin-macchiato code .hljs-tag{color:#a5adcb}html.theme--catppuccin-macchiato code .hljs-name{color:#c6a0f6}html.theme--catppuccin-macchiato code .hljs-attr{color:#8aadf4}html.theme--catppuccin-macchiato code .hljs-attribute{color:#a6da95}html.theme--catppuccin-macchiato code .hljs-bullet{color:#8bd5ca}html.theme--catppuccin-macchiato code .hljs-code{color:#a6da95}html.theme--catppuccin-macchiato code .hljs-emphasis{color:#ed8796;font-style:italic}html.theme--catppuccin-macchiato code .hljs-strong{color:#ed8796;font-weight:bold}html.theme--catppuccin-macchiato code .hljs-formula{color:#8bd5ca}html.theme--catppuccin-macchiato code .hljs-link{color:#7dc4e4;font-style:italic}html.theme--catppuccin-macchiato code .hljs-quote{color:#a6da95;font-style:italic}html.theme--catppuccin-macchiato code .hljs-selector-tag{color:#eed49f}html.theme--catppuccin-macchiato code .hljs-selector-id{color:#8aadf4}html.theme--catppuccin-macchiato code .hljs-selector-class{color:#8bd5ca}html.theme--catppuccin-macchiato code .hljs-selector-attr{color:#c6a0f6}html.theme--catppuccin-macchiato code .hljs-selector-pseudo{color:#8bd5ca}html.theme--catppuccin-macchiato code .hljs-template-tag{color:#f0c6c6}html.theme--catppuccin-macchiato code .hljs-template-variable{color:#f0c6c6}html.theme--catppuccin-macchiato code .hljs-addition{color:#a6da95;background:rgba(166,227,161,0.15)}html.theme--catppuccin-macchiato code .hljs-deletion{color:#ed8796;background:rgba(243,139,168,0.15)}html.theme--catppuccin-macchiato .search-result-link{border-radius:0.7em;transition:all 300ms}html.theme--catppuccin-macchiato .search-result-link:hover,html.theme--catppuccin-macchiato .search-result-link:focus{background-color:#363a4f}html.theme--catppuccin-macchiato .search-result-link .property-search-result-badge,html.theme--catppuccin-macchiato .search-result-link .search-filter{transition:all 300ms}html.theme--catppuccin-macchiato .search-result-link:hover .property-search-result-badge,html.theme--catppuccin-macchiato .search-result-link:hover .search-filter,html.theme--catppuccin-macchiato .search-result-link:focus .property-search-result-badge,html.theme--catppuccin-macchiato .search-result-link:focus .search-filter{color:#363a4f !important;background-color:#b7bdf8 !important}html.theme--catppuccin-macchiato .search-result-title{color:#cad3f5}html.theme--catppuccin-macchiato .search-result-highlight{background-color:#ed8796;color:#1e2030}html.theme--catppuccin-macchiato .search-divider{border-bottom:1px solid #5e6d6f50}html.theme--catppuccin-macchiato .w-100{width:100%}html.theme--catppuccin-macchiato .gap-2{gap:0.5rem}html.theme--catppuccin-macchiato .gap-4{gap:1rem} diff --git a/previews/PR4245/assets/themes/catppuccin-mocha.css b/previews/PR4245/assets/themes/catppuccin-mocha.css deleted file mode 100644 index 8b8265256087..000000000000 --- a/previews/PR4245/assets/themes/catppuccin-mocha.css +++ /dev/null @@ -1 +0,0 @@ -html.theme--catppuccin-mocha .pagination-previous,html.theme--catppuccin-mocha .pagination-next,html.theme--catppuccin-mocha .pagination-link,html.theme--catppuccin-mocha .pagination-ellipsis,html.theme--catppuccin-mocha .file-cta,html.theme--catppuccin-mocha .file-name,html.theme--catppuccin-mocha .select select,html.theme--catppuccin-mocha .textarea,html.theme--catppuccin-mocha .input,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input,html.theme--catppuccin-mocha .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:1rem;height:2.5em;justify-content:flex-start;line-height:1.5;padding-bottom:calc(0.5em - 1px);padding-left:calc(0.75em - 1px);padding-right:calc(0.75em - 1px);padding-top:calc(0.5em - 1px);position:relative;vertical-align:top}html.theme--catppuccin-mocha .pagination-previous:focus,html.theme--catppuccin-mocha .pagination-next:focus,html.theme--catppuccin-mocha .pagination-link:focus,html.theme--catppuccin-mocha .pagination-ellipsis:focus,html.theme--catppuccin-mocha .file-cta:focus,html.theme--catppuccin-mocha .file-name:focus,html.theme--catppuccin-mocha .select select:focus,html.theme--catppuccin-mocha .textarea:focus,html.theme--catppuccin-mocha .input:focus,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input:focus,html.theme--catppuccin-mocha .button:focus,html.theme--catppuccin-mocha .is-focused.pagination-previous,html.theme--catppuccin-mocha .is-focused.pagination-next,html.theme--catppuccin-mocha .is-focused.pagination-link,html.theme--catppuccin-mocha .is-focused.pagination-ellipsis,html.theme--catppuccin-mocha .is-focused.file-cta,html.theme--catppuccin-mocha .is-focused.file-name,html.theme--catppuccin-mocha .select select.is-focused,html.theme--catppuccin-mocha .is-focused.textarea,html.theme--catppuccin-mocha .is-focused.input,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--catppuccin-mocha .is-focused.button,html.theme--catppuccin-mocha .pagination-previous:active,html.theme--catppuccin-mocha .pagination-next:active,html.theme--catppuccin-mocha .pagination-link:active,html.theme--catppuccin-mocha .pagination-ellipsis:active,html.theme--catppuccin-mocha .file-cta:active,html.theme--catppuccin-mocha .file-name:active,html.theme--catppuccin-mocha .select select:active,html.theme--catppuccin-mocha .textarea:active,html.theme--catppuccin-mocha .input:active,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input:active,html.theme--catppuccin-mocha .button:active,html.theme--catppuccin-mocha .is-active.pagination-previous,html.theme--catppuccin-mocha .is-active.pagination-next,html.theme--catppuccin-mocha .is-active.pagination-link,html.theme--catppuccin-mocha .is-active.pagination-ellipsis,html.theme--catppuccin-mocha .is-active.file-cta,html.theme--catppuccin-mocha .is-active.file-name,html.theme--catppuccin-mocha .select select.is-active,html.theme--catppuccin-mocha .is-active.textarea,html.theme--catppuccin-mocha .is-active.input,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-active,html.theme--catppuccin-mocha .is-active.button{outline:none}html.theme--catppuccin-mocha .pagination-previous[disabled],html.theme--catppuccin-mocha .pagination-next[disabled],html.theme--catppuccin-mocha .pagination-link[disabled],html.theme--catppuccin-mocha .pagination-ellipsis[disabled],html.theme--catppuccin-mocha .file-cta[disabled],html.theme--catppuccin-mocha .file-name[disabled],html.theme--catppuccin-mocha .select select[disabled],html.theme--catppuccin-mocha .textarea[disabled],html.theme--catppuccin-mocha .input[disabled],html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input[disabled],html.theme--catppuccin-mocha .button[disabled],fieldset[disabled] html.theme--catppuccin-mocha .pagination-previous,html.theme--catppuccin-mocha fieldset[disabled] .pagination-previous,fieldset[disabled] html.theme--catppuccin-mocha .pagination-next,html.theme--catppuccin-mocha fieldset[disabled] .pagination-next,fieldset[disabled] html.theme--catppuccin-mocha .pagination-link,html.theme--catppuccin-mocha fieldset[disabled] .pagination-link,fieldset[disabled] html.theme--catppuccin-mocha .pagination-ellipsis,html.theme--catppuccin-mocha fieldset[disabled] .pagination-ellipsis,fieldset[disabled] html.theme--catppuccin-mocha .file-cta,html.theme--catppuccin-mocha fieldset[disabled] .file-cta,fieldset[disabled] html.theme--catppuccin-mocha .file-name,html.theme--catppuccin-mocha fieldset[disabled] .file-name,fieldset[disabled] html.theme--catppuccin-mocha .select select,fieldset[disabled] html.theme--catppuccin-mocha .textarea,fieldset[disabled] html.theme--catppuccin-mocha .input,fieldset[disabled] html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input,html.theme--catppuccin-mocha fieldset[disabled] .select select,html.theme--catppuccin-mocha .select fieldset[disabled] select,html.theme--catppuccin-mocha fieldset[disabled] .textarea,html.theme--catppuccin-mocha fieldset[disabled] .input,html.theme--catppuccin-mocha fieldset[disabled] #documenter .docs-sidebar form.docs-search>input,html.theme--catppuccin-mocha #documenter .docs-sidebar fieldset[disabled] form.docs-search>input,fieldset[disabled] html.theme--catppuccin-mocha .button,html.theme--catppuccin-mocha fieldset[disabled] .button{cursor:not-allowed}html.theme--catppuccin-mocha .tabs,html.theme--catppuccin-mocha .pagination-previous,html.theme--catppuccin-mocha .pagination-next,html.theme--catppuccin-mocha .pagination-link,html.theme--catppuccin-mocha .pagination-ellipsis,html.theme--catppuccin-mocha .breadcrumb,html.theme--catppuccin-mocha .file,html.theme--catppuccin-mocha .button,.is-unselectable{-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}html.theme--catppuccin-mocha .navbar-link:not(.is-arrowless)::after,html.theme--catppuccin-mocha .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--catppuccin-mocha .admonition:not(:last-child),html.theme--catppuccin-mocha .tabs:not(:last-child),html.theme--catppuccin-mocha .pagination:not(:last-child),html.theme--catppuccin-mocha .message:not(:last-child),html.theme--catppuccin-mocha .level:not(:last-child),html.theme--catppuccin-mocha .breadcrumb:not(:last-child),html.theme--catppuccin-mocha .block:not(:last-child),html.theme--catppuccin-mocha .title:not(:last-child),html.theme--catppuccin-mocha .subtitle:not(:last-child),html.theme--catppuccin-mocha .table-container:not(:last-child),html.theme--catppuccin-mocha .table:not(:last-child),html.theme--catppuccin-mocha .progress:not(:last-child),html.theme--catppuccin-mocha .notification:not(:last-child),html.theme--catppuccin-mocha .content:not(:last-child),html.theme--catppuccin-mocha .box:not(:last-child){margin-bottom:1.5rem}html.theme--catppuccin-mocha .modal-close,html.theme--catppuccin-mocha .delete{-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-moz-appearance:none;-webkit-appearance:none;background-color:rgba(10,10,10,0.2);border:none;border-radius:9999px;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--catppuccin-mocha .modal-close::before,html.theme--catppuccin-mocha .delete::before,html.theme--catppuccin-mocha .modal-close::after,html.theme--catppuccin-mocha .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--catppuccin-mocha .modal-close::before,html.theme--catppuccin-mocha .delete::before{height:2px;width:50%}html.theme--catppuccin-mocha .modal-close::after,html.theme--catppuccin-mocha .delete::after{height:50%;width:2px}html.theme--catppuccin-mocha .modal-close:hover,html.theme--catppuccin-mocha .delete:hover,html.theme--catppuccin-mocha .modal-close:focus,html.theme--catppuccin-mocha .delete:focus{background-color:rgba(10,10,10,0.3)}html.theme--catppuccin-mocha .modal-close:active,html.theme--catppuccin-mocha .delete:active{background-color:rgba(10,10,10,0.4)}html.theme--catppuccin-mocha .is-small.modal-close,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.modal-close,html.theme--catppuccin-mocha .is-small.delete,html.theme--catppuccin-mocha #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--catppuccin-mocha .is-medium.modal-close,html.theme--catppuccin-mocha .is-medium.delete{height:24px;max-height:24px;max-width:24px;min-height:24px;min-width:24px;width:24px}html.theme--catppuccin-mocha .is-large.modal-close,html.theme--catppuccin-mocha .is-large.delete{height:32px;max-height:32px;max-width:32px;min-height:32px;min-width:32px;width:32px}html.theme--catppuccin-mocha .control.is-loading::after,html.theme--catppuccin-mocha .select.is-loading::after,html.theme--catppuccin-mocha .loader,html.theme--catppuccin-mocha .button.is-loading::after{animation:spinAround 500ms infinite linear;border:2px solid #7f849c;border-radius:9999px;border-right-color:transparent;border-top-color:transparent;content:"";display:block;height:1em;position:relative;width:1em}html.theme--catppuccin-mocha .hero-video,html.theme--catppuccin-mocha .modal-background,html.theme--catppuccin-mocha .modal,html.theme--catppuccin-mocha .image.is-square img,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-square img,html.theme--catppuccin-mocha .image.is-square .has-ratio,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-square .has-ratio,html.theme--catppuccin-mocha .image.is-1by1 img,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-1by1 img,html.theme--catppuccin-mocha .image.is-1by1 .has-ratio,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-1by1 .has-ratio,html.theme--catppuccin-mocha .image.is-5by4 img,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-5by4 img,html.theme--catppuccin-mocha .image.is-5by4 .has-ratio,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-5by4 .has-ratio,html.theme--catppuccin-mocha .image.is-4by3 img,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-4by3 img,html.theme--catppuccin-mocha .image.is-4by3 .has-ratio,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-4by3 .has-ratio,html.theme--catppuccin-mocha .image.is-3by2 img,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-3by2 img,html.theme--catppuccin-mocha .image.is-3by2 .has-ratio,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-3by2 .has-ratio,html.theme--catppuccin-mocha .image.is-5by3 img,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-5by3 img,html.theme--catppuccin-mocha .image.is-5by3 .has-ratio,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-5by3 .has-ratio,html.theme--catppuccin-mocha .image.is-16by9 img,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-16by9 img,html.theme--catppuccin-mocha .image.is-16by9 .has-ratio,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-16by9 .has-ratio,html.theme--catppuccin-mocha .image.is-2by1 img,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-2by1 img,html.theme--catppuccin-mocha .image.is-2by1 .has-ratio,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-2by1 .has-ratio,html.theme--catppuccin-mocha .image.is-3by1 img,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-3by1 img,html.theme--catppuccin-mocha .image.is-3by1 .has-ratio,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-3by1 .has-ratio,html.theme--catppuccin-mocha .image.is-4by5 img,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-4by5 img,html.theme--catppuccin-mocha .image.is-4by5 .has-ratio,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-4by5 .has-ratio,html.theme--catppuccin-mocha .image.is-3by4 img,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-3by4 img,html.theme--catppuccin-mocha .image.is-3by4 .has-ratio,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-3by4 .has-ratio,html.theme--catppuccin-mocha .image.is-2by3 img,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-2by3 img,html.theme--catppuccin-mocha .image.is-2by3 .has-ratio,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-2by3 .has-ratio,html.theme--catppuccin-mocha .image.is-3by5 img,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-3by5 img,html.theme--catppuccin-mocha .image.is-3by5 .has-ratio,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-3by5 .has-ratio,html.theme--catppuccin-mocha .image.is-9by16 img,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-9by16 img,html.theme--catppuccin-mocha .image.is-9by16 .has-ratio,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-9by16 .has-ratio,html.theme--catppuccin-mocha .image.is-1by2 img,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-1by2 img,html.theme--catppuccin-mocha .image.is-1by2 .has-ratio,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-1by2 .has-ratio,html.theme--catppuccin-mocha .image.is-1by3 img,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-1by3 img,html.theme--catppuccin-mocha .image.is-1by3 .has-ratio,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-1by3 .has-ratio,.is-overlay{bottom:0;left:0;position:absolute;right:0;top:0}html.theme--catppuccin-mocha .navbar-burger{-moz-appearance:none;-webkit-appearance:none;appearance:none;background:none;border:none;color:currentColor;font-family:inherit;font-size:1em;margin:0;padding:0}/*! minireset.css v0.0.6 | 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,video{height:auto;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:inherit}.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:#313244 !important}a.has-text-dark:hover,a.has-text-dark:focus{color:#1c1c26 !important}.has-background-dark{background-color:#313244 !important}.has-text-primary{color:#89b4fa !important}a.has-text-primary:hover,a.has-text-primary:focus{color:#5895f8 !important}.has-background-primary{background-color:#89b4fa !important}.has-text-primary-light{color:#ebf3fe !important}a.has-text-primary-light:hover,a.has-text-primary-light:focus{color:#bbd3fc !important}.has-background-primary-light{background-color:#ebf3fe !important}.has-text-primary-dark{color:#063c93 !important}a.has-text-primary-dark:hover,a.has-text-primary-dark:focus{color:#0850c4 !important}.has-background-primary-dark{background-color:#063c93 !important}.has-text-link{color:#89b4fa !important}a.has-text-link:hover,a.has-text-link:focus{color:#5895f8 !important}.has-background-link{background-color:#89b4fa !important}.has-text-link-light{color:#ebf3fe !important}a.has-text-link-light:hover,a.has-text-link-light:focus{color:#bbd3fc !important}.has-background-link-light{background-color:#ebf3fe !important}.has-text-link-dark{color:#063c93 !important}a.has-text-link-dark:hover,a.has-text-link-dark:focus{color:#0850c4 !important}.has-background-link-dark{background-color:#063c93 !important}.has-text-info{color:#94e2d5 !important}a.has-text-info:hover,a.has-text-info:focus{color:#6cd7c5 !important}.has-background-info{background-color:#94e2d5 !important}.has-text-info-light{color:#effbf9 !important}a.has-text-info-light:hover,a.has-text-info-light:focus{color:#c7f0e9 !important}.has-background-info-light{background-color:#effbf9 !important}.has-text-info-dark{color:#207466 !important}a.has-text-info-dark:hover,a.has-text-info-dark:focus{color:#2a9c89 !important}.has-background-info-dark{background-color:#207466 !important}.has-text-success{color:#a6e3a1 !important}a.has-text-success:hover,a.has-text-success:focus{color:#81d77a !important}.has-background-success{background-color:#a6e3a1 !important}.has-text-success-light{color:#f0faef !important}a.has-text-success-light:hover,a.has-text-success-light:focus{color:#cbefc8 !important}.has-background-success-light{background-color:#f0faef !important}.has-text-success-dark{color:#287222 !important}a.has-text-success-dark:hover,a.has-text-success-dark:focus{color:#36992e !important}.has-background-success-dark{background-color:#287222 !important}.has-text-warning{color:#f9e2af !important}a.has-text-warning:hover,a.has-text-warning:focus{color:#f5d180 !important}.has-background-warning{background-color:#f9e2af !important}.has-text-warning-light{color:#fef8ec !important}a.has-text-warning-light:hover,a.has-text-warning-light:focus{color:#fae7bd !important}.has-background-warning-light{background-color:#fef8ec !important}.has-text-warning-dark{color:#8a620a !important}a.has-text-warning-dark:hover,a.has-text-warning-dark:focus{color:#b9840e !important}.has-background-warning-dark{background-color:#8a620a !important}.has-text-danger{color:#f38ba8 !important}a.has-text-danger:hover,a.has-text-danger:focus{color:#ee5d85 !important}.has-background-danger{background-color:#f38ba8 !important}.has-text-danger-light{color:#fdedf1 !important}a.has-text-danger-light:hover,a.has-text-danger-light:focus{color:#f8bece !important}.has-background-danger-light{background-color:#fdedf1 !important}.has-text-danger-dark{color:#991036 !important}a.has-text-danger-dark:hover,a.has-text-danger-dark:focus{color:#c71546 !important}.has-background-danger-dark{background-color:#991036 !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:#313244 !important}.has-background-grey-darker{background-color:#313244 !important}.has-text-grey-dark{color:#45475a !important}.has-background-grey-dark{background-color:#45475a !important}.has-text-grey{color:#585b70 !important}.has-background-grey{background-color:#585b70 !important}.has-text-grey-light{color:#6c7086 !important}.has-background-grey-light{background-color:#6c7086 !important}.has-text-grey-lighter{color:#7f849c !important}.has-background-grey-lighter{background-color:#7f849c !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}.is-flex-direction-row{flex-direction:row !important}.is-flex-direction-row-reverse{flex-direction:row-reverse !important}.is-flex-direction-column{flex-direction:column !important}.is-flex-direction-column-reverse{flex-direction:column-reverse !important}.is-flex-wrap-nowrap{flex-wrap:nowrap !important}.is-flex-wrap-wrap{flex-wrap:wrap !important}.is-flex-wrap-wrap-reverse{flex-wrap:wrap-reverse !important}.is-justify-content-flex-start{justify-content:flex-start !important}.is-justify-content-flex-end{justify-content:flex-end !important}.is-justify-content-center{justify-content:center !important}.is-justify-content-space-between{justify-content:space-between !important}.is-justify-content-space-around{justify-content:space-around !important}.is-justify-content-space-evenly{justify-content:space-evenly !important}.is-justify-content-start{justify-content:start !important}.is-justify-content-end{justify-content:end !important}.is-justify-content-left{justify-content:left !important}.is-justify-content-right{justify-content:right !important}.is-align-content-flex-start{align-content:flex-start !important}.is-align-content-flex-end{align-content:flex-end !important}.is-align-content-center{align-content:center !important}.is-align-content-space-between{align-content:space-between !important}.is-align-content-space-around{align-content:space-around !important}.is-align-content-space-evenly{align-content:space-evenly !important}.is-align-content-stretch{align-content:stretch !important}.is-align-content-start{align-content:start !important}.is-align-content-end{align-content:end !important}.is-align-content-baseline{align-content:baseline !important}.is-align-items-stretch{align-items:stretch !important}.is-align-items-flex-start{align-items:flex-start !important}.is-align-items-flex-end{align-items:flex-end !important}.is-align-items-center{align-items:center !important}.is-align-items-baseline{align-items:baseline !important}.is-align-items-start{align-items:start !important}.is-align-items-end{align-items:end !important}.is-align-items-self-start{align-items:self-start !important}.is-align-items-self-end{align-items:self-end !important}.is-align-self-auto{align-self:auto !important}.is-align-self-flex-start{align-self:flex-start !important}.is-align-self-flex-end{align-self:flex-end !important}.is-align-self-center{align-self:center !important}.is-align-self-baseline{align-self:baseline !important}.is-align-self-stretch{align-self:stretch !important}.is-flex-grow-0{flex-grow:0 !important}.is-flex-grow-1{flex-grow:1 !important}.is-flex-grow-2{flex-grow:2 !important}.is-flex-grow-3{flex-grow:3 !important}.is-flex-grow-4{flex-grow:4 !important}.is-flex-grow-5{flex-grow:5 !important}.is-flex-shrink-0{flex-shrink:0 !important}.is-flex-shrink-1{flex-shrink:1 !important}.is-flex-shrink-2{flex-shrink:2 !important}.is-flex-shrink-3{flex-shrink:3 !important}.is-flex-shrink-4{flex-shrink:4 !important}.is-flex-shrink-5{flex-shrink:5 !important}.is-clearfix::after{clear:both;content:" ";display:table}.is-pulled-left{float:left !important}.is-pulled-right{float:right !important}.is-radiusless{border-radius:0 !important}.is-shadowless{box-shadow:none !important}.is-clickable{cursor:pointer !important;pointer-events:all !important}.is-clipped{overflow:hidden !important}.is-relative{position:relative !important}.is-marginless{margin:0 !important}.is-paddingless{padding:0 !important}.m-0{margin:0 !important}.mt-0{margin-top:0 !important}.mr-0{margin-right:0 !important}.mb-0{margin-bottom:0 !important}.ml-0{margin-left:0 !important}.mx-0{margin-left:0 !important;margin-right:0 !important}.my-0{margin-top:0 !important;margin-bottom:0 !important}.m-1{margin:.25rem !important}.mt-1{margin-top:.25rem !important}.mr-1{margin-right:.25rem !important}.mb-1{margin-bottom:.25rem !important}.ml-1{margin-left:.25rem !important}.mx-1{margin-left:.25rem !important;margin-right:.25rem !important}.my-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.m-2{margin:.5rem !important}.mt-2{margin-top:.5rem !important}.mr-2{margin-right:.5rem !important}.mb-2{margin-bottom:.5rem !important}.ml-2{margin-left:.5rem !important}.mx-2{margin-left:.5rem !important;margin-right:.5rem !important}.my-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.m-3{margin:.75rem !important}.mt-3{margin-top:.75rem !important}.mr-3{margin-right:.75rem !important}.mb-3{margin-bottom:.75rem !important}.ml-3{margin-left:.75rem !important}.mx-3{margin-left:.75rem !important;margin-right:.75rem !important}.my-3{margin-top:.75rem !important;margin-bottom:.75rem !important}.m-4{margin:1rem !important}.mt-4{margin-top:1rem !important}.mr-4{margin-right:1rem !important}.mb-4{margin-bottom:1rem !important}.ml-4{margin-left:1rem !important}.mx-4{margin-left:1rem !important;margin-right:1rem !important}.my-4{margin-top:1rem !important;margin-bottom:1rem !important}.m-5{margin:1.5rem !important}.mt-5{margin-top:1.5rem !important}.mr-5{margin-right:1.5rem !important}.mb-5{margin-bottom:1.5rem !important}.ml-5{margin-left:1.5rem !important}.mx-5{margin-left:1.5rem !important;margin-right:1.5rem !important}.my-5{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.m-6{margin:3rem !important}.mt-6{margin-top:3rem !important}.mr-6{margin-right:3rem !important}.mb-6{margin-bottom:3rem !important}.ml-6{margin-left:3rem !important}.mx-6{margin-left:3rem !important;margin-right:3rem !important}.my-6{margin-top:3rem !important;margin-bottom:3rem !important}.m-auto{margin:auto !important}.mt-auto{margin-top:auto !important}.mr-auto{margin-right:auto !important}.mb-auto{margin-bottom:auto !important}.ml-auto{margin-left:auto !important}.mx-auto{margin-left:auto !important;margin-right:auto !important}.my-auto{margin-top:auto !important;margin-bottom:auto !important}.p-0{padding:0 !important}.pt-0{padding-top:0 !important}.pr-0{padding-right:0 !important}.pb-0{padding-bottom:0 !important}.pl-0{padding-left:0 !important}.px-0{padding-left:0 !important;padding-right:0 !important}.py-0{padding-top:0 !important;padding-bottom:0 !important}.p-1{padding:.25rem !important}.pt-1{padding-top:.25rem !important}.pr-1{padding-right:.25rem !important}.pb-1{padding-bottom:.25rem !important}.pl-1{padding-left:.25rem !important}.px-1{padding-left:.25rem !important;padding-right:.25rem !important}.py-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.p-2{padding:.5rem !important}.pt-2{padding-top:.5rem !important}.pr-2{padding-right:.5rem !important}.pb-2{padding-bottom:.5rem !important}.pl-2{padding-left:.5rem !important}.px-2{padding-left:.5rem !important;padding-right:.5rem !important}.py-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.p-3{padding:.75rem !important}.pt-3{padding-top:.75rem !important}.pr-3{padding-right:.75rem !important}.pb-3{padding-bottom:.75rem !important}.pl-3{padding-left:.75rem !important}.px-3{padding-left:.75rem !important;padding-right:.75rem !important}.py-3{padding-top:.75rem !important;padding-bottom:.75rem !important}.p-4{padding:1rem !important}.pt-4{padding-top:1rem !important}.pr-4{padding-right:1rem !important}.pb-4{padding-bottom:1rem !important}.pl-4{padding-left:1rem !important}.px-4{padding-left:1rem !important;padding-right:1rem !important}.py-4{padding-top:1rem !important;padding-bottom:1rem !important}.p-5{padding:1.5rem !important}.pt-5{padding-top:1.5rem !important}.pr-5{padding-right:1.5rem !important}.pb-5{padding-bottom:1.5rem !important}.pl-5{padding-left:1.5rem !important}.px-5{padding-left:1.5rem !important;padding-right:1.5rem !important}.py-5{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.p-6{padding:3rem !important}.pt-6{padding-top:3rem !important}.pr-6{padding-right:3rem !important}.pb-6{padding-bottom:3rem !important}.pl-6{padding-left:3rem !important}.px-6{padding-left:3rem !important;padding-right:3rem !important}.py-6{padding-top:3rem !important;padding-bottom:3rem !important}.p-auto{padding:auto !important}.pt-auto{padding-top:auto !important}.pr-auto{padding-right:auto !important}.pb-auto{padding-bottom:auto !important}.pl-auto{padding-left:auto !important}.px-auto{padding-left:auto !important;padding-right:auto !important}.py-auto{padding-top:auto !important;padding-bottom:auto !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,html.theme--catppuccin-mocha .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}.is-underlined{text-decoration:underline !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}}html.theme--catppuccin-mocha html{background-color:#1e1e2e;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--catppuccin-mocha article,html.theme--catppuccin-mocha aside,html.theme--catppuccin-mocha figure,html.theme--catppuccin-mocha footer,html.theme--catppuccin-mocha header,html.theme--catppuccin-mocha hgroup,html.theme--catppuccin-mocha section{display:block}html.theme--catppuccin-mocha body,html.theme--catppuccin-mocha button,html.theme--catppuccin-mocha input,html.theme--catppuccin-mocha optgroup,html.theme--catppuccin-mocha select,html.theme--catppuccin-mocha textarea{font-family:"Lato Medium",-apple-system,BlinkMacSystemFont,"Segoe UI","Helvetica Neue","Helvetica","Arial",sans-serif}html.theme--catppuccin-mocha code,html.theme--catppuccin-mocha 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--catppuccin-mocha body{color:#cdd6f4;font-size:1em;font-weight:400;line-height:1.5}html.theme--catppuccin-mocha a{color:#89b4fa;cursor:pointer;text-decoration:none}html.theme--catppuccin-mocha a strong{color:currentColor}html.theme--catppuccin-mocha a:hover{color:#89dceb}html.theme--catppuccin-mocha code{background-color:#181825;color:#cdd6f4;font-size:.875em;font-weight:normal;padding:.1em}html.theme--catppuccin-mocha hr{background-color:#181825;border:none;display:block;height:2px;margin:1.5rem 0}html.theme--catppuccin-mocha img{height:auto;max-width:100%}html.theme--catppuccin-mocha input[type="checkbox"],html.theme--catppuccin-mocha input[type="radio"]{vertical-align:baseline}html.theme--catppuccin-mocha small{font-size:.875em}html.theme--catppuccin-mocha span{font-style:inherit;font-weight:inherit}html.theme--catppuccin-mocha strong{color:#b8c5ef;font-weight:700}html.theme--catppuccin-mocha fieldset{border:none}html.theme--catppuccin-mocha pre{-webkit-overflow-scrolling:touch;background-color:#181825;color:#cdd6f4;font-size:.875em;overflow-x:auto;padding:1.25rem 1.5rem;white-space:pre;word-wrap:normal}html.theme--catppuccin-mocha pre code{background-color:transparent;color:currentColor;font-size:1em;padding:0}html.theme--catppuccin-mocha table td,html.theme--catppuccin-mocha table th{vertical-align:top}html.theme--catppuccin-mocha table td:not([align]),html.theme--catppuccin-mocha table th:not([align]){text-align:inherit}html.theme--catppuccin-mocha table th{color:#b8c5ef}html.theme--catppuccin-mocha .box{background-color:#45475a;border-radius:8px;box-shadow:none;color:#cdd6f4;display:block;padding:1.25rem}html.theme--catppuccin-mocha a.box:hover,html.theme--catppuccin-mocha a.box:focus{box-shadow:0 0.5em 1em -0.125em rgba(10,10,10,0.1),0 0 0 1px #89b4fa}html.theme--catppuccin-mocha a.box:active{box-shadow:inset 0 1px 2px rgba(10,10,10,0.2),0 0 0 1px #89b4fa}html.theme--catppuccin-mocha .button{background-color:#181825;border-color:#363653;border-width:1px;color:#89b4fa;cursor:pointer;justify-content:center;padding-bottom:calc(0.5em - 1px);padding-left:1em;padding-right:1em;padding-top:calc(0.5em - 1px);text-align:center;white-space:nowrap}html.theme--catppuccin-mocha .button strong{color:inherit}html.theme--catppuccin-mocha .button .icon,html.theme--catppuccin-mocha .button .icon.is-small,html.theme--catppuccin-mocha .button #documenter .docs-sidebar form.docs-search>input.icon,html.theme--catppuccin-mocha #documenter .docs-sidebar .button form.docs-search>input.icon,html.theme--catppuccin-mocha .button .icon.is-medium,html.theme--catppuccin-mocha .button .icon.is-large{height:1.5em;width:1.5em}html.theme--catppuccin-mocha .button .icon:first-child:not(:last-child){margin-left:calc(-0.5em - 1px);margin-right:.25em}html.theme--catppuccin-mocha .button .icon:last-child:not(:first-child){margin-left:.25em;margin-right:calc(-0.5em - 1px)}html.theme--catppuccin-mocha .button .icon:first-child:last-child{margin-left:calc(-0.5em - 1px);margin-right:calc(-0.5em - 1px)}html.theme--catppuccin-mocha .button:hover,html.theme--catppuccin-mocha .button.is-hovered{border-color:#6c7086;color:#b8c5ef}html.theme--catppuccin-mocha .button:focus,html.theme--catppuccin-mocha .button.is-focused{border-color:#6c7086;color:#71a4f9}html.theme--catppuccin-mocha .button:focus:not(:active),html.theme--catppuccin-mocha .button.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(137,180,250,0.25)}html.theme--catppuccin-mocha .button:active,html.theme--catppuccin-mocha .button.is-active{border-color:#45475a;color:#b8c5ef}html.theme--catppuccin-mocha .button.is-text{background-color:transparent;border-color:transparent;color:#cdd6f4;text-decoration:underline}html.theme--catppuccin-mocha .button.is-text:hover,html.theme--catppuccin-mocha .button.is-text.is-hovered,html.theme--catppuccin-mocha .button.is-text:focus,html.theme--catppuccin-mocha .button.is-text.is-focused{background-color:#181825;color:#b8c5ef}html.theme--catppuccin-mocha .button.is-text:active,html.theme--catppuccin-mocha .button.is-text.is-active{background-color:#0e0e16;color:#b8c5ef}html.theme--catppuccin-mocha .button.is-text[disabled],fieldset[disabled] html.theme--catppuccin-mocha .button.is-text{background-color:transparent;border-color:transparent;box-shadow:none}html.theme--catppuccin-mocha .button.is-ghost{background:none;border-color:rgba(0,0,0,0);color:#89b4fa;text-decoration:none}html.theme--catppuccin-mocha .button.is-ghost:hover,html.theme--catppuccin-mocha .button.is-ghost.is-hovered{color:#89b4fa;text-decoration:underline}html.theme--catppuccin-mocha .button.is-white{background-color:#fff;border-color:transparent;color:#0a0a0a}html.theme--catppuccin-mocha .button.is-white:hover,html.theme--catppuccin-mocha .button.is-white.is-hovered{background-color:#f9f9f9;border-color:transparent;color:#0a0a0a}html.theme--catppuccin-mocha .button.is-white:focus,html.theme--catppuccin-mocha .button.is-white.is-focused{border-color:transparent;color:#0a0a0a}html.theme--catppuccin-mocha .button.is-white:focus:not(:active),html.theme--catppuccin-mocha .button.is-white.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(255,255,255,0.25)}html.theme--catppuccin-mocha .button.is-white:active,html.theme--catppuccin-mocha .button.is-white.is-active{background-color:#f2f2f2;border-color:transparent;color:#0a0a0a}html.theme--catppuccin-mocha .button.is-white[disabled],fieldset[disabled] html.theme--catppuccin-mocha .button.is-white{background-color:#fff;border-color:#fff;box-shadow:none}html.theme--catppuccin-mocha .button.is-white.is-inverted{background-color:#0a0a0a;color:#fff}html.theme--catppuccin-mocha .button.is-white.is-inverted:hover,html.theme--catppuccin-mocha .button.is-white.is-inverted.is-hovered{background-color:#000}html.theme--catppuccin-mocha .button.is-white.is-inverted[disabled],fieldset[disabled] html.theme--catppuccin-mocha .button.is-white.is-inverted{background-color:#0a0a0a;border-color:transparent;box-shadow:none;color:#fff}html.theme--catppuccin-mocha .button.is-white.is-loading::after{border-color:transparent transparent #0a0a0a #0a0a0a !important}html.theme--catppuccin-mocha .button.is-white.is-outlined{background-color:transparent;border-color:#fff;color:#fff}html.theme--catppuccin-mocha .button.is-white.is-outlined:hover,html.theme--catppuccin-mocha .button.is-white.is-outlined.is-hovered,html.theme--catppuccin-mocha .button.is-white.is-outlined:focus,html.theme--catppuccin-mocha .button.is-white.is-outlined.is-focused{background-color:#fff;border-color:#fff;color:#0a0a0a}html.theme--catppuccin-mocha .button.is-white.is-outlined.is-loading::after{border-color:transparent transparent #fff #fff !important}html.theme--catppuccin-mocha .button.is-white.is-outlined.is-loading:hover::after,html.theme--catppuccin-mocha .button.is-white.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-mocha .button.is-white.is-outlined.is-loading:focus::after,html.theme--catppuccin-mocha .button.is-white.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #0a0a0a #0a0a0a !important}html.theme--catppuccin-mocha .button.is-white.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-mocha .button.is-white.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}html.theme--catppuccin-mocha .button.is-white.is-inverted.is-outlined{background-color:transparent;border-color:#0a0a0a;color:#0a0a0a}html.theme--catppuccin-mocha .button.is-white.is-inverted.is-outlined:hover,html.theme--catppuccin-mocha .button.is-white.is-inverted.is-outlined.is-hovered,html.theme--catppuccin-mocha .button.is-white.is-inverted.is-outlined:focus,html.theme--catppuccin-mocha .button.is-white.is-inverted.is-outlined.is-focused{background-color:#0a0a0a;color:#fff}html.theme--catppuccin-mocha .button.is-white.is-inverted.is-outlined.is-loading:hover::after,html.theme--catppuccin-mocha .button.is-white.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-mocha .button.is-white.is-inverted.is-outlined.is-loading:focus::after,html.theme--catppuccin-mocha .button.is-white.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #fff #fff !important}html.theme--catppuccin-mocha .button.is-white.is-inverted.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-mocha .button.is-white.is-inverted.is-outlined{background-color:transparent;border-color:#0a0a0a;box-shadow:none;color:#0a0a0a}html.theme--catppuccin-mocha .button.is-black{background-color:#0a0a0a;border-color:transparent;color:#fff}html.theme--catppuccin-mocha .button.is-black:hover,html.theme--catppuccin-mocha .button.is-black.is-hovered{background-color:#040404;border-color:transparent;color:#fff}html.theme--catppuccin-mocha .button.is-black:focus,html.theme--catppuccin-mocha .button.is-black.is-focused{border-color:transparent;color:#fff}html.theme--catppuccin-mocha .button.is-black:focus:not(:active),html.theme--catppuccin-mocha .button.is-black.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(10,10,10,0.25)}html.theme--catppuccin-mocha .button.is-black:active,html.theme--catppuccin-mocha .button.is-black.is-active{background-color:#000;border-color:transparent;color:#fff}html.theme--catppuccin-mocha .button.is-black[disabled],fieldset[disabled] html.theme--catppuccin-mocha .button.is-black{background-color:#0a0a0a;border-color:#0a0a0a;box-shadow:none}html.theme--catppuccin-mocha .button.is-black.is-inverted{background-color:#fff;color:#0a0a0a}html.theme--catppuccin-mocha .button.is-black.is-inverted:hover,html.theme--catppuccin-mocha .button.is-black.is-inverted.is-hovered{background-color:#f2f2f2}html.theme--catppuccin-mocha .button.is-black.is-inverted[disabled],fieldset[disabled] html.theme--catppuccin-mocha .button.is-black.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#0a0a0a}html.theme--catppuccin-mocha .button.is-black.is-loading::after{border-color:transparent transparent #fff #fff !important}html.theme--catppuccin-mocha .button.is-black.is-outlined{background-color:transparent;border-color:#0a0a0a;color:#0a0a0a}html.theme--catppuccin-mocha .button.is-black.is-outlined:hover,html.theme--catppuccin-mocha .button.is-black.is-outlined.is-hovered,html.theme--catppuccin-mocha .button.is-black.is-outlined:focus,html.theme--catppuccin-mocha .button.is-black.is-outlined.is-focused{background-color:#0a0a0a;border-color:#0a0a0a;color:#fff}html.theme--catppuccin-mocha .button.is-black.is-outlined.is-loading::after{border-color:transparent transparent #0a0a0a #0a0a0a !important}html.theme--catppuccin-mocha .button.is-black.is-outlined.is-loading:hover::after,html.theme--catppuccin-mocha .button.is-black.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-mocha .button.is-black.is-outlined.is-loading:focus::after,html.theme--catppuccin-mocha .button.is-black.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #fff #fff !important}html.theme--catppuccin-mocha .button.is-black.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-mocha .button.is-black.is-outlined{background-color:transparent;border-color:#0a0a0a;box-shadow:none;color:#0a0a0a}html.theme--catppuccin-mocha .button.is-black.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}html.theme--catppuccin-mocha .button.is-black.is-inverted.is-outlined:hover,html.theme--catppuccin-mocha .button.is-black.is-inverted.is-outlined.is-hovered,html.theme--catppuccin-mocha .button.is-black.is-inverted.is-outlined:focus,html.theme--catppuccin-mocha .button.is-black.is-inverted.is-outlined.is-focused{background-color:#fff;color:#0a0a0a}html.theme--catppuccin-mocha .button.is-black.is-inverted.is-outlined.is-loading:hover::after,html.theme--catppuccin-mocha .button.is-black.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-mocha .button.is-black.is-inverted.is-outlined.is-loading:focus::after,html.theme--catppuccin-mocha .button.is-black.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #0a0a0a #0a0a0a !important}html.theme--catppuccin-mocha .button.is-black.is-inverted.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-mocha .button.is-black.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}html.theme--catppuccin-mocha .button.is-light{background-color:#f5f5f5;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .button.is-light:hover,html.theme--catppuccin-mocha .button.is-light.is-hovered{background-color:#eee;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .button.is-light:focus,html.theme--catppuccin-mocha .button.is-light.is-focused{border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .button.is-light:focus:not(:active),html.theme--catppuccin-mocha .button.is-light.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(245,245,245,0.25)}html.theme--catppuccin-mocha .button.is-light:active,html.theme--catppuccin-mocha .button.is-light.is-active{background-color:#e8e8e8;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .button.is-light[disabled],fieldset[disabled] html.theme--catppuccin-mocha .button.is-light{background-color:#f5f5f5;border-color:#f5f5f5;box-shadow:none}html.theme--catppuccin-mocha .button.is-light.is-inverted{background-color:rgba(0,0,0,0.7);color:#f5f5f5}html.theme--catppuccin-mocha .button.is-light.is-inverted:hover,html.theme--catppuccin-mocha .button.is-light.is-inverted.is-hovered{background-color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .button.is-light.is-inverted[disabled],fieldset[disabled] html.theme--catppuccin-mocha .button.is-light.is-inverted{background-color:rgba(0,0,0,0.7);border-color:transparent;box-shadow:none;color:#f5f5f5}html.theme--catppuccin-mocha .button.is-light.is-loading::after{border-color:transparent transparent rgba(0,0,0,0.7) rgba(0,0,0,0.7) !important}html.theme--catppuccin-mocha .button.is-light.is-outlined{background-color:transparent;border-color:#f5f5f5;color:#f5f5f5}html.theme--catppuccin-mocha .button.is-light.is-outlined:hover,html.theme--catppuccin-mocha .button.is-light.is-outlined.is-hovered,html.theme--catppuccin-mocha .button.is-light.is-outlined:focus,html.theme--catppuccin-mocha .button.is-light.is-outlined.is-focused{background-color:#f5f5f5;border-color:#f5f5f5;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .button.is-light.is-outlined.is-loading::after{border-color:transparent transparent #f5f5f5 #f5f5f5 !important}html.theme--catppuccin-mocha .button.is-light.is-outlined.is-loading:hover::after,html.theme--catppuccin-mocha .button.is-light.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-mocha .button.is-light.is-outlined.is-loading:focus::after,html.theme--catppuccin-mocha .button.is-light.is-outlined.is-loading.is-focused::after{border-color:transparent transparent rgba(0,0,0,0.7) rgba(0,0,0,0.7) !important}html.theme--catppuccin-mocha .button.is-light.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-mocha .button.is-light.is-outlined{background-color:transparent;border-color:#f5f5f5;box-shadow:none;color:#f5f5f5}html.theme--catppuccin-mocha .button.is-light.is-inverted.is-outlined{background-color:transparent;border-color:rgba(0,0,0,0.7);color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .button.is-light.is-inverted.is-outlined:hover,html.theme--catppuccin-mocha .button.is-light.is-inverted.is-outlined.is-hovered,html.theme--catppuccin-mocha .button.is-light.is-inverted.is-outlined:focus,html.theme--catppuccin-mocha .button.is-light.is-inverted.is-outlined.is-focused{background-color:rgba(0,0,0,0.7);color:#f5f5f5}html.theme--catppuccin-mocha .button.is-light.is-inverted.is-outlined.is-loading:hover::after,html.theme--catppuccin-mocha .button.is-light.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-mocha .button.is-light.is-inverted.is-outlined.is-loading:focus::after,html.theme--catppuccin-mocha .button.is-light.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #f5f5f5 #f5f5f5 !important}html.theme--catppuccin-mocha .button.is-light.is-inverted.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-mocha .button.is-light.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)}html.theme--catppuccin-mocha .button.is-dark,html.theme--catppuccin-mocha .content kbd.button{background-color:#313244;border-color:transparent;color:#fff}html.theme--catppuccin-mocha .button.is-dark:hover,html.theme--catppuccin-mocha .content kbd.button:hover,html.theme--catppuccin-mocha .button.is-dark.is-hovered,html.theme--catppuccin-mocha .content kbd.button.is-hovered{background-color:#2c2d3d;border-color:transparent;color:#fff}html.theme--catppuccin-mocha .button.is-dark:focus,html.theme--catppuccin-mocha .content kbd.button:focus,html.theme--catppuccin-mocha .button.is-dark.is-focused,html.theme--catppuccin-mocha .content kbd.button.is-focused{border-color:transparent;color:#fff}html.theme--catppuccin-mocha .button.is-dark:focus:not(:active),html.theme--catppuccin-mocha .content kbd.button:focus:not(:active),html.theme--catppuccin-mocha .button.is-dark.is-focused:not(:active),html.theme--catppuccin-mocha .content kbd.button.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(49,50,68,0.25)}html.theme--catppuccin-mocha .button.is-dark:active,html.theme--catppuccin-mocha .content kbd.button:active,html.theme--catppuccin-mocha .button.is-dark.is-active,html.theme--catppuccin-mocha .content kbd.button.is-active{background-color:#262735;border-color:transparent;color:#fff}html.theme--catppuccin-mocha .button.is-dark[disabled],html.theme--catppuccin-mocha .content kbd.button[disabled],fieldset[disabled] html.theme--catppuccin-mocha .button.is-dark,fieldset[disabled] html.theme--catppuccin-mocha .content kbd.button{background-color:#313244;border-color:#313244;box-shadow:none}html.theme--catppuccin-mocha .button.is-dark.is-inverted,html.theme--catppuccin-mocha .content kbd.button.is-inverted{background-color:#fff;color:#313244}html.theme--catppuccin-mocha .button.is-dark.is-inverted:hover,html.theme--catppuccin-mocha .content kbd.button.is-inverted:hover,html.theme--catppuccin-mocha .button.is-dark.is-inverted.is-hovered,html.theme--catppuccin-mocha .content kbd.button.is-inverted.is-hovered{background-color:#f2f2f2}html.theme--catppuccin-mocha .button.is-dark.is-inverted[disabled],html.theme--catppuccin-mocha .content kbd.button.is-inverted[disabled],fieldset[disabled] html.theme--catppuccin-mocha .button.is-dark.is-inverted,fieldset[disabled] html.theme--catppuccin-mocha .content kbd.button.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#313244}html.theme--catppuccin-mocha .button.is-dark.is-loading::after,html.theme--catppuccin-mocha .content kbd.button.is-loading::after{border-color:transparent transparent #fff #fff !important}html.theme--catppuccin-mocha .button.is-dark.is-outlined,html.theme--catppuccin-mocha .content kbd.button.is-outlined{background-color:transparent;border-color:#313244;color:#313244}html.theme--catppuccin-mocha .button.is-dark.is-outlined:hover,html.theme--catppuccin-mocha .content kbd.button.is-outlined:hover,html.theme--catppuccin-mocha .button.is-dark.is-outlined.is-hovered,html.theme--catppuccin-mocha .content kbd.button.is-outlined.is-hovered,html.theme--catppuccin-mocha .button.is-dark.is-outlined:focus,html.theme--catppuccin-mocha .content kbd.button.is-outlined:focus,html.theme--catppuccin-mocha .button.is-dark.is-outlined.is-focused,html.theme--catppuccin-mocha .content kbd.button.is-outlined.is-focused{background-color:#313244;border-color:#313244;color:#fff}html.theme--catppuccin-mocha .button.is-dark.is-outlined.is-loading::after,html.theme--catppuccin-mocha .content kbd.button.is-outlined.is-loading::after{border-color:transparent transparent #313244 #313244 !important}html.theme--catppuccin-mocha .button.is-dark.is-outlined.is-loading:hover::after,html.theme--catppuccin-mocha .content kbd.button.is-outlined.is-loading:hover::after,html.theme--catppuccin-mocha .button.is-dark.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-mocha .content kbd.button.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-mocha .button.is-dark.is-outlined.is-loading:focus::after,html.theme--catppuccin-mocha .content kbd.button.is-outlined.is-loading:focus::after,html.theme--catppuccin-mocha .button.is-dark.is-outlined.is-loading.is-focused::after,html.theme--catppuccin-mocha .content kbd.button.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #fff #fff !important}html.theme--catppuccin-mocha .button.is-dark.is-outlined[disabled],html.theme--catppuccin-mocha .content kbd.button.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-mocha .button.is-dark.is-outlined,fieldset[disabled] html.theme--catppuccin-mocha .content kbd.button.is-outlined{background-color:transparent;border-color:#313244;box-shadow:none;color:#313244}html.theme--catppuccin-mocha .button.is-dark.is-inverted.is-outlined,html.theme--catppuccin-mocha .content kbd.button.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}html.theme--catppuccin-mocha .button.is-dark.is-inverted.is-outlined:hover,html.theme--catppuccin-mocha .content kbd.button.is-inverted.is-outlined:hover,html.theme--catppuccin-mocha .button.is-dark.is-inverted.is-outlined.is-hovered,html.theme--catppuccin-mocha .content kbd.button.is-inverted.is-outlined.is-hovered,html.theme--catppuccin-mocha .button.is-dark.is-inverted.is-outlined:focus,html.theme--catppuccin-mocha .content kbd.button.is-inverted.is-outlined:focus,html.theme--catppuccin-mocha .button.is-dark.is-inverted.is-outlined.is-focused,html.theme--catppuccin-mocha .content kbd.button.is-inverted.is-outlined.is-focused{background-color:#fff;color:#313244}html.theme--catppuccin-mocha .button.is-dark.is-inverted.is-outlined.is-loading:hover::after,html.theme--catppuccin-mocha .content kbd.button.is-inverted.is-outlined.is-loading:hover::after,html.theme--catppuccin-mocha .button.is-dark.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-mocha .content kbd.button.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-mocha .button.is-dark.is-inverted.is-outlined.is-loading:focus::after,html.theme--catppuccin-mocha .content kbd.button.is-inverted.is-outlined.is-loading:focus::after,html.theme--catppuccin-mocha .button.is-dark.is-inverted.is-outlined.is-loading.is-focused::after,html.theme--catppuccin-mocha .content kbd.button.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #313244 #313244 !important}html.theme--catppuccin-mocha .button.is-dark.is-inverted.is-outlined[disabled],html.theme--catppuccin-mocha .content kbd.button.is-inverted.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-mocha .button.is-dark.is-inverted.is-outlined,fieldset[disabled] html.theme--catppuccin-mocha .content kbd.button.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}html.theme--catppuccin-mocha .button.is-primary,html.theme--catppuccin-mocha .docstring>section>a.button.docs-sourcelink{background-color:#89b4fa;border-color:transparent;color:#fff}html.theme--catppuccin-mocha .button.is-primary:hover,html.theme--catppuccin-mocha .docstring>section>a.button.docs-sourcelink:hover,html.theme--catppuccin-mocha .button.is-primary.is-hovered,html.theme--catppuccin-mocha .docstring>section>a.button.is-hovered.docs-sourcelink{background-color:#7dacf9;border-color:transparent;color:#fff}html.theme--catppuccin-mocha .button.is-primary:focus,html.theme--catppuccin-mocha .docstring>section>a.button.docs-sourcelink:focus,html.theme--catppuccin-mocha .button.is-primary.is-focused,html.theme--catppuccin-mocha .docstring>section>a.button.is-focused.docs-sourcelink{border-color:transparent;color:#fff}html.theme--catppuccin-mocha .button.is-primary:focus:not(:active),html.theme--catppuccin-mocha .docstring>section>a.button.docs-sourcelink:focus:not(:active),html.theme--catppuccin-mocha .button.is-primary.is-focused:not(:active),html.theme--catppuccin-mocha .docstring>section>a.button.is-focused.docs-sourcelink:not(:active){box-shadow:0 0 0 0.125em rgba(137,180,250,0.25)}html.theme--catppuccin-mocha .button.is-primary:active,html.theme--catppuccin-mocha .docstring>section>a.button.docs-sourcelink:active,html.theme--catppuccin-mocha .button.is-primary.is-active,html.theme--catppuccin-mocha .docstring>section>a.button.is-active.docs-sourcelink{background-color:#71a4f9;border-color:transparent;color:#fff}html.theme--catppuccin-mocha .button.is-primary[disabled],html.theme--catppuccin-mocha .docstring>section>a.button.docs-sourcelink[disabled],fieldset[disabled] html.theme--catppuccin-mocha .button.is-primary,fieldset[disabled] html.theme--catppuccin-mocha .docstring>section>a.button.docs-sourcelink{background-color:#89b4fa;border-color:#89b4fa;box-shadow:none}html.theme--catppuccin-mocha .button.is-primary.is-inverted,html.theme--catppuccin-mocha .docstring>section>a.button.is-inverted.docs-sourcelink{background-color:#fff;color:#89b4fa}html.theme--catppuccin-mocha .button.is-primary.is-inverted:hover,html.theme--catppuccin-mocha .docstring>section>a.button.is-inverted.docs-sourcelink:hover,html.theme--catppuccin-mocha .button.is-primary.is-inverted.is-hovered,html.theme--catppuccin-mocha .docstring>section>a.button.is-inverted.is-hovered.docs-sourcelink{background-color:#f2f2f2}html.theme--catppuccin-mocha .button.is-primary.is-inverted[disabled],html.theme--catppuccin-mocha .docstring>section>a.button.is-inverted.docs-sourcelink[disabled],fieldset[disabled] html.theme--catppuccin-mocha .button.is-primary.is-inverted,fieldset[disabled] html.theme--catppuccin-mocha .docstring>section>a.button.is-inverted.docs-sourcelink{background-color:#fff;border-color:transparent;box-shadow:none;color:#89b4fa}html.theme--catppuccin-mocha .button.is-primary.is-loading::after,html.theme--catppuccin-mocha .docstring>section>a.button.is-loading.docs-sourcelink::after{border-color:transparent transparent #fff #fff !important}html.theme--catppuccin-mocha .button.is-primary.is-outlined,html.theme--catppuccin-mocha .docstring>section>a.button.is-outlined.docs-sourcelink{background-color:transparent;border-color:#89b4fa;color:#89b4fa}html.theme--catppuccin-mocha .button.is-primary.is-outlined:hover,html.theme--catppuccin-mocha .docstring>section>a.button.is-outlined.docs-sourcelink:hover,html.theme--catppuccin-mocha .button.is-primary.is-outlined.is-hovered,html.theme--catppuccin-mocha .docstring>section>a.button.is-outlined.is-hovered.docs-sourcelink,html.theme--catppuccin-mocha .button.is-primary.is-outlined:focus,html.theme--catppuccin-mocha .docstring>section>a.button.is-outlined.docs-sourcelink:focus,html.theme--catppuccin-mocha .button.is-primary.is-outlined.is-focused,html.theme--catppuccin-mocha .docstring>section>a.button.is-outlined.is-focused.docs-sourcelink{background-color:#89b4fa;border-color:#89b4fa;color:#fff}html.theme--catppuccin-mocha .button.is-primary.is-outlined.is-loading::after,html.theme--catppuccin-mocha .docstring>section>a.button.is-outlined.is-loading.docs-sourcelink::after{border-color:transparent transparent #89b4fa #89b4fa !important}html.theme--catppuccin-mocha .button.is-primary.is-outlined.is-loading:hover::after,html.theme--catppuccin-mocha .docstring>section>a.button.is-outlined.is-loading.docs-sourcelink:hover::after,html.theme--catppuccin-mocha .button.is-primary.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-mocha .docstring>section>a.button.is-outlined.is-loading.is-hovered.docs-sourcelink::after,html.theme--catppuccin-mocha .button.is-primary.is-outlined.is-loading:focus::after,html.theme--catppuccin-mocha .docstring>section>a.button.is-outlined.is-loading.docs-sourcelink:focus::after,html.theme--catppuccin-mocha .button.is-primary.is-outlined.is-loading.is-focused::after,html.theme--catppuccin-mocha .docstring>section>a.button.is-outlined.is-loading.is-focused.docs-sourcelink::after{border-color:transparent transparent #fff #fff !important}html.theme--catppuccin-mocha .button.is-primary.is-outlined[disabled],html.theme--catppuccin-mocha .docstring>section>a.button.is-outlined.docs-sourcelink[disabled],fieldset[disabled] html.theme--catppuccin-mocha .button.is-primary.is-outlined,fieldset[disabled] html.theme--catppuccin-mocha .docstring>section>a.button.is-outlined.docs-sourcelink{background-color:transparent;border-color:#89b4fa;box-shadow:none;color:#89b4fa}html.theme--catppuccin-mocha .button.is-primary.is-inverted.is-outlined,html.theme--catppuccin-mocha .docstring>section>a.button.is-inverted.is-outlined.docs-sourcelink{background-color:transparent;border-color:#fff;color:#fff}html.theme--catppuccin-mocha .button.is-primary.is-inverted.is-outlined:hover,html.theme--catppuccin-mocha .docstring>section>a.button.is-inverted.is-outlined.docs-sourcelink:hover,html.theme--catppuccin-mocha .button.is-primary.is-inverted.is-outlined.is-hovered,html.theme--catppuccin-mocha .docstring>section>a.button.is-inverted.is-outlined.is-hovered.docs-sourcelink,html.theme--catppuccin-mocha .button.is-primary.is-inverted.is-outlined:focus,html.theme--catppuccin-mocha .docstring>section>a.button.is-inverted.is-outlined.docs-sourcelink:focus,html.theme--catppuccin-mocha .button.is-primary.is-inverted.is-outlined.is-focused,html.theme--catppuccin-mocha .docstring>section>a.button.is-inverted.is-outlined.is-focused.docs-sourcelink{background-color:#fff;color:#89b4fa}html.theme--catppuccin-mocha .button.is-primary.is-inverted.is-outlined.is-loading:hover::after,html.theme--catppuccin-mocha .docstring>section>a.button.is-inverted.is-outlined.is-loading.docs-sourcelink:hover::after,html.theme--catppuccin-mocha .button.is-primary.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-mocha .docstring>section>a.button.is-inverted.is-outlined.is-loading.is-hovered.docs-sourcelink::after,html.theme--catppuccin-mocha .button.is-primary.is-inverted.is-outlined.is-loading:focus::after,html.theme--catppuccin-mocha .docstring>section>a.button.is-inverted.is-outlined.is-loading.docs-sourcelink:focus::after,html.theme--catppuccin-mocha .button.is-primary.is-inverted.is-outlined.is-loading.is-focused::after,html.theme--catppuccin-mocha .docstring>section>a.button.is-inverted.is-outlined.is-loading.is-focused.docs-sourcelink::after{border-color:transparent transparent #89b4fa #89b4fa !important}html.theme--catppuccin-mocha .button.is-primary.is-inverted.is-outlined[disabled],html.theme--catppuccin-mocha .docstring>section>a.button.is-inverted.is-outlined.docs-sourcelink[disabled],fieldset[disabled] html.theme--catppuccin-mocha .button.is-primary.is-inverted.is-outlined,fieldset[disabled] html.theme--catppuccin-mocha .docstring>section>a.button.is-inverted.is-outlined.docs-sourcelink{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}html.theme--catppuccin-mocha .button.is-primary.is-light,html.theme--catppuccin-mocha .docstring>section>a.button.is-light.docs-sourcelink{background-color:#ebf3fe;color:#063c93}html.theme--catppuccin-mocha .button.is-primary.is-light:hover,html.theme--catppuccin-mocha .docstring>section>a.button.is-light.docs-sourcelink:hover,html.theme--catppuccin-mocha .button.is-primary.is-light.is-hovered,html.theme--catppuccin-mocha .docstring>section>a.button.is-light.is-hovered.docs-sourcelink{background-color:#dfebfe;border-color:transparent;color:#063c93}html.theme--catppuccin-mocha .button.is-primary.is-light:active,html.theme--catppuccin-mocha .docstring>section>a.button.is-light.docs-sourcelink:active,html.theme--catppuccin-mocha .button.is-primary.is-light.is-active,html.theme--catppuccin-mocha .docstring>section>a.button.is-light.is-active.docs-sourcelink{background-color:#d3e3fd;border-color:transparent;color:#063c93}html.theme--catppuccin-mocha .button.is-link{background-color:#89b4fa;border-color:transparent;color:#fff}html.theme--catppuccin-mocha .button.is-link:hover,html.theme--catppuccin-mocha .button.is-link.is-hovered{background-color:#7dacf9;border-color:transparent;color:#fff}html.theme--catppuccin-mocha .button.is-link:focus,html.theme--catppuccin-mocha .button.is-link.is-focused{border-color:transparent;color:#fff}html.theme--catppuccin-mocha .button.is-link:focus:not(:active),html.theme--catppuccin-mocha .button.is-link.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(137,180,250,0.25)}html.theme--catppuccin-mocha .button.is-link:active,html.theme--catppuccin-mocha .button.is-link.is-active{background-color:#71a4f9;border-color:transparent;color:#fff}html.theme--catppuccin-mocha .button.is-link[disabled],fieldset[disabled] html.theme--catppuccin-mocha .button.is-link{background-color:#89b4fa;border-color:#89b4fa;box-shadow:none}html.theme--catppuccin-mocha .button.is-link.is-inverted{background-color:#fff;color:#89b4fa}html.theme--catppuccin-mocha .button.is-link.is-inverted:hover,html.theme--catppuccin-mocha .button.is-link.is-inverted.is-hovered{background-color:#f2f2f2}html.theme--catppuccin-mocha .button.is-link.is-inverted[disabled],fieldset[disabled] html.theme--catppuccin-mocha .button.is-link.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#89b4fa}html.theme--catppuccin-mocha .button.is-link.is-loading::after{border-color:transparent transparent #fff #fff !important}html.theme--catppuccin-mocha .button.is-link.is-outlined{background-color:transparent;border-color:#89b4fa;color:#89b4fa}html.theme--catppuccin-mocha .button.is-link.is-outlined:hover,html.theme--catppuccin-mocha .button.is-link.is-outlined.is-hovered,html.theme--catppuccin-mocha .button.is-link.is-outlined:focus,html.theme--catppuccin-mocha .button.is-link.is-outlined.is-focused{background-color:#89b4fa;border-color:#89b4fa;color:#fff}html.theme--catppuccin-mocha .button.is-link.is-outlined.is-loading::after{border-color:transparent transparent #89b4fa #89b4fa !important}html.theme--catppuccin-mocha .button.is-link.is-outlined.is-loading:hover::after,html.theme--catppuccin-mocha .button.is-link.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-mocha .button.is-link.is-outlined.is-loading:focus::after,html.theme--catppuccin-mocha .button.is-link.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #fff #fff !important}html.theme--catppuccin-mocha .button.is-link.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-mocha .button.is-link.is-outlined{background-color:transparent;border-color:#89b4fa;box-shadow:none;color:#89b4fa}html.theme--catppuccin-mocha .button.is-link.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}html.theme--catppuccin-mocha .button.is-link.is-inverted.is-outlined:hover,html.theme--catppuccin-mocha .button.is-link.is-inverted.is-outlined.is-hovered,html.theme--catppuccin-mocha .button.is-link.is-inverted.is-outlined:focus,html.theme--catppuccin-mocha .button.is-link.is-inverted.is-outlined.is-focused{background-color:#fff;color:#89b4fa}html.theme--catppuccin-mocha .button.is-link.is-inverted.is-outlined.is-loading:hover::after,html.theme--catppuccin-mocha .button.is-link.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-mocha .button.is-link.is-inverted.is-outlined.is-loading:focus::after,html.theme--catppuccin-mocha .button.is-link.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #89b4fa #89b4fa !important}html.theme--catppuccin-mocha .button.is-link.is-inverted.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-mocha .button.is-link.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}html.theme--catppuccin-mocha .button.is-link.is-light{background-color:#ebf3fe;color:#063c93}html.theme--catppuccin-mocha .button.is-link.is-light:hover,html.theme--catppuccin-mocha .button.is-link.is-light.is-hovered{background-color:#dfebfe;border-color:transparent;color:#063c93}html.theme--catppuccin-mocha .button.is-link.is-light:active,html.theme--catppuccin-mocha .button.is-link.is-light.is-active{background-color:#d3e3fd;border-color:transparent;color:#063c93}html.theme--catppuccin-mocha .button.is-info{background-color:#94e2d5;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .button.is-info:hover,html.theme--catppuccin-mocha .button.is-info.is-hovered{background-color:#8adfd1;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .button.is-info:focus,html.theme--catppuccin-mocha .button.is-info.is-focused{border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .button.is-info:focus:not(:active),html.theme--catppuccin-mocha .button.is-info.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(148,226,213,0.25)}html.theme--catppuccin-mocha .button.is-info:active,html.theme--catppuccin-mocha .button.is-info.is-active{background-color:#80ddcd;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .button.is-info[disabled],fieldset[disabled] html.theme--catppuccin-mocha .button.is-info{background-color:#94e2d5;border-color:#94e2d5;box-shadow:none}html.theme--catppuccin-mocha .button.is-info.is-inverted{background-color:rgba(0,0,0,0.7);color:#94e2d5}html.theme--catppuccin-mocha .button.is-info.is-inverted:hover,html.theme--catppuccin-mocha .button.is-info.is-inverted.is-hovered{background-color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .button.is-info.is-inverted[disabled],fieldset[disabled] html.theme--catppuccin-mocha .button.is-info.is-inverted{background-color:rgba(0,0,0,0.7);border-color:transparent;box-shadow:none;color:#94e2d5}html.theme--catppuccin-mocha .button.is-info.is-loading::after{border-color:transparent transparent rgba(0,0,0,0.7) rgba(0,0,0,0.7) !important}html.theme--catppuccin-mocha .button.is-info.is-outlined{background-color:transparent;border-color:#94e2d5;color:#94e2d5}html.theme--catppuccin-mocha .button.is-info.is-outlined:hover,html.theme--catppuccin-mocha .button.is-info.is-outlined.is-hovered,html.theme--catppuccin-mocha .button.is-info.is-outlined:focus,html.theme--catppuccin-mocha .button.is-info.is-outlined.is-focused{background-color:#94e2d5;border-color:#94e2d5;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .button.is-info.is-outlined.is-loading::after{border-color:transparent transparent #94e2d5 #94e2d5 !important}html.theme--catppuccin-mocha .button.is-info.is-outlined.is-loading:hover::after,html.theme--catppuccin-mocha .button.is-info.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-mocha .button.is-info.is-outlined.is-loading:focus::after,html.theme--catppuccin-mocha .button.is-info.is-outlined.is-loading.is-focused::after{border-color:transparent transparent rgba(0,0,0,0.7) rgba(0,0,0,0.7) !important}html.theme--catppuccin-mocha .button.is-info.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-mocha .button.is-info.is-outlined{background-color:transparent;border-color:#94e2d5;box-shadow:none;color:#94e2d5}html.theme--catppuccin-mocha .button.is-info.is-inverted.is-outlined{background-color:transparent;border-color:rgba(0,0,0,0.7);color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .button.is-info.is-inverted.is-outlined:hover,html.theme--catppuccin-mocha .button.is-info.is-inverted.is-outlined.is-hovered,html.theme--catppuccin-mocha .button.is-info.is-inverted.is-outlined:focus,html.theme--catppuccin-mocha .button.is-info.is-inverted.is-outlined.is-focused{background-color:rgba(0,0,0,0.7);color:#94e2d5}html.theme--catppuccin-mocha .button.is-info.is-inverted.is-outlined.is-loading:hover::after,html.theme--catppuccin-mocha .button.is-info.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-mocha .button.is-info.is-inverted.is-outlined.is-loading:focus::after,html.theme--catppuccin-mocha .button.is-info.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #94e2d5 #94e2d5 !important}html.theme--catppuccin-mocha .button.is-info.is-inverted.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-mocha .button.is-info.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)}html.theme--catppuccin-mocha .button.is-info.is-light{background-color:#effbf9;color:#207466}html.theme--catppuccin-mocha .button.is-info.is-light:hover,html.theme--catppuccin-mocha .button.is-info.is-light.is-hovered{background-color:#e5f8f5;border-color:transparent;color:#207466}html.theme--catppuccin-mocha .button.is-info.is-light:active,html.theme--catppuccin-mocha .button.is-info.is-light.is-active{background-color:#dbf5f1;border-color:transparent;color:#207466}html.theme--catppuccin-mocha .button.is-success{background-color:#a6e3a1;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .button.is-success:hover,html.theme--catppuccin-mocha .button.is-success.is-hovered{background-color:#9de097;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .button.is-success:focus,html.theme--catppuccin-mocha .button.is-success.is-focused{border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .button.is-success:focus:not(:active),html.theme--catppuccin-mocha .button.is-success.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(166,227,161,0.25)}html.theme--catppuccin-mocha .button.is-success:active,html.theme--catppuccin-mocha .button.is-success.is-active{background-color:#93dd8d;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .button.is-success[disabled],fieldset[disabled] html.theme--catppuccin-mocha .button.is-success{background-color:#a6e3a1;border-color:#a6e3a1;box-shadow:none}html.theme--catppuccin-mocha .button.is-success.is-inverted{background-color:rgba(0,0,0,0.7);color:#a6e3a1}html.theme--catppuccin-mocha .button.is-success.is-inverted:hover,html.theme--catppuccin-mocha .button.is-success.is-inverted.is-hovered{background-color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .button.is-success.is-inverted[disabled],fieldset[disabled] html.theme--catppuccin-mocha .button.is-success.is-inverted{background-color:rgba(0,0,0,0.7);border-color:transparent;box-shadow:none;color:#a6e3a1}html.theme--catppuccin-mocha .button.is-success.is-loading::after{border-color:transparent transparent rgba(0,0,0,0.7) rgba(0,0,0,0.7) !important}html.theme--catppuccin-mocha .button.is-success.is-outlined{background-color:transparent;border-color:#a6e3a1;color:#a6e3a1}html.theme--catppuccin-mocha .button.is-success.is-outlined:hover,html.theme--catppuccin-mocha .button.is-success.is-outlined.is-hovered,html.theme--catppuccin-mocha .button.is-success.is-outlined:focus,html.theme--catppuccin-mocha .button.is-success.is-outlined.is-focused{background-color:#a6e3a1;border-color:#a6e3a1;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .button.is-success.is-outlined.is-loading::after{border-color:transparent transparent #a6e3a1 #a6e3a1 !important}html.theme--catppuccin-mocha .button.is-success.is-outlined.is-loading:hover::after,html.theme--catppuccin-mocha .button.is-success.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-mocha .button.is-success.is-outlined.is-loading:focus::after,html.theme--catppuccin-mocha .button.is-success.is-outlined.is-loading.is-focused::after{border-color:transparent transparent rgba(0,0,0,0.7) rgba(0,0,0,0.7) !important}html.theme--catppuccin-mocha .button.is-success.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-mocha .button.is-success.is-outlined{background-color:transparent;border-color:#a6e3a1;box-shadow:none;color:#a6e3a1}html.theme--catppuccin-mocha .button.is-success.is-inverted.is-outlined{background-color:transparent;border-color:rgba(0,0,0,0.7);color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .button.is-success.is-inverted.is-outlined:hover,html.theme--catppuccin-mocha .button.is-success.is-inverted.is-outlined.is-hovered,html.theme--catppuccin-mocha .button.is-success.is-inverted.is-outlined:focus,html.theme--catppuccin-mocha .button.is-success.is-inverted.is-outlined.is-focused{background-color:rgba(0,0,0,0.7);color:#a6e3a1}html.theme--catppuccin-mocha .button.is-success.is-inverted.is-outlined.is-loading:hover::after,html.theme--catppuccin-mocha .button.is-success.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-mocha .button.is-success.is-inverted.is-outlined.is-loading:focus::after,html.theme--catppuccin-mocha .button.is-success.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #a6e3a1 #a6e3a1 !important}html.theme--catppuccin-mocha .button.is-success.is-inverted.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-mocha .button.is-success.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)}html.theme--catppuccin-mocha .button.is-success.is-light{background-color:#f0faef;color:#287222}html.theme--catppuccin-mocha .button.is-success.is-light:hover,html.theme--catppuccin-mocha .button.is-success.is-light.is-hovered{background-color:#e7f7e5;border-color:transparent;color:#287222}html.theme--catppuccin-mocha .button.is-success.is-light:active,html.theme--catppuccin-mocha .button.is-success.is-light.is-active{background-color:#def4dc;border-color:transparent;color:#287222}html.theme--catppuccin-mocha .button.is-warning{background-color:#f9e2af;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .button.is-warning:hover,html.theme--catppuccin-mocha .button.is-warning.is-hovered{background-color:#f8dea3;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .button.is-warning:focus,html.theme--catppuccin-mocha .button.is-warning.is-focused{border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .button.is-warning:focus:not(:active),html.theme--catppuccin-mocha .button.is-warning.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(249,226,175,0.25)}html.theme--catppuccin-mocha .button.is-warning:active,html.theme--catppuccin-mocha .button.is-warning.is-active{background-color:#f7d997;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .button.is-warning[disabled],fieldset[disabled] html.theme--catppuccin-mocha .button.is-warning{background-color:#f9e2af;border-color:#f9e2af;box-shadow:none}html.theme--catppuccin-mocha .button.is-warning.is-inverted{background-color:rgba(0,0,0,0.7);color:#f9e2af}html.theme--catppuccin-mocha .button.is-warning.is-inverted:hover,html.theme--catppuccin-mocha .button.is-warning.is-inverted.is-hovered{background-color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .button.is-warning.is-inverted[disabled],fieldset[disabled] html.theme--catppuccin-mocha .button.is-warning.is-inverted{background-color:rgba(0,0,0,0.7);border-color:transparent;box-shadow:none;color:#f9e2af}html.theme--catppuccin-mocha .button.is-warning.is-loading::after{border-color:transparent transparent rgba(0,0,0,0.7) rgba(0,0,0,0.7) !important}html.theme--catppuccin-mocha .button.is-warning.is-outlined{background-color:transparent;border-color:#f9e2af;color:#f9e2af}html.theme--catppuccin-mocha .button.is-warning.is-outlined:hover,html.theme--catppuccin-mocha .button.is-warning.is-outlined.is-hovered,html.theme--catppuccin-mocha .button.is-warning.is-outlined:focus,html.theme--catppuccin-mocha .button.is-warning.is-outlined.is-focused{background-color:#f9e2af;border-color:#f9e2af;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .button.is-warning.is-outlined.is-loading::after{border-color:transparent transparent #f9e2af #f9e2af !important}html.theme--catppuccin-mocha .button.is-warning.is-outlined.is-loading:hover::after,html.theme--catppuccin-mocha .button.is-warning.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-mocha .button.is-warning.is-outlined.is-loading:focus::after,html.theme--catppuccin-mocha .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}html.theme--catppuccin-mocha .button.is-warning.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-mocha .button.is-warning.is-outlined{background-color:transparent;border-color:#f9e2af;box-shadow:none;color:#f9e2af}html.theme--catppuccin-mocha .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)}html.theme--catppuccin-mocha .button.is-warning.is-inverted.is-outlined:hover,html.theme--catppuccin-mocha .button.is-warning.is-inverted.is-outlined.is-hovered,html.theme--catppuccin-mocha .button.is-warning.is-inverted.is-outlined:focus,html.theme--catppuccin-mocha .button.is-warning.is-inverted.is-outlined.is-focused{background-color:rgba(0,0,0,0.7);color:#f9e2af}html.theme--catppuccin-mocha .button.is-warning.is-inverted.is-outlined.is-loading:hover::after,html.theme--catppuccin-mocha .button.is-warning.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-mocha .button.is-warning.is-inverted.is-outlined.is-loading:focus::after,html.theme--catppuccin-mocha .button.is-warning.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #f9e2af #f9e2af !important}html.theme--catppuccin-mocha .button.is-warning.is-inverted.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-mocha .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)}html.theme--catppuccin-mocha .button.is-warning.is-light{background-color:#fef8ec;color:#8a620a}html.theme--catppuccin-mocha .button.is-warning.is-light:hover,html.theme--catppuccin-mocha .button.is-warning.is-light.is-hovered{background-color:#fdf4e0;border-color:transparent;color:#8a620a}html.theme--catppuccin-mocha .button.is-warning.is-light:active,html.theme--catppuccin-mocha .button.is-warning.is-light.is-active{background-color:#fcf0d4;border-color:transparent;color:#8a620a}html.theme--catppuccin-mocha .button.is-danger{background-color:#f38ba8;border-color:transparent;color:#fff}html.theme--catppuccin-mocha .button.is-danger:hover,html.theme--catppuccin-mocha .button.is-danger.is-hovered{background-color:#f27f9f;border-color:transparent;color:#fff}html.theme--catppuccin-mocha .button.is-danger:focus,html.theme--catppuccin-mocha .button.is-danger.is-focused{border-color:transparent;color:#fff}html.theme--catppuccin-mocha .button.is-danger:focus:not(:active),html.theme--catppuccin-mocha .button.is-danger.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(243,139,168,0.25)}html.theme--catppuccin-mocha .button.is-danger:active,html.theme--catppuccin-mocha .button.is-danger.is-active{background-color:#f17497;border-color:transparent;color:#fff}html.theme--catppuccin-mocha .button.is-danger[disabled],fieldset[disabled] html.theme--catppuccin-mocha .button.is-danger{background-color:#f38ba8;border-color:#f38ba8;box-shadow:none}html.theme--catppuccin-mocha .button.is-danger.is-inverted{background-color:#fff;color:#f38ba8}html.theme--catppuccin-mocha .button.is-danger.is-inverted:hover,html.theme--catppuccin-mocha .button.is-danger.is-inverted.is-hovered{background-color:#f2f2f2}html.theme--catppuccin-mocha .button.is-danger.is-inverted[disabled],fieldset[disabled] html.theme--catppuccin-mocha .button.is-danger.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#f38ba8}html.theme--catppuccin-mocha .button.is-danger.is-loading::after{border-color:transparent transparent #fff #fff !important}html.theme--catppuccin-mocha .button.is-danger.is-outlined{background-color:transparent;border-color:#f38ba8;color:#f38ba8}html.theme--catppuccin-mocha .button.is-danger.is-outlined:hover,html.theme--catppuccin-mocha .button.is-danger.is-outlined.is-hovered,html.theme--catppuccin-mocha .button.is-danger.is-outlined:focus,html.theme--catppuccin-mocha .button.is-danger.is-outlined.is-focused{background-color:#f38ba8;border-color:#f38ba8;color:#fff}html.theme--catppuccin-mocha .button.is-danger.is-outlined.is-loading::after{border-color:transparent transparent #f38ba8 #f38ba8 !important}html.theme--catppuccin-mocha .button.is-danger.is-outlined.is-loading:hover::after,html.theme--catppuccin-mocha .button.is-danger.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-mocha .button.is-danger.is-outlined.is-loading:focus::after,html.theme--catppuccin-mocha .button.is-danger.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #fff #fff !important}html.theme--catppuccin-mocha .button.is-danger.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-mocha .button.is-danger.is-outlined{background-color:transparent;border-color:#f38ba8;box-shadow:none;color:#f38ba8}html.theme--catppuccin-mocha .button.is-danger.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}html.theme--catppuccin-mocha .button.is-danger.is-inverted.is-outlined:hover,html.theme--catppuccin-mocha .button.is-danger.is-inverted.is-outlined.is-hovered,html.theme--catppuccin-mocha .button.is-danger.is-inverted.is-outlined:focus,html.theme--catppuccin-mocha .button.is-danger.is-inverted.is-outlined.is-focused{background-color:#fff;color:#f38ba8}html.theme--catppuccin-mocha .button.is-danger.is-inverted.is-outlined.is-loading:hover::after,html.theme--catppuccin-mocha .button.is-danger.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-mocha .button.is-danger.is-inverted.is-outlined.is-loading:focus::after,html.theme--catppuccin-mocha .button.is-danger.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #f38ba8 #f38ba8 !important}html.theme--catppuccin-mocha .button.is-danger.is-inverted.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-mocha .button.is-danger.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}html.theme--catppuccin-mocha .button.is-danger.is-light{background-color:#fdedf1;color:#991036}html.theme--catppuccin-mocha .button.is-danger.is-light:hover,html.theme--catppuccin-mocha .button.is-danger.is-light.is-hovered{background-color:#fce1e8;border-color:transparent;color:#991036}html.theme--catppuccin-mocha .button.is-danger.is-light:active,html.theme--catppuccin-mocha .button.is-danger.is-light.is-active{background-color:#fbd5e0;border-color:transparent;color:#991036}html.theme--catppuccin-mocha .button.is-small,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.button{font-size:.75rem}html.theme--catppuccin-mocha .button.is-small:not(.is-rounded),html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.button:not(.is-rounded){border-radius:3px}html.theme--catppuccin-mocha .button.is-normal{font-size:1rem}html.theme--catppuccin-mocha .button.is-medium{font-size:1.25rem}html.theme--catppuccin-mocha .button.is-large{font-size:1.5rem}html.theme--catppuccin-mocha .button[disabled],fieldset[disabled] html.theme--catppuccin-mocha .button{background-color:#6c7086;border-color:#585b70;box-shadow:none;opacity:.5}html.theme--catppuccin-mocha .button.is-fullwidth{display:flex;width:100%}html.theme--catppuccin-mocha .button.is-loading{color:transparent !important;pointer-events:none}html.theme--catppuccin-mocha .button.is-loading::after{position:absolute;left:calc(50% - (1em * 0.5));top:calc(50% - (1em * 0.5));position:absolute !important}html.theme--catppuccin-mocha .button.is-static{background-color:#181825;border-color:#585b70;color:#7f849c;box-shadow:none;pointer-events:none}html.theme--catppuccin-mocha .button.is-rounded,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.button{border-radius:9999px;padding-left:calc(1em + 0.25em);padding-right:calc(1em + 0.25em)}html.theme--catppuccin-mocha .buttons{align-items:center;display:flex;flex-wrap:wrap;justify-content:flex-start}html.theme--catppuccin-mocha .buttons .button{margin-bottom:0.5rem}html.theme--catppuccin-mocha .buttons .button:not(:last-child):not(.is-fullwidth){margin-right:.5rem}html.theme--catppuccin-mocha .buttons:last-child{margin-bottom:-0.5rem}html.theme--catppuccin-mocha .buttons:not(:last-child){margin-bottom:1rem}html.theme--catppuccin-mocha .buttons.are-small .button:not(.is-normal):not(.is-medium):not(.is-large){font-size:.75rem}html.theme--catppuccin-mocha .buttons.are-small .button:not(.is-normal):not(.is-medium):not(.is-large):not(.is-rounded){border-radius:3px}html.theme--catppuccin-mocha .buttons.are-medium .button:not(.is-small):not(.is-normal):not(.is-large){font-size:1.25rem}html.theme--catppuccin-mocha .buttons.are-large .button:not(.is-small):not(.is-normal):not(.is-medium){font-size:1.5rem}html.theme--catppuccin-mocha .buttons.has-addons .button:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}html.theme--catppuccin-mocha .buttons.has-addons .button:not(:last-child){border-bottom-right-radius:0;border-top-right-radius:0;margin-right:-1px}html.theme--catppuccin-mocha .buttons.has-addons .button:last-child{margin-right:0}html.theme--catppuccin-mocha .buttons.has-addons .button:hover,html.theme--catppuccin-mocha .buttons.has-addons .button.is-hovered{z-index:2}html.theme--catppuccin-mocha .buttons.has-addons .button:focus,html.theme--catppuccin-mocha .buttons.has-addons .button.is-focused,html.theme--catppuccin-mocha .buttons.has-addons .button:active,html.theme--catppuccin-mocha .buttons.has-addons .button.is-active,html.theme--catppuccin-mocha .buttons.has-addons .button.is-selected{z-index:3}html.theme--catppuccin-mocha .buttons.has-addons .button:focus:hover,html.theme--catppuccin-mocha .buttons.has-addons .button.is-focused:hover,html.theme--catppuccin-mocha .buttons.has-addons .button:active:hover,html.theme--catppuccin-mocha .buttons.has-addons .button.is-active:hover,html.theme--catppuccin-mocha .buttons.has-addons .button.is-selected:hover{z-index:4}html.theme--catppuccin-mocha .buttons.has-addons .button.is-expanded{flex-grow:1;flex-shrink:1}html.theme--catppuccin-mocha .buttons.is-centered{justify-content:center}html.theme--catppuccin-mocha .buttons.is-centered:not(.has-addons) .button:not(.is-fullwidth){margin-left:0.25rem;margin-right:0.25rem}html.theme--catppuccin-mocha .buttons.is-right{justify-content:flex-end}html.theme--catppuccin-mocha .buttons.is-right:not(.has-addons) .button:not(.is-fullwidth){margin-left:0.25rem;margin-right:0.25rem}@media screen and (max-width: 768px){html.theme--catppuccin-mocha .button.is-responsive.is-small,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-responsive{font-size:.5625rem}html.theme--catppuccin-mocha .button.is-responsive,html.theme--catppuccin-mocha .button.is-responsive.is-normal{font-size:.65625rem}html.theme--catppuccin-mocha .button.is-responsive.is-medium{font-size:.75rem}html.theme--catppuccin-mocha .button.is-responsive.is-large{font-size:1rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--catppuccin-mocha .button.is-responsive.is-small,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-responsive{font-size:.65625rem}html.theme--catppuccin-mocha .button.is-responsive,html.theme--catppuccin-mocha .button.is-responsive.is-normal{font-size:.75rem}html.theme--catppuccin-mocha .button.is-responsive.is-medium{font-size:1rem}html.theme--catppuccin-mocha .button.is-responsive.is-large{font-size:1.25rem}}html.theme--catppuccin-mocha .container{flex-grow:1;margin:0 auto;position:relative;width:auto}html.theme--catppuccin-mocha .container.is-fluid{max-width:none !important;padding-left:32px;padding-right:32px;width:100%}@media screen and (min-width: 1056px){html.theme--catppuccin-mocha .container{max-width:992px}}@media screen and (max-width: 1215px){html.theme--catppuccin-mocha .container.is-widescreen:not(.is-max-desktop){max-width:1152px}}@media screen and (max-width: 1407px){html.theme--catppuccin-mocha .container.is-fullhd:not(.is-max-desktop):not(.is-max-widescreen){max-width:1344px}}@media screen and (min-width: 1216px){html.theme--catppuccin-mocha .container:not(.is-max-desktop){max-width:1152px}}@media screen and (min-width: 1408px){html.theme--catppuccin-mocha .container:not(.is-max-desktop):not(.is-max-widescreen){max-width:1344px}}html.theme--catppuccin-mocha .content li+li{margin-top:0.25em}html.theme--catppuccin-mocha .content p:not(:last-child),html.theme--catppuccin-mocha .content dl:not(:last-child),html.theme--catppuccin-mocha .content ol:not(:last-child),html.theme--catppuccin-mocha .content ul:not(:last-child),html.theme--catppuccin-mocha .content blockquote:not(:last-child),html.theme--catppuccin-mocha .content pre:not(:last-child),html.theme--catppuccin-mocha .content table:not(:last-child){margin-bottom:1em}html.theme--catppuccin-mocha .content h1,html.theme--catppuccin-mocha .content h2,html.theme--catppuccin-mocha .content h3,html.theme--catppuccin-mocha .content h4,html.theme--catppuccin-mocha .content h5,html.theme--catppuccin-mocha .content h6{color:#cdd6f4;font-weight:600;line-height:1.125}html.theme--catppuccin-mocha .content h1{font-size:2em;margin-bottom:0.5em}html.theme--catppuccin-mocha .content h1:not(:first-child){margin-top:1em}html.theme--catppuccin-mocha .content h2{font-size:1.75em;margin-bottom:0.5714em}html.theme--catppuccin-mocha .content h2:not(:first-child){margin-top:1.1428em}html.theme--catppuccin-mocha .content h3{font-size:1.5em;margin-bottom:0.6666em}html.theme--catppuccin-mocha .content h3:not(:first-child){margin-top:1.3333em}html.theme--catppuccin-mocha .content h4{font-size:1.25em;margin-bottom:0.8em}html.theme--catppuccin-mocha .content h5{font-size:1.125em;margin-bottom:0.8888em}html.theme--catppuccin-mocha .content h6{font-size:1em;margin-bottom:1em}html.theme--catppuccin-mocha .content blockquote{background-color:#181825;border-left:5px solid #585b70;padding:1.25em 1.5em}html.theme--catppuccin-mocha .content ol{list-style-position:outside;margin-left:2em;margin-top:1em}html.theme--catppuccin-mocha .content ol:not([type]){list-style-type:decimal}html.theme--catppuccin-mocha .content ol.is-lower-alpha:not([type]){list-style-type:lower-alpha}html.theme--catppuccin-mocha .content ol.is-lower-roman:not([type]){list-style-type:lower-roman}html.theme--catppuccin-mocha .content ol.is-upper-alpha:not([type]){list-style-type:upper-alpha}html.theme--catppuccin-mocha .content ol.is-upper-roman:not([type]){list-style-type:upper-roman}html.theme--catppuccin-mocha .content ul{list-style:disc outside;margin-left:2em;margin-top:1em}html.theme--catppuccin-mocha .content ul ul{list-style-type:circle;margin-top:0.5em}html.theme--catppuccin-mocha .content ul ul ul{list-style-type:square}html.theme--catppuccin-mocha .content dd{margin-left:2em}html.theme--catppuccin-mocha .content figure{margin-left:2em;margin-right:2em;text-align:center}html.theme--catppuccin-mocha .content figure:not(:first-child){margin-top:2em}html.theme--catppuccin-mocha .content figure:not(:last-child){margin-bottom:2em}html.theme--catppuccin-mocha .content figure img{display:inline-block}html.theme--catppuccin-mocha .content figure figcaption{font-style:italic}html.theme--catppuccin-mocha .content pre{-webkit-overflow-scrolling:touch;overflow-x:auto;padding:0;white-space:pre;word-wrap:normal}html.theme--catppuccin-mocha .content sup,html.theme--catppuccin-mocha .content sub{font-size:75%}html.theme--catppuccin-mocha .content table{width:100%}html.theme--catppuccin-mocha .content table td,html.theme--catppuccin-mocha .content table th{border:1px solid #585b70;border-width:0 0 1px;padding:0.5em 0.75em;vertical-align:top}html.theme--catppuccin-mocha .content table th{color:#b8c5ef}html.theme--catppuccin-mocha .content table th:not([align]){text-align:inherit}html.theme--catppuccin-mocha .content table thead td,html.theme--catppuccin-mocha .content table thead th{border-width:0 0 2px;color:#b8c5ef}html.theme--catppuccin-mocha .content table tfoot td,html.theme--catppuccin-mocha .content table tfoot th{border-width:2px 0 0;color:#b8c5ef}html.theme--catppuccin-mocha .content table tbody tr:last-child td,html.theme--catppuccin-mocha .content table tbody tr:last-child th{border-bottom-width:0}html.theme--catppuccin-mocha .content .tabs li+li{margin-top:0}html.theme--catppuccin-mocha .content.is-small,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.content{font-size:.75rem}html.theme--catppuccin-mocha .content.is-normal{font-size:1rem}html.theme--catppuccin-mocha .content.is-medium{font-size:1.25rem}html.theme--catppuccin-mocha .content.is-large{font-size:1.5rem}html.theme--catppuccin-mocha .icon{align-items:center;display:inline-flex;justify-content:center;height:1.5rem;width:1.5rem}html.theme--catppuccin-mocha .icon.is-small,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.icon{height:1rem;width:1rem}html.theme--catppuccin-mocha .icon.is-medium{height:2rem;width:2rem}html.theme--catppuccin-mocha .icon.is-large{height:3rem;width:3rem}html.theme--catppuccin-mocha .icon-text{align-items:flex-start;color:inherit;display:inline-flex;flex-wrap:wrap;line-height:1.5rem;vertical-align:top}html.theme--catppuccin-mocha .icon-text .icon{flex-grow:0;flex-shrink:0}html.theme--catppuccin-mocha .icon-text .icon:not(:last-child){margin-right:.25em}html.theme--catppuccin-mocha .icon-text .icon:not(:first-child){margin-left:.25em}html.theme--catppuccin-mocha div.icon-text{display:flex}html.theme--catppuccin-mocha .image,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img{display:block;position:relative}html.theme--catppuccin-mocha .image img,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img img{display:block;height:auto;width:100%}html.theme--catppuccin-mocha .image img.is-rounded,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img img.is-rounded{border-radius:9999px}html.theme--catppuccin-mocha .image.is-fullwidth,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-fullwidth{width:100%}html.theme--catppuccin-mocha .image.is-square img,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-square img,html.theme--catppuccin-mocha .image.is-square .has-ratio,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-square .has-ratio,html.theme--catppuccin-mocha .image.is-1by1 img,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-1by1 img,html.theme--catppuccin-mocha .image.is-1by1 .has-ratio,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-1by1 .has-ratio,html.theme--catppuccin-mocha .image.is-5by4 img,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-5by4 img,html.theme--catppuccin-mocha .image.is-5by4 .has-ratio,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-5by4 .has-ratio,html.theme--catppuccin-mocha .image.is-4by3 img,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-4by3 img,html.theme--catppuccin-mocha .image.is-4by3 .has-ratio,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-4by3 .has-ratio,html.theme--catppuccin-mocha .image.is-3by2 img,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-3by2 img,html.theme--catppuccin-mocha .image.is-3by2 .has-ratio,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-3by2 .has-ratio,html.theme--catppuccin-mocha .image.is-5by3 img,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-5by3 img,html.theme--catppuccin-mocha .image.is-5by3 .has-ratio,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-5by3 .has-ratio,html.theme--catppuccin-mocha .image.is-16by9 img,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-16by9 img,html.theme--catppuccin-mocha .image.is-16by9 .has-ratio,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-16by9 .has-ratio,html.theme--catppuccin-mocha .image.is-2by1 img,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-2by1 img,html.theme--catppuccin-mocha .image.is-2by1 .has-ratio,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-2by1 .has-ratio,html.theme--catppuccin-mocha .image.is-3by1 img,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-3by1 img,html.theme--catppuccin-mocha .image.is-3by1 .has-ratio,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-3by1 .has-ratio,html.theme--catppuccin-mocha .image.is-4by5 img,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-4by5 img,html.theme--catppuccin-mocha .image.is-4by5 .has-ratio,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-4by5 .has-ratio,html.theme--catppuccin-mocha .image.is-3by4 img,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-3by4 img,html.theme--catppuccin-mocha .image.is-3by4 .has-ratio,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-3by4 .has-ratio,html.theme--catppuccin-mocha .image.is-2by3 img,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-2by3 img,html.theme--catppuccin-mocha .image.is-2by3 .has-ratio,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-2by3 .has-ratio,html.theme--catppuccin-mocha .image.is-3by5 img,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-3by5 img,html.theme--catppuccin-mocha .image.is-3by5 .has-ratio,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-3by5 .has-ratio,html.theme--catppuccin-mocha .image.is-9by16 img,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-9by16 img,html.theme--catppuccin-mocha .image.is-9by16 .has-ratio,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-9by16 .has-ratio,html.theme--catppuccin-mocha .image.is-1by2 img,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-1by2 img,html.theme--catppuccin-mocha .image.is-1by2 .has-ratio,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-1by2 .has-ratio,html.theme--catppuccin-mocha .image.is-1by3 img,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-1by3 img,html.theme--catppuccin-mocha .image.is-1by3 .has-ratio,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-1by3 .has-ratio{height:100%;width:100%}html.theme--catppuccin-mocha .image.is-square,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-square,html.theme--catppuccin-mocha .image.is-1by1,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-1by1{padding-top:100%}html.theme--catppuccin-mocha .image.is-5by4,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-5by4{padding-top:80%}html.theme--catppuccin-mocha .image.is-4by3,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-4by3{padding-top:75%}html.theme--catppuccin-mocha .image.is-3by2,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-3by2{padding-top:66.6666%}html.theme--catppuccin-mocha .image.is-5by3,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-5by3{padding-top:60%}html.theme--catppuccin-mocha .image.is-16by9,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-16by9{padding-top:56.25%}html.theme--catppuccin-mocha .image.is-2by1,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-2by1{padding-top:50%}html.theme--catppuccin-mocha .image.is-3by1,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-3by1{padding-top:33.3333%}html.theme--catppuccin-mocha .image.is-4by5,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-4by5{padding-top:125%}html.theme--catppuccin-mocha .image.is-3by4,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-3by4{padding-top:133.3333%}html.theme--catppuccin-mocha .image.is-2by3,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-2by3{padding-top:150%}html.theme--catppuccin-mocha .image.is-3by5,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-3by5{padding-top:166.6666%}html.theme--catppuccin-mocha .image.is-9by16,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-9by16{padding-top:177.7777%}html.theme--catppuccin-mocha .image.is-1by2,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-1by2{padding-top:200%}html.theme--catppuccin-mocha .image.is-1by3,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-1by3{padding-top:300%}html.theme--catppuccin-mocha .image.is-16x16,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-16x16{height:16px;width:16px}html.theme--catppuccin-mocha .image.is-24x24,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-24x24{height:24px;width:24px}html.theme--catppuccin-mocha .image.is-32x32,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-32x32{height:32px;width:32px}html.theme--catppuccin-mocha .image.is-48x48,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-48x48{height:48px;width:48px}html.theme--catppuccin-mocha .image.is-64x64,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-64x64{height:64px;width:64px}html.theme--catppuccin-mocha .image.is-96x96,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-96x96{height:96px;width:96px}html.theme--catppuccin-mocha .image.is-128x128,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-128x128{height:128px;width:128px}html.theme--catppuccin-mocha .notification{background-color:#181825;border-radius:.4em;position:relative;padding:1.25rem 2.5rem 1.25rem 1.5rem}html.theme--catppuccin-mocha .notification a:not(.button):not(.dropdown-item){color:currentColor;text-decoration:underline}html.theme--catppuccin-mocha .notification strong{color:currentColor}html.theme--catppuccin-mocha .notification code,html.theme--catppuccin-mocha .notification pre{background:#fff}html.theme--catppuccin-mocha .notification pre code{background:transparent}html.theme--catppuccin-mocha .notification>.delete{right:.5rem;position:absolute;top:0.5rem}html.theme--catppuccin-mocha .notification .title,html.theme--catppuccin-mocha .notification .subtitle,html.theme--catppuccin-mocha .notification .content{color:currentColor}html.theme--catppuccin-mocha .notification.is-white{background-color:#fff;color:#0a0a0a}html.theme--catppuccin-mocha .notification.is-black{background-color:#0a0a0a;color:#fff}html.theme--catppuccin-mocha .notification.is-light{background-color:#f5f5f5;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .notification.is-dark,html.theme--catppuccin-mocha .content kbd.notification{background-color:#313244;color:#fff}html.theme--catppuccin-mocha .notification.is-primary,html.theme--catppuccin-mocha .docstring>section>a.notification.docs-sourcelink{background-color:#89b4fa;color:#fff}html.theme--catppuccin-mocha .notification.is-primary.is-light,html.theme--catppuccin-mocha .docstring>section>a.notification.is-light.docs-sourcelink{background-color:#ebf3fe;color:#063c93}html.theme--catppuccin-mocha .notification.is-link{background-color:#89b4fa;color:#fff}html.theme--catppuccin-mocha .notification.is-link.is-light{background-color:#ebf3fe;color:#063c93}html.theme--catppuccin-mocha .notification.is-info{background-color:#94e2d5;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .notification.is-info.is-light{background-color:#effbf9;color:#207466}html.theme--catppuccin-mocha .notification.is-success{background-color:#a6e3a1;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .notification.is-success.is-light{background-color:#f0faef;color:#287222}html.theme--catppuccin-mocha .notification.is-warning{background-color:#f9e2af;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .notification.is-warning.is-light{background-color:#fef8ec;color:#8a620a}html.theme--catppuccin-mocha .notification.is-danger{background-color:#f38ba8;color:#fff}html.theme--catppuccin-mocha .notification.is-danger.is-light{background-color:#fdedf1;color:#991036}html.theme--catppuccin-mocha .progress{-moz-appearance:none;-webkit-appearance:none;border:none;border-radius:9999px;display:block;height:1rem;overflow:hidden;padding:0;width:100%}html.theme--catppuccin-mocha .progress::-webkit-progress-bar{background-color:#45475a}html.theme--catppuccin-mocha .progress::-webkit-progress-value{background-color:#7f849c}html.theme--catppuccin-mocha .progress::-moz-progress-bar{background-color:#7f849c}html.theme--catppuccin-mocha .progress::-ms-fill{background-color:#7f849c;border:none}html.theme--catppuccin-mocha .progress.is-white::-webkit-progress-value{background-color:#fff}html.theme--catppuccin-mocha .progress.is-white::-moz-progress-bar{background-color:#fff}html.theme--catppuccin-mocha .progress.is-white::-ms-fill{background-color:#fff}html.theme--catppuccin-mocha .progress.is-white:indeterminate{background-image:linear-gradient(to right, #fff 30%, #45475a 30%)}html.theme--catppuccin-mocha .progress.is-black::-webkit-progress-value{background-color:#0a0a0a}html.theme--catppuccin-mocha .progress.is-black::-moz-progress-bar{background-color:#0a0a0a}html.theme--catppuccin-mocha .progress.is-black::-ms-fill{background-color:#0a0a0a}html.theme--catppuccin-mocha .progress.is-black:indeterminate{background-image:linear-gradient(to right, #0a0a0a 30%, #45475a 30%)}html.theme--catppuccin-mocha .progress.is-light::-webkit-progress-value{background-color:#f5f5f5}html.theme--catppuccin-mocha .progress.is-light::-moz-progress-bar{background-color:#f5f5f5}html.theme--catppuccin-mocha .progress.is-light::-ms-fill{background-color:#f5f5f5}html.theme--catppuccin-mocha .progress.is-light:indeterminate{background-image:linear-gradient(to right, #f5f5f5 30%, #45475a 30%)}html.theme--catppuccin-mocha .progress.is-dark::-webkit-progress-value,html.theme--catppuccin-mocha .content kbd.progress::-webkit-progress-value{background-color:#313244}html.theme--catppuccin-mocha .progress.is-dark::-moz-progress-bar,html.theme--catppuccin-mocha .content kbd.progress::-moz-progress-bar{background-color:#313244}html.theme--catppuccin-mocha .progress.is-dark::-ms-fill,html.theme--catppuccin-mocha .content kbd.progress::-ms-fill{background-color:#313244}html.theme--catppuccin-mocha .progress.is-dark:indeterminate,html.theme--catppuccin-mocha .content kbd.progress:indeterminate{background-image:linear-gradient(to right, #313244 30%, #45475a 30%)}html.theme--catppuccin-mocha .progress.is-primary::-webkit-progress-value,html.theme--catppuccin-mocha .docstring>section>a.progress.docs-sourcelink::-webkit-progress-value{background-color:#89b4fa}html.theme--catppuccin-mocha .progress.is-primary::-moz-progress-bar,html.theme--catppuccin-mocha .docstring>section>a.progress.docs-sourcelink::-moz-progress-bar{background-color:#89b4fa}html.theme--catppuccin-mocha .progress.is-primary::-ms-fill,html.theme--catppuccin-mocha .docstring>section>a.progress.docs-sourcelink::-ms-fill{background-color:#89b4fa}html.theme--catppuccin-mocha .progress.is-primary:indeterminate,html.theme--catppuccin-mocha .docstring>section>a.progress.docs-sourcelink:indeterminate{background-image:linear-gradient(to right, #89b4fa 30%, #45475a 30%)}html.theme--catppuccin-mocha .progress.is-link::-webkit-progress-value{background-color:#89b4fa}html.theme--catppuccin-mocha .progress.is-link::-moz-progress-bar{background-color:#89b4fa}html.theme--catppuccin-mocha .progress.is-link::-ms-fill{background-color:#89b4fa}html.theme--catppuccin-mocha .progress.is-link:indeterminate{background-image:linear-gradient(to right, #89b4fa 30%, #45475a 30%)}html.theme--catppuccin-mocha .progress.is-info::-webkit-progress-value{background-color:#94e2d5}html.theme--catppuccin-mocha .progress.is-info::-moz-progress-bar{background-color:#94e2d5}html.theme--catppuccin-mocha .progress.is-info::-ms-fill{background-color:#94e2d5}html.theme--catppuccin-mocha .progress.is-info:indeterminate{background-image:linear-gradient(to right, #94e2d5 30%, #45475a 30%)}html.theme--catppuccin-mocha .progress.is-success::-webkit-progress-value{background-color:#a6e3a1}html.theme--catppuccin-mocha .progress.is-success::-moz-progress-bar{background-color:#a6e3a1}html.theme--catppuccin-mocha .progress.is-success::-ms-fill{background-color:#a6e3a1}html.theme--catppuccin-mocha .progress.is-success:indeterminate{background-image:linear-gradient(to right, #a6e3a1 30%, #45475a 30%)}html.theme--catppuccin-mocha .progress.is-warning::-webkit-progress-value{background-color:#f9e2af}html.theme--catppuccin-mocha .progress.is-warning::-moz-progress-bar{background-color:#f9e2af}html.theme--catppuccin-mocha .progress.is-warning::-ms-fill{background-color:#f9e2af}html.theme--catppuccin-mocha .progress.is-warning:indeterminate{background-image:linear-gradient(to right, #f9e2af 30%, #45475a 30%)}html.theme--catppuccin-mocha .progress.is-danger::-webkit-progress-value{background-color:#f38ba8}html.theme--catppuccin-mocha .progress.is-danger::-moz-progress-bar{background-color:#f38ba8}html.theme--catppuccin-mocha .progress.is-danger::-ms-fill{background-color:#f38ba8}html.theme--catppuccin-mocha .progress.is-danger:indeterminate{background-image:linear-gradient(to right, #f38ba8 30%, #45475a 30%)}html.theme--catppuccin-mocha .progress:indeterminate{animation-duration:1.5s;animation-iteration-count:infinite;animation-name:moveIndeterminate;animation-timing-function:linear;background-color:#45475a;background-image:linear-gradient(to right, #cdd6f4 30%, #45475a 30%);background-position:top left;background-repeat:no-repeat;background-size:150% 150%}html.theme--catppuccin-mocha .progress:indeterminate::-webkit-progress-bar{background-color:transparent}html.theme--catppuccin-mocha .progress:indeterminate::-moz-progress-bar{background-color:transparent}html.theme--catppuccin-mocha .progress:indeterminate::-ms-fill{animation-name:none}html.theme--catppuccin-mocha .progress.is-small,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.progress{height:.75rem}html.theme--catppuccin-mocha .progress.is-medium{height:1.25rem}html.theme--catppuccin-mocha .progress.is-large{height:1.5rem}@keyframes moveIndeterminate{from{background-position:200% 0}to{background-position:-200% 0}}html.theme--catppuccin-mocha .table{background-color:#45475a;color:#cdd6f4}html.theme--catppuccin-mocha .table td,html.theme--catppuccin-mocha .table th{border:1px solid #585b70;border-width:0 0 1px;padding:0.5em 0.75em;vertical-align:top}html.theme--catppuccin-mocha .table td.is-white,html.theme--catppuccin-mocha .table th.is-white{background-color:#fff;border-color:#fff;color:#0a0a0a}html.theme--catppuccin-mocha .table td.is-black,html.theme--catppuccin-mocha .table th.is-black{background-color:#0a0a0a;border-color:#0a0a0a;color:#fff}html.theme--catppuccin-mocha .table td.is-light,html.theme--catppuccin-mocha .table th.is-light{background-color:#f5f5f5;border-color:#f5f5f5;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .table td.is-dark,html.theme--catppuccin-mocha .table th.is-dark{background-color:#313244;border-color:#313244;color:#fff}html.theme--catppuccin-mocha .table td.is-primary,html.theme--catppuccin-mocha .table th.is-primary{background-color:#89b4fa;border-color:#89b4fa;color:#fff}html.theme--catppuccin-mocha .table td.is-link,html.theme--catppuccin-mocha .table th.is-link{background-color:#89b4fa;border-color:#89b4fa;color:#fff}html.theme--catppuccin-mocha .table td.is-info,html.theme--catppuccin-mocha .table th.is-info{background-color:#94e2d5;border-color:#94e2d5;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .table td.is-success,html.theme--catppuccin-mocha .table th.is-success{background-color:#a6e3a1;border-color:#a6e3a1;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .table td.is-warning,html.theme--catppuccin-mocha .table th.is-warning{background-color:#f9e2af;border-color:#f9e2af;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .table td.is-danger,html.theme--catppuccin-mocha .table th.is-danger{background-color:#f38ba8;border-color:#f38ba8;color:#fff}html.theme--catppuccin-mocha .table td.is-narrow,html.theme--catppuccin-mocha .table th.is-narrow{white-space:nowrap;width:1%}html.theme--catppuccin-mocha .table td.is-selected,html.theme--catppuccin-mocha .table th.is-selected{background-color:#89b4fa;color:#fff}html.theme--catppuccin-mocha .table td.is-selected a,html.theme--catppuccin-mocha .table td.is-selected strong,html.theme--catppuccin-mocha .table th.is-selected a,html.theme--catppuccin-mocha .table th.is-selected strong{color:currentColor}html.theme--catppuccin-mocha .table td.is-vcentered,html.theme--catppuccin-mocha .table th.is-vcentered{vertical-align:middle}html.theme--catppuccin-mocha .table th{color:#b8c5ef}html.theme--catppuccin-mocha .table th:not([align]){text-align:left}html.theme--catppuccin-mocha .table tr.is-selected{background-color:#89b4fa;color:#fff}html.theme--catppuccin-mocha .table tr.is-selected a,html.theme--catppuccin-mocha .table tr.is-selected strong{color:currentColor}html.theme--catppuccin-mocha .table tr.is-selected td,html.theme--catppuccin-mocha .table tr.is-selected th{border-color:#fff;color:currentColor}html.theme--catppuccin-mocha .table thead{background-color:rgba(0,0,0,0)}html.theme--catppuccin-mocha .table thead td,html.theme--catppuccin-mocha .table thead th{border-width:0 0 2px;color:#b8c5ef}html.theme--catppuccin-mocha .table tfoot{background-color:rgba(0,0,0,0)}html.theme--catppuccin-mocha .table tfoot td,html.theme--catppuccin-mocha .table tfoot th{border-width:2px 0 0;color:#b8c5ef}html.theme--catppuccin-mocha .table tbody{background-color:rgba(0,0,0,0)}html.theme--catppuccin-mocha .table tbody tr:last-child td,html.theme--catppuccin-mocha .table tbody tr:last-child th{border-bottom-width:0}html.theme--catppuccin-mocha .table.is-bordered td,html.theme--catppuccin-mocha .table.is-bordered th{border-width:1px}html.theme--catppuccin-mocha .table.is-bordered tr:last-child td,html.theme--catppuccin-mocha .table.is-bordered tr:last-child th{border-bottom-width:1px}html.theme--catppuccin-mocha .table.is-fullwidth{width:100%}html.theme--catppuccin-mocha .table.is-hoverable tbody tr:not(.is-selected):hover{background-color:#313244}html.theme--catppuccin-mocha .table.is-hoverable.is-striped tbody tr:not(.is-selected):hover{background-color:#313244}html.theme--catppuccin-mocha .table.is-hoverable.is-striped tbody tr:not(.is-selected):hover:nth-child(even){background-color:#35364a}html.theme--catppuccin-mocha .table.is-narrow td,html.theme--catppuccin-mocha .table.is-narrow th{padding:0.25em 0.5em}html.theme--catppuccin-mocha .table.is-striped tbody tr:not(.is-selected):nth-child(even){background-color:#313244}html.theme--catppuccin-mocha .table-container{-webkit-overflow-scrolling:touch;overflow:auto;overflow-y:hidden;max-width:100%}html.theme--catppuccin-mocha .tags{align-items:center;display:flex;flex-wrap:wrap;justify-content:flex-start}html.theme--catppuccin-mocha .tags .tag,html.theme--catppuccin-mocha .tags .content kbd,html.theme--catppuccin-mocha .content .tags kbd,html.theme--catppuccin-mocha .tags .docstring>section>a.docs-sourcelink{margin-bottom:0.5rem}html.theme--catppuccin-mocha .tags .tag:not(:last-child),html.theme--catppuccin-mocha .tags .content kbd:not(:last-child),html.theme--catppuccin-mocha .content .tags kbd:not(:last-child),html.theme--catppuccin-mocha .tags .docstring>section>a.docs-sourcelink:not(:last-child){margin-right:.5rem}html.theme--catppuccin-mocha .tags:last-child{margin-bottom:-0.5rem}html.theme--catppuccin-mocha .tags:not(:last-child){margin-bottom:1rem}html.theme--catppuccin-mocha .tags.are-medium .tag:not(.is-normal):not(.is-large),html.theme--catppuccin-mocha .tags.are-medium .content kbd:not(.is-normal):not(.is-large),html.theme--catppuccin-mocha .content .tags.are-medium kbd:not(.is-normal):not(.is-large),html.theme--catppuccin-mocha .tags.are-medium .docstring>section>a.docs-sourcelink:not(.is-normal):not(.is-large){font-size:1rem}html.theme--catppuccin-mocha .tags.are-large .tag:not(.is-normal):not(.is-medium),html.theme--catppuccin-mocha .tags.are-large .content kbd:not(.is-normal):not(.is-medium),html.theme--catppuccin-mocha .content .tags.are-large kbd:not(.is-normal):not(.is-medium),html.theme--catppuccin-mocha .tags.are-large .docstring>section>a.docs-sourcelink:not(.is-normal):not(.is-medium){font-size:1.25rem}html.theme--catppuccin-mocha .tags.is-centered{justify-content:center}html.theme--catppuccin-mocha .tags.is-centered .tag,html.theme--catppuccin-mocha .tags.is-centered .content kbd,html.theme--catppuccin-mocha .content .tags.is-centered kbd,html.theme--catppuccin-mocha .tags.is-centered .docstring>section>a.docs-sourcelink{margin-right:0.25rem;margin-left:0.25rem}html.theme--catppuccin-mocha .tags.is-right{justify-content:flex-end}html.theme--catppuccin-mocha .tags.is-right .tag:not(:first-child),html.theme--catppuccin-mocha .tags.is-right .content kbd:not(:first-child),html.theme--catppuccin-mocha .content .tags.is-right kbd:not(:first-child),html.theme--catppuccin-mocha .tags.is-right .docstring>section>a.docs-sourcelink:not(:first-child){margin-left:0.5rem}html.theme--catppuccin-mocha .tags.is-right .tag:not(:last-child),html.theme--catppuccin-mocha .tags.is-right .content kbd:not(:last-child),html.theme--catppuccin-mocha .content .tags.is-right kbd:not(:last-child),html.theme--catppuccin-mocha .tags.is-right .docstring>section>a.docs-sourcelink:not(:last-child){margin-right:0}html.theme--catppuccin-mocha .tags.has-addons .tag,html.theme--catppuccin-mocha .tags.has-addons .content kbd,html.theme--catppuccin-mocha .content .tags.has-addons kbd,html.theme--catppuccin-mocha .tags.has-addons .docstring>section>a.docs-sourcelink{margin-right:0}html.theme--catppuccin-mocha .tags.has-addons .tag:not(:first-child),html.theme--catppuccin-mocha .tags.has-addons .content kbd:not(:first-child),html.theme--catppuccin-mocha .content .tags.has-addons kbd:not(:first-child),html.theme--catppuccin-mocha .tags.has-addons .docstring>section>a.docs-sourcelink:not(:first-child){margin-left:0;border-top-left-radius:0;border-bottom-left-radius:0}html.theme--catppuccin-mocha .tags.has-addons .tag:not(:last-child),html.theme--catppuccin-mocha .tags.has-addons .content kbd:not(:last-child),html.theme--catppuccin-mocha .content .tags.has-addons kbd:not(:last-child),html.theme--catppuccin-mocha .tags.has-addons .docstring>section>a.docs-sourcelink:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}html.theme--catppuccin-mocha .tag:not(body),html.theme--catppuccin-mocha .content kbd:not(body),html.theme--catppuccin-mocha .docstring>section>a.docs-sourcelink:not(body){align-items:center;background-color:#181825;border-radius:.4em;color:#cdd6f4;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}html.theme--catppuccin-mocha .tag:not(body) .delete,html.theme--catppuccin-mocha .content kbd:not(body) .delete,html.theme--catppuccin-mocha .docstring>section>a.docs-sourcelink:not(body) .delete{margin-left:.25rem;margin-right:-.375rem}html.theme--catppuccin-mocha .tag.is-white:not(body),html.theme--catppuccin-mocha .content kbd.is-white:not(body),html.theme--catppuccin-mocha .docstring>section>a.docs-sourcelink.is-white:not(body){background-color:#fff;color:#0a0a0a}html.theme--catppuccin-mocha .tag.is-black:not(body),html.theme--catppuccin-mocha .content kbd.is-black:not(body),html.theme--catppuccin-mocha .docstring>section>a.docs-sourcelink.is-black:not(body){background-color:#0a0a0a;color:#fff}html.theme--catppuccin-mocha .tag.is-light:not(body),html.theme--catppuccin-mocha .content kbd.is-light:not(body),html.theme--catppuccin-mocha .docstring>section>a.docs-sourcelink.is-light:not(body){background-color:#f5f5f5;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .tag.is-dark:not(body),html.theme--catppuccin-mocha .content kbd:not(body),html.theme--catppuccin-mocha .docstring>section>a.docs-sourcelink.is-dark:not(body),html.theme--catppuccin-mocha .content .docstring>section>kbd:not(body){background-color:#313244;color:#fff}html.theme--catppuccin-mocha .tag.is-primary:not(body),html.theme--catppuccin-mocha .content kbd.is-primary:not(body),html.theme--catppuccin-mocha .docstring>section>a.docs-sourcelink:not(body){background-color:#89b4fa;color:#fff}html.theme--catppuccin-mocha .tag.is-primary.is-light:not(body),html.theme--catppuccin-mocha .content kbd.is-primary.is-light:not(body),html.theme--catppuccin-mocha .docstring>section>a.docs-sourcelink.is-light:not(body){background-color:#ebf3fe;color:#063c93}html.theme--catppuccin-mocha .tag.is-link:not(body),html.theme--catppuccin-mocha .content kbd.is-link:not(body),html.theme--catppuccin-mocha .docstring>section>a.docs-sourcelink.is-link:not(body){background-color:#89b4fa;color:#fff}html.theme--catppuccin-mocha .tag.is-link.is-light:not(body),html.theme--catppuccin-mocha .content kbd.is-link.is-light:not(body),html.theme--catppuccin-mocha .docstring>section>a.docs-sourcelink.is-link.is-light:not(body){background-color:#ebf3fe;color:#063c93}html.theme--catppuccin-mocha .tag.is-info:not(body),html.theme--catppuccin-mocha .content kbd.is-info:not(body),html.theme--catppuccin-mocha .docstring>section>a.docs-sourcelink.is-info:not(body){background-color:#94e2d5;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .tag.is-info.is-light:not(body),html.theme--catppuccin-mocha .content kbd.is-info.is-light:not(body),html.theme--catppuccin-mocha .docstring>section>a.docs-sourcelink.is-info.is-light:not(body){background-color:#effbf9;color:#207466}html.theme--catppuccin-mocha .tag.is-success:not(body),html.theme--catppuccin-mocha .content kbd.is-success:not(body),html.theme--catppuccin-mocha .docstring>section>a.docs-sourcelink.is-success:not(body){background-color:#a6e3a1;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .tag.is-success.is-light:not(body),html.theme--catppuccin-mocha .content kbd.is-success.is-light:not(body),html.theme--catppuccin-mocha .docstring>section>a.docs-sourcelink.is-success.is-light:not(body){background-color:#f0faef;color:#287222}html.theme--catppuccin-mocha .tag.is-warning:not(body),html.theme--catppuccin-mocha .content kbd.is-warning:not(body),html.theme--catppuccin-mocha .docstring>section>a.docs-sourcelink.is-warning:not(body){background-color:#f9e2af;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .tag.is-warning.is-light:not(body),html.theme--catppuccin-mocha .content kbd.is-warning.is-light:not(body),html.theme--catppuccin-mocha .docstring>section>a.docs-sourcelink.is-warning.is-light:not(body){background-color:#fef8ec;color:#8a620a}html.theme--catppuccin-mocha .tag.is-danger:not(body),html.theme--catppuccin-mocha .content kbd.is-danger:not(body),html.theme--catppuccin-mocha .docstring>section>a.docs-sourcelink.is-danger:not(body){background-color:#f38ba8;color:#fff}html.theme--catppuccin-mocha .tag.is-danger.is-light:not(body),html.theme--catppuccin-mocha .content kbd.is-danger.is-light:not(body),html.theme--catppuccin-mocha .docstring>section>a.docs-sourcelink.is-danger.is-light:not(body){background-color:#fdedf1;color:#991036}html.theme--catppuccin-mocha .tag.is-normal:not(body),html.theme--catppuccin-mocha .content kbd.is-normal:not(body),html.theme--catppuccin-mocha .docstring>section>a.docs-sourcelink.is-normal:not(body){font-size:.75rem}html.theme--catppuccin-mocha .tag.is-medium:not(body),html.theme--catppuccin-mocha .content kbd.is-medium:not(body),html.theme--catppuccin-mocha .docstring>section>a.docs-sourcelink.is-medium:not(body){font-size:1rem}html.theme--catppuccin-mocha .tag.is-large:not(body),html.theme--catppuccin-mocha .content kbd.is-large:not(body),html.theme--catppuccin-mocha .docstring>section>a.docs-sourcelink.is-large:not(body){font-size:1.25rem}html.theme--catppuccin-mocha .tag:not(body) .icon:first-child:not(:last-child),html.theme--catppuccin-mocha .content kbd:not(body) .icon:first-child:not(:last-child),html.theme--catppuccin-mocha .docstring>section>a.docs-sourcelink:not(body) .icon:first-child:not(:last-child){margin-left:-.375em;margin-right:.1875em}html.theme--catppuccin-mocha .tag:not(body) .icon:last-child:not(:first-child),html.theme--catppuccin-mocha .content kbd:not(body) .icon:last-child:not(:first-child),html.theme--catppuccin-mocha .docstring>section>a.docs-sourcelink:not(body) .icon:last-child:not(:first-child){margin-left:.1875em;margin-right:-.375em}html.theme--catppuccin-mocha .tag:not(body) .icon:first-child:last-child,html.theme--catppuccin-mocha .content kbd:not(body) .icon:first-child:last-child,html.theme--catppuccin-mocha .docstring>section>a.docs-sourcelink:not(body) .icon:first-child:last-child{margin-left:-.375em;margin-right:-.375em}html.theme--catppuccin-mocha .tag.is-delete:not(body),html.theme--catppuccin-mocha .content kbd.is-delete:not(body),html.theme--catppuccin-mocha .docstring>section>a.docs-sourcelink.is-delete:not(body){margin-left:1px;padding:0;position:relative;width:2em}html.theme--catppuccin-mocha .tag.is-delete:not(body)::before,html.theme--catppuccin-mocha .content kbd.is-delete:not(body)::before,html.theme--catppuccin-mocha .docstring>section>a.docs-sourcelink.is-delete:not(body)::before,html.theme--catppuccin-mocha .tag.is-delete:not(body)::after,html.theme--catppuccin-mocha .content kbd.is-delete:not(body)::after,html.theme--catppuccin-mocha .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--catppuccin-mocha .tag.is-delete:not(body)::before,html.theme--catppuccin-mocha .content kbd.is-delete:not(body)::before,html.theme--catppuccin-mocha .docstring>section>a.docs-sourcelink.is-delete:not(body)::before{height:1px;width:50%}html.theme--catppuccin-mocha .tag.is-delete:not(body)::after,html.theme--catppuccin-mocha .content kbd.is-delete:not(body)::after,html.theme--catppuccin-mocha .docstring>section>a.docs-sourcelink.is-delete:not(body)::after{height:50%;width:1px}html.theme--catppuccin-mocha .tag.is-delete:not(body):hover,html.theme--catppuccin-mocha .content kbd.is-delete:not(body):hover,html.theme--catppuccin-mocha .docstring>section>a.docs-sourcelink.is-delete:not(body):hover,html.theme--catppuccin-mocha .tag.is-delete:not(body):focus,html.theme--catppuccin-mocha .content kbd.is-delete:not(body):focus,html.theme--catppuccin-mocha .docstring>section>a.docs-sourcelink.is-delete:not(body):focus{background-color:#0e0e16}html.theme--catppuccin-mocha .tag.is-delete:not(body):active,html.theme--catppuccin-mocha .content kbd.is-delete:not(body):active,html.theme--catppuccin-mocha .docstring>section>a.docs-sourcelink.is-delete:not(body):active{background-color:#040406}html.theme--catppuccin-mocha .tag.is-rounded:not(body),html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input:not(body),html.theme--catppuccin-mocha .content kbd.is-rounded:not(body),html.theme--catppuccin-mocha #documenter .docs-sidebar .content form.docs-search>input:not(body),html.theme--catppuccin-mocha .docstring>section>a.docs-sourcelink.is-rounded:not(body){border-radius:9999px}html.theme--catppuccin-mocha a.tag:hover,html.theme--catppuccin-mocha .docstring>section>a.docs-sourcelink:hover{text-decoration:underline}html.theme--catppuccin-mocha .title,html.theme--catppuccin-mocha .subtitle{word-break:break-word}html.theme--catppuccin-mocha .title em,html.theme--catppuccin-mocha .title span,html.theme--catppuccin-mocha .subtitle em,html.theme--catppuccin-mocha .subtitle span{font-weight:inherit}html.theme--catppuccin-mocha .title sub,html.theme--catppuccin-mocha .subtitle sub{font-size:.75em}html.theme--catppuccin-mocha .title sup,html.theme--catppuccin-mocha .subtitle sup{font-size:.75em}html.theme--catppuccin-mocha .title .tag,html.theme--catppuccin-mocha .title .content kbd,html.theme--catppuccin-mocha .content .title kbd,html.theme--catppuccin-mocha .title .docstring>section>a.docs-sourcelink,html.theme--catppuccin-mocha .subtitle .tag,html.theme--catppuccin-mocha .subtitle .content kbd,html.theme--catppuccin-mocha .content .subtitle kbd,html.theme--catppuccin-mocha .subtitle .docstring>section>a.docs-sourcelink{vertical-align:middle}html.theme--catppuccin-mocha .title{color:#fff;font-size:2rem;font-weight:500;line-height:1.125}html.theme--catppuccin-mocha .title strong{color:inherit;font-weight:inherit}html.theme--catppuccin-mocha .title:not(.is-spaced)+.subtitle{margin-top:-1.25rem}html.theme--catppuccin-mocha .title.is-1{font-size:3rem}html.theme--catppuccin-mocha .title.is-2{font-size:2.5rem}html.theme--catppuccin-mocha .title.is-3{font-size:2rem}html.theme--catppuccin-mocha .title.is-4{font-size:1.5rem}html.theme--catppuccin-mocha .title.is-5{font-size:1.25rem}html.theme--catppuccin-mocha .title.is-6{font-size:1rem}html.theme--catppuccin-mocha .title.is-7{font-size:.75rem}html.theme--catppuccin-mocha .subtitle{color:#6c7086;font-size:1.25rem;font-weight:400;line-height:1.25}html.theme--catppuccin-mocha .subtitle strong{color:#6c7086;font-weight:600}html.theme--catppuccin-mocha .subtitle:not(.is-spaced)+.title{margin-top:-1.25rem}html.theme--catppuccin-mocha .subtitle.is-1{font-size:3rem}html.theme--catppuccin-mocha .subtitle.is-2{font-size:2.5rem}html.theme--catppuccin-mocha .subtitle.is-3{font-size:2rem}html.theme--catppuccin-mocha .subtitle.is-4{font-size:1.5rem}html.theme--catppuccin-mocha .subtitle.is-5{font-size:1.25rem}html.theme--catppuccin-mocha .subtitle.is-6{font-size:1rem}html.theme--catppuccin-mocha .subtitle.is-7{font-size:.75rem}html.theme--catppuccin-mocha .heading{display:block;font-size:11px;letter-spacing:1px;margin-bottom:5px;text-transform:uppercase}html.theme--catppuccin-mocha .number{align-items:center;background-color:#181825;border-radius:9999px;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--catppuccin-mocha .select select,html.theme--catppuccin-mocha .textarea,html.theme--catppuccin-mocha .input,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input{background-color:#1e1e2e;border-color:#585b70;border-radius:.4em;color:#7f849c}html.theme--catppuccin-mocha .select select::-moz-placeholder,html.theme--catppuccin-mocha .textarea::-moz-placeholder,html.theme--catppuccin-mocha .input::-moz-placeholder,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input::-moz-placeholder{color:#868c98}html.theme--catppuccin-mocha .select select::-webkit-input-placeholder,html.theme--catppuccin-mocha .textarea::-webkit-input-placeholder,html.theme--catppuccin-mocha .input::-webkit-input-placeholder,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input::-webkit-input-placeholder{color:#868c98}html.theme--catppuccin-mocha .select select:-moz-placeholder,html.theme--catppuccin-mocha .textarea:-moz-placeholder,html.theme--catppuccin-mocha .input:-moz-placeholder,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input:-moz-placeholder{color:#868c98}html.theme--catppuccin-mocha .select select:-ms-input-placeholder,html.theme--catppuccin-mocha .textarea:-ms-input-placeholder,html.theme--catppuccin-mocha .input:-ms-input-placeholder,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input:-ms-input-placeholder{color:#868c98}html.theme--catppuccin-mocha .select select:hover,html.theme--catppuccin-mocha .textarea:hover,html.theme--catppuccin-mocha .input:hover,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input:hover,html.theme--catppuccin-mocha .select select.is-hovered,html.theme--catppuccin-mocha .is-hovered.textarea,html.theme--catppuccin-mocha .is-hovered.input,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-hovered{border-color:#6c7086}html.theme--catppuccin-mocha .select select:focus,html.theme--catppuccin-mocha .textarea:focus,html.theme--catppuccin-mocha .input:focus,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input:focus,html.theme--catppuccin-mocha .select select.is-focused,html.theme--catppuccin-mocha .is-focused.textarea,html.theme--catppuccin-mocha .is-focused.input,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--catppuccin-mocha .select select:active,html.theme--catppuccin-mocha .textarea:active,html.theme--catppuccin-mocha .input:active,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input:active,html.theme--catppuccin-mocha .select select.is-active,html.theme--catppuccin-mocha .is-active.textarea,html.theme--catppuccin-mocha .is-active.input,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-active{border-color:#89b4fa;box-shadow:0 0 0 0.125em rgba(137,180,250,0.25)}html.theme--catppuccin-mocha .select select[disabled],html.theme--catppuccin-mocha .textarea[disabled],html.theme--catppuccin-mocha .input[disabled],html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input[disabled],fieldset[disabled] html.theme--catppuccin-mocha .select select,fieldset[disabled] html.theme--catppuccin-mocha .textarea,fieldset[disabled] html.theme--catppuccin-mocha .input,fieldset[disabled] html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input{background-color:#6c7086;border-color:#181825;box-shadow:none;color:#f7f8fd}html.theme--catppuccin-mocha .select select[disabled]::-moz-placeholder,html.theme--catppuccin-mocha .textarea[disabled]::-moz-placeholder,html.theme--catppuccin-mocha .input[disabled]::-moz-placeholder,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input[disabled]::-moz-placeholder,fieldset[disabled] html.theme--catppuccin-mocha .select select::-moz-placeholder,fieldset[disabled] html.theme--catppuccin-mocha .textarea::-moz-placeholder,fieldset[disabled] html.theme--catppuccin-mocha .input::-moz-placeholder,fieldset[disabled] html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input::-moz-placeholder{color:rgba(247,248,253,0.3)}html.theme--catppuccin-mocha .select select[disabled]::-webkit-input-placeholder,html.theme--catppuccin-mocha .textarea[disabled]::-webkit-input-placeholder,html.theme--catppuccin-mocha .input[disabled]::-webkit-input-placeholder,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input[disabled]::-webkit-input-placeholder,fieldset[disabled] html.theme--catppuccin-mocha .select select::-webkit-input-placeholder,fieldset[disabled] html.theme--catppuccin-mocha .textarea::-webkit-input-placeholder,fieldset[disabled] html.theme--catppuccin-mocha .input::-webkit-input-placeholder,fieldset[disabled] html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input::-webkit-input-placeholder{color:rgba(247,248,253,0.3)}html.theme--catppuccin-mocha .select select[disabled]:-moz-placeholder,html.theme--catppuccin-mocha .textarea[disabled]:-moz-placeholder,html.theme--catppuccin-mocha .input[disabled]:-moz-placeholder,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input[disabled]:-moz-placeholder,fieldset[disabled] html.theme--catppuccin-mocha .select select:-moz-placeholder,fieldset[disabled] html.theme--catppuccin-mocha .textarea:-moz-placeholder,fieldset[disabled] html.theme--catppuccin-mocha .input:-moz-placeholder,fieldset[disabled] html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input:-moz-placeholder{color:rgba(247,248,253,0.3)}html.theme--catppuccin-mocha .select select[disabled]:-ms-input-placeholder,html.theme--catppuccin-mocha .textarea[disabled]:-ms-input-placeholder,html.theme--catppuccin-mocha .input[disabled]:-ms-input-placeholder,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input[disabled]:-ms-input-placeholder,fieldset[disabled] html.theme--catppuccin-mocha .select select:-ms-input-placeholder,fieldset[disabled] html.theme--catppuccin-mocha .textarea:-ms-input-placeholder,fieldset[disabled] html.theme--catppuccin-mocha .input:-ms-input-placeholder,fieldset[disabled] html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input:-ms-input-placeholder{color:rgba(247,248,253,0.3)}html.theme--catppuccin-mocha .textarea,html.theme--catppuccin-mocha .input,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input{box-shadow:inset 0 0.0625em 0.125em rgba(10,10,10,0.05);max-width:100%;width:100%}html.theme--catppuccin-mocha .textarea[readonly],html.theme--catppuccin-mocha .input[readonly],html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input[readonly]{box-shadow:none}html.theme--catppuccin-mocha .is-white.textarea,html.theme--catppuccin-mocha .is-white.input,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-white{border-color:#fff}html.theme--catppuccin-mocha .is-white.textarea:focus,html.theme--catppuccin-mocha .is-white.input:focus,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-white:focus,html.theme--catppuccin-mocha .is-white.is-focused.textarea,html.theme--catppuccin-mocha .is-white.is-focused.input,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--catppuccin-mocha .is-white.textarea:active,html.theme--catppuccin-mocha .is-white.input:active,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-white:active,html.theme--catppuccin-mocha .is-white.is-active.textarea,html.theme--catppuccin-mocha .is-white.is-active.input,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(255,255,255,0.25)}html.theme--catppuccin-mocha .is-black.textarea,html.theme--catppuccin-mocha .is-black.input,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-black{border-color:#0a0a0a}html.theme--catppuccin-mocha .is-black.textarea:focus,html.theme--catppuccin-mocha .is-black.input:focus,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-black:focus,html.theme--catppuccin-mocha .is-black.is-focused.textarea,html.theme--catppuccin-mocha .is-black.is-focused.input,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--catppuccin-mocha .is-black.textarea:active,html.theme--catppuccin-mocha .is-black.input:active,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-black:active,html.theme--catppuccin-mocha .is-black.is-active.textarea,html.theme--catppuccin-mocha .is-black.is-active.input,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(10,10,10,0.25)}html.theme--catppuccin-mocha .is-light.textarea,html.theme--catppuccin-mocha .is-light.input,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-light{border-color:#f5f5f5}html.theme--catppuccin-mocha .is-light.textarea:focus,html.theme--catppuccin-mocha .is-light.input:focus,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-light:focus,html.theme--catppuccin-mocha .is-light.is-focused.textarea,html.theme--catppuccin-mocha .is-light.is-focused.input,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--catppuccin-mocha .is-light.textarea:active,html.theme--catppuccin-mocha .is-light.input:active,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-light:active,html.theme--catppuccin-mocha .is-light.is-active.textarea,html.theme--catppuccin-mocha .is-light.is-active.input,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(245,245,245,0.25)}html.theme--catppuccin-mocha .is-dark.textarea,html.theme--catppuccin-mocha .content kbd.textarea,html.theme--catppuccin-mocha .is-dark.input,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-dark,html.theme--catppuccin-mocha .content kbd.input{border-color:#313244}html.theme--catppuccin-mocha .is-dark.textarea:focus,html.theme--catppuccin-mocha .content kbd.textarea:focus,html.theme--catppuccin-mocha .is-dark.input:focus,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-dark:focus,html.theme--catppuccin-mocha .content kbd.input:focus,html.theme--catppuccin-mocha .is-dark.is-focused.textarea,html.theme--catppuccin-mocha .content kbd.is-focused.textarea,html.theme--catppuccin-mocha .is-dark.is-focused.input,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--catppuccin-mocha .content kbd.is-focused.input,html.theme--catppuccin-mocha #documenter .docs-sidebar .content form.docs-search>input.is-focused,html.theme--catppuccin-mocha .is-dark.textarea:active,html.theme--catppuccin-mocha .content kbd.textarea:active,html.theme--catppuccin-mocha .is-dark.input:active,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-dark:active,html.theme--catppuccin-mocha .content kbd.input:active,html.theme--catppuccin-mocha .is-dark.is-active.textarea,html.theme--catppuccin-mocha .content kbd.is-active.textarea,html.theme--catppuccin-mocha .is-dark.is-active.input,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-active,html.theme--catppuccin-mocha .content kbd.is-active.input,html.theme--catppuccin-mocha #documenter .docs-sidebar .content form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(49,50,68,0.25)}html.theme--catppuccin-mocha .is-primary.textarea,html.theme--catppuccin-mocha .docstring>section>a.textarea.docs-sourcelink,html.theme--catppuccin-mocha .is-primary.input,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-primary,html.theme--catppuccin-mocha .docstring>section>a.input.docs-sourcelink{border-color:#89b4fa}html.theme--catppuccin-mocha .is-primary.textarea:focus,html.theme--catppuccin-mocha .docstring>section>a.textarea.docs-sourcelink:focus,html.theme--catppuccin-mocha .is-primary.input:focus,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-primary:focus,html.theme--catppuccin-mocha .docstring>section>a.input.docs-sourcelink:focus,html.theme--catppuccin-mocha .is-primary.is-focused.textarea,html.theme--catppuccin-mocha .docstring>section>a.is-focused.textarea.docs-sourcelink,html.theme--catppuccin-mocha .is-primary.is-focused.input,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--catppuccin-mocha .docstring>section>a.is-focused.input.docs-sourcelink,html.theme--catppuccin-mocha .is-primary.textarea:active,html.theme--catppuccin-mocha .docstring>section>a.textarea.docs-sourcelink:active,html.theme--catppuccin-mocha .is-primary.input:active,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-primary:active,html.theme--catppuccin-mocha .docstring>section>a.input.docs-sourcelink:active,html.theme--catppuccin-mocha .is-primary.is-active.textarea,html.theme--catppuccin-mocha .docstring>section>a.is-active.textarea.docs-sourcelink,html.theme--catppuccin-mocha .is-primary.is-active.input,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-active,html.theme--catppuccin-mocha .docstring>section>a.is-active.input.docs-sourcelink{box-shadow:0 0 0 0.125em rgba(137,180,250,0.25)}html.theme--catppuccin-mocha .is-link.textarea,html.theme--catppuccin-mocha .is-link.input,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-link{border-color:#89b4fa}html.theme--catppuccin-mocha .is-link.textarea:focus,html.theme--catppuccin-mocha .is-link.input:focus,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-link:focus,html.theme--catppuccin-mocha .is-link.is-focused.textarea,html.theme--catppuccin-mocha .is-link.is-focused.input,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--catppuccin-mocha .is-link.textarea:active,html.theme--catppuccin-mocha .is-link.input:active,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-link:active,html.theme--catppuccin-mocha .is-link.is-active.textarea,html.theme--catppuccin-mocha .is-link.is-active.input,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(137,180,250,0.25)}html.theme--catppuccin-mocha .is-info.textarea,html.theme--catppuccin-mocha .is-info.input,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-info{border-color:#94e2d5}html.theme--catppuccin-mocha .is-info.textarea:focus,html.theme--catppuccin-mocha .is-info.input:focus,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-info:focus,html.theme--catppuccin-mocha .is-info.is-focused.textarea,html.theme--catppuccin-mocha .is-info.is-focused.input,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--catppuccin-mocha .is-info.textarea:active,html.theme--catppuccin-mocha .is-info.input:active,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-info:active,html.theme--catppuccin-mocha .is-info.is-active.textarea,html.theme--catppuccin-mocha .is-info.is-active.input,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(148,226,213,0.25)}html.theme--catppuccin-mocha .is-success.textarea,html.theme--catppuccin-mocha .is-success.input,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-success{border-color:#a6e3a1}html.theme--catppuccin-mocha .is-success.textarea:focus,html.theme--catppuccin-mocha .is-success.input:focus,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-success:focus,html.theme--catppuccin-mocha .is-success.is-focused.textarea,html.theme--catppuccin-mocha .is-success.is-focused.input,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--catppuccin-mocha .is-success.textarea:active,html.theme--catppuccin-mocha .is-success.input:active,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-success:active,html.theme--catppuccin-mocha .is-success.is-active.textarea,html.theme--catppuccin-mocha .is-success.is-active.input,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(166,227,161,0.25)}html.theme--catppuccin-mocha .is-warning.textarea,html.theme--catppuccin-mocha .is-warning.input,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-warning{border-color:#f9e2af}html.theme--catppuccin-mocha .is-warning.textarea:focus,html.theme--catppuccin-mocha .is-warning.input:focus,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-warning:focus,html.theme--catppuccin-mocha .is-warning.is-focused.textarea,html.theme--catppuccin-mocha .is-warning.is-focused.input,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--catppuccin-mocha .is-warning.textarea:active,html.theme--catppuccin-mocha .is-warning.input:active,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-warning:active,html.theme--catppuccin-mocha .is-warning.is-active.textarea,html.theme--catppuccin-mocha .is-warning.is-active.input,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(249,226,175,0.25)}html.theme--catppuccin-mocha .is-danger.textarea,html.theme--catppuccin-mocha .is-danger.input,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-danger{border-color:#f38ba8}html.theme--catppuccin-mocha .is-danger.textarea:focus,html.theme--catppuccin-mocha .is-danger.input:focus,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-danger:focus,html.theme--catppuccin-mocha .is-danger.is-focused.textarea,html.theme--catppuccin-mocha .is-danger.is-focused.input,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--catppuccin-mocha .is-danger.textarea:active,html.theme--catppuccin-mocha .is-danger.input:active,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-danger:active,html.theme--catppuccin-mocha .is-danger.is-active.textarea,html.theme--catppuccin-mocha .is-danger.is-active.input,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(243,139,168,0.25)}html.theme--catppuccin-mocha .is-small.textarea,html.theme--catppuccin-mocha .is-small.input,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input{border-radius:3px;font-size:.75rem}html.theme--catppuccin-mocha .is-medium.textarea,html.theme--catppuccin-mocha .is-medium.input,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-medium{font-size:1.25rem}html.theme--catppuccin-mocha .is-large.textarea,html.theme--catppuccin-mocha .is-large.input,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-large{font-size:1.5rem}html.theme--catppuccin-mocha .is-fullwidth.textarea,html.theme--catppuccin-mocha .is-fullwidth.input,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-fullwidth{display:block;width:100%}html.theme--catppuccin-mocha .is-inline.textarea,html.theme--catppuccin-mocha .is-inline.input,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-inline{display:inline;width:auto}html.theme--catppuccin-mocha .input.is-rounded,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input{border-radius:9999px;padding-left:calc(calc(0.75em - 1px) + 0.375em);padding-right:calc(calc(0.75em - 1px) + 0.375em)}html.theme--catppuccin-mocha .input.is-static,html.theme--catppuccin-mocha #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--catppuccin-mocha .textarea{display:block;max-width:100%;min-width:100%;padding:calc(0.75em - 1px);resize:vertical}html.theme--catppuccin-mocha .textarea:not([rows]){max-height:40em;min-height:8em}html.theme--catppuccin-mocha .textarea[rows]{height:initial}html.theme--catppuccin-mocha .textarea.has-fixed-size{resize:none}html.theme--catppuccin-mocha .radio,html.theme--catppuccin-mocha .checkbox{cursor:pointer;display:inline-block;line-height:1.25;position:relative}html.theme--catppuccin-mocha .radio input,html.theme--catppuccin-mocha .checkbox input{cursor:pointer}html.theme--catppuccin-mocha .radio:hover,html.theme--catppuccin-mocha .checkbox:hover{color:#89dceb}html.theme--catppuccin-mocha .radio[disabled],html.theme--catppuccin-mocha .checkbox[disabled],fieldset[disabled] html.theme--catppuccin-mocha .radio,fieldset[disabled] html.theme--catppuccin-mocha .checkbox,html.theme--catppuccin-mocha .radio input[disabled],html.theme--catppuccin-mocha .checkbox input[disabled]{color:#f7f8fd;cursor:not-allowed}html.theme--catppuccin-mocha .radio+.radio{margin-left:.5em}html.theme--catppuccin-mocha .select{display:inline-block;max-width:100%;position:relative;vertical-align:top}html.theme--catppuccin-mocha .select:not(.is-multiple){height:2.5em}html.theme--catppuccin-mocha .select:not(.is-multiple):not(.is-loading)::after{border-color:#89b4fa;right:1.125em;z-index:4}html.theme--catppuccin-mocha .select.is-rounded select,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.select select{border-radius:9999px;padding-left:1em}html.theme--catppuccin-mocha .select select{cursor:pointer;display:block;font-size:1em;max-width:100%;outline:none}html.theme--catppuccin-mocha .select select::-ms-expand{display:none}html.theme--catppuccin-mocha .select select[disabled]:hover,fieldset[disabled] html.theme--catppuccin-mocha .select select:hover{border-color:#181825}html.theme--catppuccin-mocha .select select:not([multiple]){padding-right:2.5em}html.theme--catppuccin-mocha .select select[multiple]{height:auto;padding:0}html.theme--catppuccin-mocha .select select[multiple] option{padding:0.5em 1em}html.theme--catppuccin-mocha .select:not(.is-multiple):not(.is-loading):hover::after{border-color:#89dceb}html.theme--catppuccin-mocha .select.is-white:not(:hover)::after{border-color:#fff}html.theme--catppuccin-mocha .select.is-white select{border-color:#fff}html.theme--catppuccin-mocha .select.is-white select:hover,html.theme--catppuccin-mocha .select.is-white select.is-hovered{border-color:#f2f2f2}html.theme--catppuccin-mocha .select.is-white select:focus,html.theme--catppuccin-mocha .select.is-white select.is-focused,html.theme--catppuccin-mocha .select.is-white select:active,html.theme--catppuccin-mocha .select.is-white select.is-active{box-shadow:0 0 0 0.125em rgba(255,255,255,0.25)}html.theme--catppuccin-mocha .select.is-black:not(:hover)::after{border-color:#0a0a0a}html.theme--catppuccin-mocha .select.is-black select{border-color:#0a0a0a}html.theme--catppuccin-mocha .select.is-black select:hover,html.theme--catppuccin-mocha .select.is-black select.is-hovered{border-color:#000}html.theme--catppuccin-mocha .select.is-black select:focus,html.theme--catppuccin-mocha .select.is-black select.is-focused,html.theme--catppuccin-mocha .select.is-black select:active,html.theme--catppuccin-mocha .select.is-black select.is-active{box-shadow:0 0 0 0.125em rgba(10,10,10,0.25)}html.theme--catppuccin-mocha .select.is-light:not(:hover)::after{border-color:#f5f5f5}html.theme--catppuccin-mocha .select.is-light select{border-color:#f5f5f5}html.theme--catppuccin-mocha .select.is-light select:hover,html.theme--catppuccin-mocha .select.is-light select.is-hovered{border-color:#e8e8e8}html.theme--catppuccin-mocha .select.is-light select:focus,html.theme--catppuccin-mocha .select.is-light select.is-focused,html.theme--catppuccin-mocha .select.is-light select:active,html.theme--catppuccin-mocha .select.is-light select.is-active{box-shadow:0 0 0 0.125em rgba(245,245,245,0.25)}html.theme--catppuccin-mocha .select.is-dark:not(:hover)::after,html.theme--catppuccin-mocha .content kbd.select:not(:hover)::after{border-color:#313244}html.theme--catppuccin-mocha .select.is-dark select,html.theme--catppuccin-mocha .content kbd.select select{border-color:#313244}html.theme--catppuccin-mocha .select.is-dark select:hover,html.theme--catppuccin-mocha .content kbd.select select:hover,html.theme--catppuccin-mocha .select.is-dark select.is-hovered,html.theme--catppuccin-mocha .content kbd.select select.is-hovered{border-color:#262735}html.theme--catppuccin-mocha .select.is-dark select:focus,html.theme--catppuccin-mocha .content kbd.select select:focus,html.theme--catppuccin-mocha .select.is-dark select.is-focused,html.theme--catppuccin-mocha .content kbd.select select.is-focused,html.theme--catppuccin-mocha .select.is-dark select:active,html.theme--catppuccin-mocha .content kbd.select select:active,html.theme--catppuccin-mocha .select.is-dark select.is-active,html.theme--catppuccin-mocha .content kbd.select select.is-active{box-shadow:0 0 0 0.125em rgba(49,50,68,0.25)}html.theme--catppuccin-mocha .select.is-primary:not(:hover)::after,html.theme--catppuccin-mocha .docstring>section>a.select.docs-sourcelink:not(:hover)::after{border-color:#89b4fa}html.theme--catppuccin-mocha .select.is-primary select,html.theme--catppuccin-mocha .docstring>section>a.select.docs-sourcelink select{border-color:#89b4fa}html.theme--catppuccin-mocha .select.is-primary select:hover,html.theme--catppuccin-mocha .docstring>section>a.select.docs-sourcelink select:hover,html.theme--catppuccin-mocha .select.is-primary select.is-hovered,html.theme--catppuccin-mocha .docstring>section>a.select.docs-sourcelink select.is-hovered{border-color:#71a4f9}html.theme--catppuccin-mocha .select.is-primary select:focus,html.theme--catppuccin-mocha .docstring>section>a.select.docs-sourcelink select:focus,html.theme--catppuccin-mocha .select.is-primary select.is-focused,html.theme--catppuccin-mocha .docstring>section>a.select.docs-sourcelink select.is-focused,html.theme--catppuccin-mocha .select.is-primary select:active,html.theme--catppuccin-mocha .docstring>section>a.select.docs-sourcelink select:active,html.theme--catppuccin-mocha .select.is-primary select.is-active,html.theme--catppuccin-mocha .docstring>section>a.select.docs-sourcelink select.is-active{box-shadow:0 0 0 0.125em rgba(137,180,250,0.25)}html.theme--catppuccin-mocha .select.is-link:not(:hover)::after{border-color:#89b4fa}html.theme--catppuccin-mocha .select.is-link select{border-color:#89b4fa}html.theme--catppuccin-mocha .select.is-link select:hover,html.theme--catppuccin-mocha .select.is-link select.is-hovered{border-color:#71a4f9}html.theme--catppuccin-mocha .select.is-link select:focus,html.theme--catppuccin-mocha .select.is-link select.is-focused,html.theme--catppuccin-mocha .select.is-link select:active,html.theme--catppuccin-mocha .select.is-link select.is-active{box-shadow:0 0 0 0.125em rgba(137,180,250,0.25)}html.theme--catppuccin-mocha .select.is-info:not(:hover)::after{border-color:#94e2d5}html.theme--catppuccin-mocha .select.is-info select{border-color:#94e2d5}html.theme--catppuccin-mocha .select.is-info select:hover,html.theme--catppuccin-mocha .select.is-info select.is-hovered{border-color:#80ddcd}html.theme--catppuccin-mocha .select.is-info select:focus,html.theme--catppuccin-mocha .select.is-info select.is-focused,html.theme--catppuccin-mocha .select.is-info select:active,html.theme--catppuccin-mocha .select.is-info select.is-active{box-shadow:0 0 0 0.125em rgba(148,226,213,0.25)}html.theme--catppuccin-mocha .select.is-success:not(:hover)::after{border-color:#a6e3a1}html.theme--catppuccin-mocha .select.is-success select{border-color:#a6e3a1}html.theme--catppuccin-mocha .select.is-success select:hover,html.theme--catppuccin-mocha .select.is-success select.is-hovered{border-color:#93dd8d}html.theme--catppuccin-mocha .select.is-success select:focus,html.theme--catppuccin-mocha .select.is-success select.is-focused,html.theme--catppuccin-mocha .select.is-success select:active,html.theme--catppuccin-mocha .select.is-success select.is-active{box-shadow:0 0 0 0.125em rgba(166,227,161,0.25)}html.theme--catppuccin-mocha .select.is-warning:not(:hover)::after{border-color:#f9e2af}html.theme--catppuccin-mocha .select.is-warning select{border-color:#f9e2af}html.theme--catppuccin-mocha .select.is-warning select:hover,html.theme--catppuccin-mocha .select.is-warning select.is-hovered{border-color:#f7d997}html.theme--catppuccin-mocha .select.is-warning select:focus,html.theme--catppuccin-mocha .select.is-warning select.is-focused,html.theme--catppuccin-mocha .select.is-warning select:active,html.theme--catppuccin-mocha .select.is-warning select.is-active{box-shadow:0 0 0 0.125em rgba(249,226,175,0.25)}html.theme--catppuccin-mocha .select.is-danger:not(:hover)::after{border-color:#f38ba8}html.theme--catppuccin-mocha .select.is-danger select{border-color:#f38ba8}html.theme--catppuccin-mocha .select.is-danger select:hover,html.theme--catppuccin-mocha .select.is-danger select.is-hovered{border-color:#f17497}html.theme--catppuccin-mocha .select.is-danger select:focus,html.theme--catppuccin-mocha .select.is-danger select.is-focused,html.theme--catppuccin-mocha .select.is-danger select:active,html.theme--catppuccin-mocha .select.is-danger select.is-active{box-shadow:0 0 0 0.125em rgba(243,139,168,0.25)}html.theme--catppuccin-mocha .select.is-small,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.select{border-radius:3px;font-size:.75rem}html.theme--catppuccin-mocha .select.is-medium{font-size:1.25rem}html.theme--catppuccin-mocha .select.is-large{font-size:1.5rem}html.theme--catppuccin-mocha .select.is-disabled::after{border-color:#f7f8fd !important;opacity:0.5}html.theme--catppuccin-mocha .select.is-fullwidth{width:100%}html.theme--catppuccin-mocha .select.is-fullwidth select{width:100%}html.theme--catppuccin-mocha .select.is-loading::after{margin-top:0;position:absolute;right:.625em;top:0.625em;transform:none}html.theme--catppuccin-mocha .select.is-loading.is-small:after,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-loading:after{font-size:.75rem}html.theme--catppuccin-mocha .select.is-loading.is-medium:after{font-size:1.25rem}html.theme--catppuccin-mocha .select.is-loading.is-large:after{font-size:1.5rem}html.theme--catppuccin-mocha .file{align-items:stretch;display:flex;justify-content:flex-start;position:relative}html.theme--catppuccin-mocha .file.is-white .file-cta{background-color:#fff;border-color:transparent;color:#0a0a0a}html.theme--catppuccin-mocha .file.is-white:hover .file-cta,html.theme--catppuccin-mocha .file.is-white.is-hovered .file-cta{background-color:#f9f9f9;border-color:transparent;color:#0a0a0a}html.theme--catppuccin-mocha .file.is-white:focus .file-cta,html.theme--catppuccin-mocha .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--catppuccin-mocha .file.is-white:active .file-cta,html.theme--catppuccin-mocha .file.is-white.is-active .file-cta{background-color:#f2f2f2;border-color:transparent;color:#0a0a0a}html.theme--catppuccin-mocha .file.is-black .file-cta{background-color:#0a0a0a;border-color:transparent;color:#fff}html.theme--catppuccin-mocha .file.is-black:hover .file-cta,html.theme--catppuccin-mocha .file.is-black.is-hovered .file-cta{background-color:#040404;border-color:transparent;color:#fff}html.theme--catppuccin-mocha .file.is-black:focus .file-cta,html.theme--catppuccin-mocha .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--catppuccin-mocha .file.is-black:active .file-cta,html.theme--catppuccin-mocha .file.is-black.is-active .file-cta{background-color:#000;border-color:transparent;color:#fff}html.theme--catppuccin-mocha .file.is-light .file-cta{background-color:#f5f5f5;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .file.is-light:hover .file-cta,html.theme--catppuccin-mocha .file.is-light.is-hovered .file-cta{background-color:#eee;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .file.is-light:focus .file-cta,html.theme--catppuccin-mocha .file.is-light.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(245,245,245,0.25);color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .file.is-light:active .file-cta,html.theme--catppuccin-mocha .file.is-light.is-active .file-cta{background-color:#e8e8e8;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .file.is-dark .file-cta,html.theme--catppuccin-mocha .content kbd.file .file-cta{background-color:#313244;border-color:transparent;color:#fff}html.theme--catppuccin-mocha .file.is-dark:hover .file-cta,html.theme--catppuccin-mocha .content kbd.file:hover .file-cta,html.theme--catppuccin-mocha .file.is-dark.is-hovered .file-cta,html.theme--catppuccin-mocha .content kbd.file.is-hovered .file-cta{background-color:#2c2d3d;border-color:transparent;color:#fff}html.theme--catppuccin-mocha .file.is-dark:focus .file-cta,html.theme--catppuccin-mocha .content kbd.file:focus .file-cta,html.theme--catppuccin-mocha .file.is-dark.is-focused .file-cta,html.theme--catppuccin-mocha .content kbd.file.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(49,50,68,0.25);color:#fff}html.theme--catppuccin-mocha .file.is-dark:active .file-cta,html.theme--catppuccin-mocha .content kbd.file:active .file-cta,html.theme--catppuccin-mocha .file.is-dark.is-active .file-cta,html.theme--catppuccin-mocha .content kbd.file.is-active .file-cta{background-color:#262735;border-color:transparent;color:#fff}html.theme--catppuccin-mocha .file.is-primary .file-cta,html.theme--catppuccin-mocha .docstring>section>a.file.docs-sourcelink .file-cta{background-color:#89b4fa;border-color:transparent;color:#fff}html.theme--catppuccin-mocha .file.is-primary:hover .file-cta,html.theme--catppuccin-mocha .docstring>section>a.file.docs-sourcelink:hover .file-cta,html.theme--catppuccin-mocha .file.is-primary.is-hovered .file-cta,html.theme--catppuccin-mocha .docstring>section>a.file.is-hovered.docs-sourcelink .file-cta{background-color:#7dacf9;border-color:transparent;color:#fff}html.theme--catppuccin-mocha .file.is-primary:focus .file-cta,html.theme--catppuccin-mocha .docstring>section>a.file.docs-sourcelink:focus .file-cta,html.theme--catppuccin-mocha .file.is-primary.is-focused .file-cta,html.theme--catppuccin-mocha .docstring>section>a.file.is-focused.docs-sourcelink .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(137,180,250,0.25);color:#fff}html.theme--catppuccin-mocha .file.is-primary:active .file-cta,html.theme--catppuccin-mocha .docstring>section>a.file.docs-sourcelink:active .file-cta,html.theme--catppuccin-mocha .file.is-primary.is-active .file-cta,html.theme--catppuccin-mocha .docstring>section>a.file.is-active.docs-sourcelink .file-cta{background-color:#71a4f9;border-color:transparent;color:#fff}html.theme--catppuccin-mocha .file.is-link .file-cta{background-color:#89b4fa;border-color:transparent;color:#fff}html.theme--catppuccin-mocha .file.is-link:hover .file-cta,html.theme--catppuccin-mocha .file.is-link.is-hovered .file-cta{background-color:#7dacf9;border-color:transparent;color:#fff}html.theme--catppuccin-mocha .file.is-link:focus .file-cta,html.theme--catppuccin-mocha .file.is-link.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(137,180,250,0.25);color:#fff}html.theme--catppuccin-mocha .file.is-link:active .file-cta,html.theme--catppuccin-mocha .file.is-link.is-active .file-cta{background-color:#71a4f9;border-color:transparent;color:#fff}html.theme--catppuccin-mocha .file.is-info .file-cta{background-color:#94e2d5;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .file.is-info:hover .file-cta,html.theme--catppuccin-mocha .file.is-info.is-hovered .file-cta{background-color:#8adfd1;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .file.is-info:focus .file-cta,html.theme--catppuccin-mocha .file.is-info.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(148,226,213,0.25);color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .file.is-info:active .file-cta,html.theme--catppuccin-mocha .file.is-info.is-active .file-cta{background-color:#80ddcd;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .file.is-success .file-cta{background-color:#a6e3a1;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .file.is-success:hover .file-cta,html.theme--catppuccin-mocha .file.is-success.is-hovered .file-cta{background-color:#9de097;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .file.is-success:focus .file-cta,html.theme--catppuccin-mocha .file.is-success.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(166,227,161,0.25);color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .file.is-success:active .file-cta,html.theme--catppuccin-mocha .file.is-success.is-active .file-cta{background-color:#93dd8d;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .file.is-warning .file-cta{background-color:#f9e2af;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .file.is-warning:hover .file-cta,html.theme--catppuccin-mocha .file.is-warning.is-hovered .file-cta{background-color:#f8dea3;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .file.is-warning:focus .file-cta,html.theme--catppuccin-mocha .file.is-warning.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(249,226,175,0.25);color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .file.is-warning:active .file-cta,html.theme--catppuccin-mocha .file.is-warning.is-active .file-cta{background-color:#f7d997;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .file.is-danger .file-cta{background-color:#f38ba8;border-color:transparent;color:#fff}html.theme--catppuccin-mocha .file.is-danger:hover .file-cta,html.theme--catppuccin-mocha .file.is-danger.is-hovered .file-cta{background-color:#f27f9f;border-color:transparent;color:#fff}html.theme--catppuccin-mocha .file.is-danger:focus .file-cta,html.theme--catppuccin-mocha .file.is-danger.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(243,139,168,0.25);color:#fff}html.theme--catppuccin-mocha .file.is-danger:active .file-cta,html.theme--catppuccin-mocha .file.is-danger.is-active .file-cta{background-color:#f17497;border-color:transparent;color:#fff}html.theme--catppuccin-mocha .file.is-small,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.file{font-size:.75rem}html.theme--catppuccin-mocha .file.is-normal{font-size:1rem}html.theme--catppuccin-mocha .file.is-medium{font-size:1.25rem}html.theme--catppuccin-mocha .file.is-medium .file-icon .fa{font-size:21px}html.theme--catppuccin-mocha .file.is-large{font-size:1.5rem}html.theme--catppuccin-mocha .file.is-large .file-icon .fa{font-size:28px}html.theme--catppuccin-mocha .file.has-name .file-cta{border-bottom-right-radius:0;border-top-right-radius:0}html.theme--catppuccin-mocha .file.has-name .file-name{border-bottom-left-radius:0;border-top-left-radius:0}html.theme--catppuccin-mocha .file.has-name.is-empty .file-cta{border-radius:.4em}html.theme--catppuccin-mocha .file.has-name.is-empty .file-name{display:none}html.theme--catppuccin-mocha .file.is-boxed .file-label{flex-direction:column}html.theme--catppuccin-mocha .file.is-boxed .file-cta{flex-direction:column;height:auto;padding:1em 3em}html.theme--catppuccin-mocha .file.is-boxed .file-name{border-width:0 1px 1px}html.theme--catppuccin-mocha .file.is-boxed .file-icon{height:1.5em;width:1.5em}html.theme--catppuccin-mocha .file.is-boxed .file-icon .fa{font-size:21px}html.theme--catppuccin-mocha .file.is-boxed.is-small .file-icon .fa,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-boxed .file-icon .fa{font-size:14px}html.theme--catppuccin-mocha .file.is-boxed.is-medium .file-icon .fa{font-size:28px}html.theme--catppuccin-mocha .file.is-boxed.is-large .file-icon .fa{font-size:35px}html.theme--catppuccin-mocha .file.is-boxed.has-name .file-cta{border-radius:.4em .4em 0 0}html.theme--catppuccin-mocha .file.is-boxed.has-name .file-name{border-radius:0 0 .4em .4em;border-width:0 1px 1px}html.theme--catppuccin-mocha .file.is-centered{justify-content:center}html.theme--catppuccin-mocha .file.is-fullwidth .file-label{width:100%}html.theme--catppuccin-mocha .file.is-fullwidth .file-name{flex-grow:1;max-width:none}html.theme--catppuccin-mocha .file.is-right{justify-content:flex-end}html.theme--catppuccin-mocha .file.is-right .file-cta{border-radius:0 .4em .4em 0}html.theme--catppuccin-mocha .file.is-right .file-name{border-radius:.4em 0 0 .4em;border-width:1px 0 1px 1px;order:-1}html.theme--catppuccin-mocha .file-label{align-items:stretch;display:flex;cursor:pointer;justify-content:flex-start;overflow:hidden;position:relative}html.theme--catppuccin-mocha .file-label:hover .file-cta{background-color:#2c2d3d;color:#b8c5ef}html.theme--catppuccin-mocha .file-label:hover .file-name{border-color:#525569}html.theme--catppuccin-mocha .file-label:active .file-cta{background-color:#262735;color:#b8c5ef}html.theme--catppuccin-mocha .file-label:active .file-name{border-color:#4d4f62}html.theme--catppuccin-mocha .file-input{height:100%;left:0;opacity:0;outline:none;position:absolute;top:0;width:100%}html.theme--catppuccin-mocha .file-cta,html.theme--catppuccin-mocha .file-name{border-color:#585b70;border-radius:.4em;font-size:1em;padding-left:1em;padding-right:1em;white-space:nowrap}html.theme--catppuccin-mocha .file-cta{background-color:#313244;color:#cdd6f4}html.theme--catppuccin-mocha .file-name{border-color:#585b70;border-style:solid;border-width:1px 1px 1px 0;display:block;max-width:16em;overflow:hidden;text-align:inherit;text-overflow:ellipsis}html.theme--catppuccin-mocha .file-icon{align-items:center;display:flex;height:1em;justify-content:center;margin-right:.5em;width:1em}html.theme--catppuccin-mocha .file-icon .fa{font-size:14px}html.theme--catppuccin-mocha .label{color:#b8c5ef;display:block;font-size:1rem;font-weight:700}html.theme--catppuccin-mocha .label:not(:last-child){margin-bottom:0.5em}html.theme--catppuccin-mocha .label.is-small,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.label{font-size:.75rem}html.theme--catppuccin-mocha .label.is-medium{font-size:1.25rem}html.theme--catppuccin-mocha .label.is-large{font-size:1.5rem}html.theme--catppuccin-mocha .help{display:block;font-size:.75rem;margin-top:0.25rem}html.theme--catppuccin-mocha .help.is-white{color:#fff}html.theme--catppuccin-mocha .help.is-black{color:#0a0a0a}html.theme--catppuccin-mocha .help.is-light{color:#f5f5f5}html.theme--catppuccin-mocha .help.is-dark,html.theme--catppuccin-mocha .content kbd.help{color:#313244}html.theme--catppuccin-mocha .help.is-primary,html.theme--catppuccin-mocha .docstring>section>a.help.docs-sourcelink{color:#89b4fa}html.theme--catppuccin-mocha .help.is-link{color:#89b4fa}html.theme--catppuccin-mocha .help.is-info{color:#94e2d5}html.theme--catppuccin-mocha .help.is-success{color:#a6e3a1}html.theme--catppuccin-mocha .help.is-warning{color:#f9e2af}html.theme--catppuccin-mocha .help.is-danger{color:#f38ba8}html.theme--catppuccin-mocha .field:not(:last-child){margin-bottom:0.75rem}html.theme--catppuccin-mocha .field.has-addons{display:flex;justify-content:flex-start}html.theme--catppuccin-mocha .field.has-addons .control:not(:last-child){margin-right:-1px}html.theme--catppuccin-mocha .field.has-addons .control:not(:first-child):not(:last-child) .button,html.theme--catppuccin-mocha .field.has-addons .control:not(:first-child):not(:last-child) .input,html.theme--catppuccin-mocha .field.has-addons .control:not(:first-child):not(:last-child) #documenter .docs-sidebar form.docs-search>input,html.theme--catppuccin-mocha #documenter .docs-sidebar .field.has-addons .control:not(:first-child):not(:last-child) form.docs-search>input,html.theme--catppuccin-mocha .field.has-addons .control:not(:first-child):not(:last-child) .select select{border-radius:0}html.theme--catppuccin-mocha .field.has-addons .control:first-child:not(:only-child) .button,html.theme--catppuccin-mocha .field.has-addons .control:first-child:not(:only-child) .input,html.theme--catppuccin-mocha .field.has-addons .control:first-child:not(:only-child) #documenter .docs-sidebar form.docs-search>input,html.theme--catppuccin-mocha #documenter .docs-sidebar .field.has-addons .control:first-child:not(:only-child) form.docs-search>input,html.theme--catppuccin-mocha .field.has-addons .control:first-child:not(:only-child) .select select{border-bottom-right-radius:0;border-top-right-radius:0}html.theme--catppuccin-mocha .field.has-addons .control:last-child:not(:only-child) .button,html.theme--catppuccin-mocha .field.has-addons .control:last-child:not(:only-child) .input,html.theme--catppuccin-mocha .field.has-addons .control:last-child:not(:only-child) #documenter .docs-sidebar form.docs-search>input,html.theme--catppuccin-mocha #documenter .docs-sidebar .field.has-addons .control:last-child:not(:only-child) form.docs-search>input,html.theme--catppuccin-mocha .field.has-addons .control:last-child:not(:only-child) .select select{border-bottom-left-radius:0;border-top-left-radius:0}html.theme--catppuccin-mocha .field.has-addons .control .button:not([disabled]):hover,html.theme--catppuccin-mocha .field.has-addons .control .button.is-hovered:not([disabled]),html.theme--catppuccin-mocha .field.has-addons .control .input:not([disabled]):hover,html.theme--catppuccin-mocha .field.has-addons .control #documenter .docs-sidebar form.docs-search>input:not([disabled]):hover,html.theme--catppuccin-mocha #documenter .docs-sidebar .field.has-addons .control form.docs-search>input:not([disabled]):hover,html.theme--catppuccin-mocha .field.has-addons .control .input.is-hovered:not([disabled]),html.theme--catppuccin-mocha .field.has-addons .control #documenter .docs-sidebar form.docs-search>input.is-hovered:not([disabled]),html.theme--catppuccin-mocha #documenter .docs-sidebar .field.has-addons .control form.docs-search>input.is-hovered:not([disabled]),html.theme--catppuccin-mocha .field.has-addons .control .select select:not([disabled]):hover,html.theme--catppuccin-mocha .field.has-addons .control .select select.is-hovered:not([disabled]){z-index:2}html.theme--catppuccin-mocha .field.has-addons .control .button:not([disabled]):focus,html.theme--catppuccin-mocha .field.has-addons .control .button.is-focused:not([disabled]),html.theme--catppuccin-mocha .field.has-addons .control .button:not([disabled]):active,html.theme--catppuccin-mocha .field.has-addons .control .button.is-active:not([disabled]),html.theme--catppuccin-mocha .field.has-addons .control .input:not([disabled]):focus,html.theme--catppuccin-mocha .field.has-addons .control #documenter .docs-sidebar form.docs-search>input:not([disabled]):focus,html.theme--catppuccin-mocha #documenter .docs-sidebar .field.has-addons .control form.docs-search>input:not([disabled]):focus,html.theme--catppuccin-mocha .field.has-addons .control .input.is-focused:not([disabled]),html.theme--catppuccin-mocha .field.has-addons .control #documenter .docs-sidebar form.docs-search>input.is-focused:not([disabled]),html.theme--catppuccin-mocha #documenter .docs-sidebar .field.has-addons .control form.docs-search>input.is-focused:not([disabled]),html.theme--catppuccin-mocha .field.has-addons .control .input:not([disabled]):active,html.theme--catppuccin-mocha .field.has-addons .control #documenter .docs-sidebar form.docs-search>input:not([disabled]):active,html.theme--catppuccin-mocha #documenter .docs-sidebar .field.has-addons .control form.docs-search>input:not([disabled]):active,html.theme--catppuccin-mocha .field.has-addons .control .input.is-active:not([disabled]),html.theme--catppuccin-mocha .field.has-addons .control #documenter .docs-sidebar form.docs-search>input.is-active:not([disabled]),html.theme--catppuccin-mocha #documenter .docs-sidebar .field.has-addons .control form.docs-search>input.is-active:not([disabled]),html.theme--catppuccin-mocha .field.has-addons .control .select select:not([disabled]):focus,html.theme--catppuccin-mocha .field.has-addons .control .select select.is-focused:not([disabled]),html.theme--catppuccin-mocha .field.has-addons .control .select select:not([disabled]):active,html.theme--catppuccin-mocha .field.has-addons .control .select select.is-active:not([disabled]){z-index:3}html.theme--catppuccin-mocha .field.has-addons .control .button:not([disabled]):focus:hover,html.theme--catppuccin-mocha .field.has-addons .control .button.is-focused:not([disabled]):hover,html.theme--catppuccin-mocha .field.has-addons .control .button:not([disabled]):active:hover,html.theme--catppuccin-mocha .field.has-addons .control .button.is-active:not([disabled]):hover,html.theme--catppuccin-mocha .field.has-addons .control .input:not([disabled]):focus:hover,html.theme--catppuccin-mocha .field.has-addons .control #documenter .docs-sidebar form.docs-search>input:not([disabled]):focus:hover,html.theme--catppuccin-mocha #documenter .docs-sidebar .field.has-addons .control form.docs-search>input:not([disabled]):focus:hover,html.theme--catppuccin-mocha .field.has-addons .control .input.is-focused:not([disabled]):hover,html.theme--catppuccin-mocha .field.has-addons .control #documenter .docs-sidebar form.docs-search>input.is-focused:not([disabled]):hover,html.theme--catppuccin-mocha #documenter .docs-sidebar .field.has-addons .control form.docs-search>input.is-focused:not([disabled]):hover,html.theme--catppuccin-mocha .field.has-addons .control .input:not([disabled]):active:hover,html.theme--catppuccin-mocha .field.has-addons .control #documenter .docs-sidebar form.docs-search>input:not([disabled]):active:hover,html.theme--catppuccin-mocha #documenter .docs-sidebar .field.has-addons .control form.docs-search>input:not([disabled]):active:hover,html.theme--catppuccin-mocha .field.has-addons .control .input.is-active:not([disabled]):hover,html.theme--catppuccin-mocha .field.has-addons .control #documenter .docs-sidebar form.docs-search>input.is-active:not([disabled]):hover,html.theme--catppuccin-mocha #documenter .docs-sidebar .field.has-addons .control form.docs-search>input.is-active:not([disabled]):hover,html.theme--catppuccin-mocha .field.has-addons .control .select select:not([disabled]):focus:hover,html.theme--catppuccin-mocha .field.has-addons .control .select select.is-focused:not([disabled]):hover,html.theme--catppuccin-mocha .field.has-addons .control .select select:not([disabled]):active:hover,html.theme--catppuccin-mocha .field.has-addons .control .select select.is-active:not([disabled]):hover{z-index:4}html.theme--catppuccin-mocha .field.has-addons .control.is-expanded{flex-grow:1;flex-shrink:1}html.theme--catppuccin-mocha .field.has-addons.has-addons-centered{justify-content:center}html.theme--catppuccin-mocha .field.has-addons.has-addons-right{justify-content:flex-end}html.theme--catppuccin-mocha .field.has-addons.has-addons-fullwidth .control{flex-grow:1;flex-shrink:0}html.theme--catppuccin-mocha .field.is-grouped{display:flex;justify-content:flex-start}html.theme--catppuccin-mocha .field.is-grouped>.control{flex-shrink:0}html.theme--catppuccin-mocha .field.is-grouped>.control:not(:last-child){margin-bottom:0;margin-right:.75rem}html.theme--catppuccin-mocha .field.is-grouped>.control.is-expanded{flex-grow:1;flex-shrink:1}html.theme--catppuccin-mocha .field.is-grouped.is-grouped-centered{justify-content:center}html.theme--catppuccin-mocha .field.is-grouped.is-grouped-right{justify-content:flex-end}html.theme--catppuccin-mocha .field.is-grouped.is-grouped-multiline{flex-wrap:wrap}html.theme--catppuccin-mocha .field.is-grouped.is-grouped-multiline>.control:last-child,html.theme--catppuccin-mocha .field.is-grouped.is-grouped-multiline>.control:not(:last-child){margin-bottom:0.75rem}html.theme--catppuccin-mocha .field.is-grouped.is-grouped-multiline:last-child{margin-bottom:-0.75rem}html.theme--catppuccin-mocha .field.is-grouped.is-grouped-multiline:not(:last-child){margin-bottom:0}@media screen and (min-width: 769px),print{html.theme--catppuccin-mocha .field.is-horizontal{display:flex}}html.theme--catppuccin-mocha .field-label .label{font-size:inherit}@media screen and (max-width: 768px){html.theme--catppuccin-mocha .field-label{margin-bottom:0.5rem}}@media screen and (min-width: 769px),print{html.theme--catppuccin-mocha .field-label{flex-basis:0;flex-grow:1;flex-shrink:0;margin-right:1.5rem;text-align:right}html.theme--catppuccin-mocha .field-label.is-small,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.field-label{font-size:.75rem;padding-top:0.375em}html.theme--catppuccin-mocha .field-label.is-normal{padding-top:0.375em}html.theme--catppuccin-mocha .field-label.is-medium{font-size:1.25rem;padding-top:0.375em}html.theme--catppuccin-mocha .field-label.is-large{font-size:1.5rem;padding-top:0.375em}}html.theme--catppuccin-mocha .field-body .field .field{margin-bottom:0}@media screen and (min-width: 769px),print{html.theme--catppuccin-mocha .field-body{display:flex;flex-basis:0;flex-grow:5;flex-shrink:1}html.theme--catppuccin-mocha .field-body .field{margin-bottom:0}html.theme--catppuccin-mocha .field-body>.field{flex-shrink:1}html.theme--catppuccin-mocha .field-body>.field:not(.is-narrow){flex-grow:1}html.theme--catppuccin-mocha .field-body>.field:not(:last-child){margin-right:.75rem}}html.theme--catppuccin-mocha .control{box-sizing:border-box;clear:both;font-size:1rem;position:relative;text-align:inherit}html.theme--catppuccin-mocha .control.has-icons-left .input:focus~.icon,html.theme--catppuccin-mocha .control.has-icons-left #documenter .docs-sidebar form.docs-search>input:focus~.icon,html.theme--catppuccin-mocha #documenter .docs-sidebar .control.has-icons-left form.docs-search>input:focus~.icon,html.theme--catppuccin-mocha .control.has-icons-left .select:focus~.icon,html.theme--catppuccin-mocha .control.has-icons-right .input:focus~.icon,html.theme--catppuccin-mocha .control.has-icons-right #documenter .docs-sidebar form.docs-search>input:focus~.icon,html.theme--catppuccin-mocha #documenter .docs-sidebar .control.has-icons-right form.docs-search>input:focus~.icon,html.theme--catppuccin-mocha .control.has-icons-right .select:focus~.icon{color:#313244}html.theme--catppuccin-mocha .control.has-icons-left .input.is-small~.icon,html.theme--catppuccin-mocha .control.has-icons-left #documenter .docs-sidebar form.docs-search>input~.icon,html.theme--catppuccin-mocha #documenter .docs-sidebar .control.has-icons-left form.docs-search>input~.icon,html.theme--catppuccin-mocha .control.has-icons-left .select.is-small~.icon,html.theme--catppuccin-mocha .control.has-icons-right .input.is-small~.icon,html.theme--catppuccin-mocha .control.has-icons-right #documenter .docs-sidebar form.docs-search>input~.icon,html.theme--catppuccin-mocha #documenter .docs-sidebar .control.has-icons-right form.docs-search>input~.icon,html.theme--catppuccin-mocha .control.has-icons-right .select.is-small~.icon{font-size:.75rem}html.theme--catppuccin-mocha .control.has-icons-left .input.is-medium~.icon,html.theme--catppuccin-mocha .control.has-icons-left #documenter .docs-sidebar form.docs-search>input.is-medium~.icon,html.theme--catppuccin-mocha #documenter .docs-sidebar .control.has-icons-left form.docs-search>input.is-medium~.icon,html.theme--catppuccin-mocha .control.has-icons-left .select.is-medium~.icon,html.theme--catppuccin-mocha .control.has-icons-right .input.is-medium~.icon,html.theme--catppuccin-mocha .control.has-icons-right #documenter .docs-sidebar form.docs-search>input.is-medium~.icon,html.theme--catppuccin-mocha #documenter .docs-sidebar .control.has-icons-right form.docs-search>input.is-medium~.icon,html.theme--catppuccin-mocha .control.has-icons-right .select.is-medium~.icon{font-size:1.25rem}html.theme--catppuccin-mocha .control.has-icons-left .input.is-large~.icon,html.theme--catppuccin-mocha .control.has-icons-left #documenter .docs-sidebar form.docs-search>input.is-large~.icon,html.theme--catppuccin-mocha #documenter .docs-sidebar .control.has-icons-left form.docs-search>input.is-large~.icon,html.theme--catppuccin-mocha .control.has-icons-left .select.is-large~.icon,html.theme--catppuccin-mocha .control.has-icons-right .input.is-large~.icon,html.theme--catppuccin-mocha .control.has-icons-right #documenter .docs-sidebar form.docs-search>input.is-large~.icon,html.theme--catppuccin-mocha #documenter .docs-sidebar .control.has-icons-right form.docs-search>input.is-large~.icon,html.theme--catppuccin-mocha .control.has-icons-right .select.is-large~.icon{font-size:1.5rem}html.theme--catppuccin-mocha .control.has-icons-left .icon,html.theme--catppuccin-mocha .control.has-icons-right .icon{color:#585b70;height:2.5em;pointer-events:none;position:absolute;top:0;width:2.5em;z-index:4}html.theme--catppuccin-mocha .control.has-icons-left .input,html.theme--catppuccin-mocha .control.has-icons-left #documenter .docs-sidebar form.docs-search>input,html.theme--catppuccin-mocha #documenter .docs-sidebar .control.has-icons-left form.docs-search>input,html.theme--catppuccin-mocha .control.has-icons-left .select select{padding-left:2.5em}html.theme--catppuccin-mocha .control.has-icons-left .icon.is-left{left:0}html.theme--catppuccin-mocha .control.has-icons-right .input,html.theme--catppuccin-mocha .control.has-icons-right #documenter .docs-sidebar form.docs-search>input,html.theme--catppuccin-mocha #documenter .docs-sidebar .control.has-icons-right form.docs-search>input,html.theme--catppuccin-mocha .control.has-icons-right .select select{padding-right:2.5em}html.theme--catppuccin-mocha .control.has-icons-right .icon.is-right{right:0}html.theme--catppuccin-mocha .control.is-loading::after{position:absolute !important;right:.625em;top:0.625em;z-index:4}html.theme--catppuccin-mocha .control.is-loading.is-small:after,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-loading:after{font-size:.75rem}html.theme--catppuccin-mocha .control.is-loading.is-medium:after{font-size:1.25rem}html.theme--catppuccin-mocha .control.is-loading.is-large:after{font-size:1.5rem}html.theme--catppuccin-mocha .breadcrumb{font-size:1rem;white-space:nowrap}html.theme--catppuccin-mocha .breadcrumb a{align-items:center;color:#89b4fa;display:flex;justify-content:center;padding:0 .75em}html.theme--catppuccin-mocha .breadcrumb a:hover{color:#89dceb}html.theme--catppuccin-mocha .breadcrumb li{align-items:center;display:flex}html.theme--catppuccin-mocha .breadcrumb li:first-child a{padding-left:0}html.theme--catppuccin-mocha .breadcrumb li.is-active a{color:#b8c5ef;cursor:default;pointer-events:none}html.theme--catppuccin-mocha .breadcrumb li+li::before{color:#6c7086;content:"\0002f"}html.theme--catppuccin-mocha .breadcrumb ul,html.theme--catppuccin-mocha .breadcrumb ol{align-items:flex-start;display:flex;flex-wrap:wrap;justify-content:flex-start}html.theme--catppuccin-mocha .breadcrumb .icon:first-child{margin-right:.5em}html.theme--catppuccin-mocha .breadcrumb .icon:last-child{margin-left:.5em}html.theme--catppuccin-mocha .breadcrumb.is-centered ol,html.theme--catppuccin-mocha .breadcrumb.is-centered ul{justify-content:center}html.theme--catppuccin-mocha .breadcrumb.is-right ol,html.theme--catppuccin-mocha .breadcrumb.is-right ul{justify-content:flex-end}html.theme--catppuccin-mocha .breadcrumb.is-small,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.breadcrumb{font-size:.75rem}html.theme--catppuccin-mocha .breadcrumb.is-medium{font-size:1.25rem}html.theme--catppuccin-mocha .breadcrumb.is-large{font-size:1.5rem}html.theme--catppuccin-mocha .breadcrumb.has-arrow-separator li+li::before{content:"\02192"}html.theme--catppuccin-mocha .breadcrumb.has-bullet-separator li+li::before{content:"\02022"}html.theme--catppuccin-mocha .breadcrumb.has-dot-separator li+li::before{content:"\000b7"}html.theme--catppuccin-mocha .breadcrumb.has-succeeds-separator li+li::before{content:"\0227B"}html.theme--catppuccin-mocha .card{background-color:#fff;border-radius:.25rem;box-shadow:#171717;color:#cdd6f4;max-width:100%;position:relative}html.theme--catppuccin-mocha .card-footer:first-child,html.theme--catppuccin-mocha .card-content:first-child,html.theme--catppuccin-mocha .card-header:first-child{border-top-left-radius:.25rem;border-top-right-radius:.25rem}html.theme--catppuccin-mocha .card-footer:last-child,html.theme--catppuccin-mocha .card-content:last-child,html.theme--catppuccin-mocha .card-header:last-child{border-bottom-left-radius:.25rem;border-bottom-right-radius:.25rem}html.theme--catppuccin-mocha .card-header{background-color:rgba(0,0,0,0);align-items:stretch;box-shadow:0 0.125em 0.25em rgba(10,10,10,0.1);display:flex}html.theme--catppuccin-mocha .card-header-title{align-items:center;color:#b8c5ef;display:flex;flex-grow:1;font-weight:700;padding:0.75rem 1rem}html.theme--catppuccin-mocha .card-header-title.is-centered{justify-content:center}html.theme--catppuccin-mocha .card-header-icon{-moz-appearance:none;-webkit-appearance:none;appearance:none;background:none;border:none;color:currentColor;font-family:inherit;font-size:1em;margin:0;padding:0;align-items:center;cursor:pointer;display:flex;justify-content:center;padding:0.75rem 1rem}html.theme--catppuccin-mocha .card-image{display:block;position:relative}html.theme--catppuccin-mocha .card-image:first-child img{border-top-left-radius:.25rem;border-top-right-radius:.25rem}html.theme--catppuccin-mocha .card-image:last-child img{border-bottom-left-radius:.25rem;border-bottom-right-radius:.25rem}html.theme--catppuccin-mocha .card-content{background-color:rgba(0,0,0,0);padding:1.5rem}html.theme--catppuccin-mocha .card-footer{background-color:rgba(0,0,0,0);border-top:1px solid #ededed;align-items:stretch;display:flex}html.theme--catppuccin-mocha .card-footer-item{align-items:center;display:flex;flex-basis:0;flex-grow:1;flex-shrink:0;justify-content:center;padding:.75rem}html.theme--catppuccin-mocha .card-footer-item:not(:last-child){border-right:1px solid #ededed}html.theme--catppuccin-mocha .card .media:not(:last-child){margin-bottom:1.5rem}html.theme--catppuccin-mocha .dropdown{display:inline-flex;position:relative;vertical-align:top}html.theme--catppuccin-mocha .dropdown.is-active .dropdown-menu,html.theme--catppuccin-mocha .dropdown.is-hoverable:hover .dropdown-menu{display:block}html.theme--catppuccin-mocha .dropdown.is-right .dropdown-menu{left:auto;right:0}html.theme--catppuccin-mocha .dropdown.is-up .dropdown-menu{bottom:100%;padding-bottom:4px;padding-top:initial;top:auto}html.theme--catppuccin-mocha .dropdown-menu{display:none;left:0;min-width:12rem;padding-top:4px;position:absolute;top:100%;z-index:20}html.theme--catppuccin-mocha .dropdown-content{background-color:#181825;border-radius:.4em;box-shadow:#171717;padding-bottom:.5rem;padding-top:.5rem}html.theme--catppuccin-mocha .dropdown-item{color:#cdd6f4;display:block;font-size:0.875rem;line-height:1.5;padding:0.375rem 1rem;position:relative}html.theme--catppuccin-mocha a.dropdown-item,html.theme--catppuccin-mocha button.dropdown-item{padding-right:3rem;text-align:inherit;white-space:nowrap;width:100%}html.theme--catppuccin-mocha a.dropdown-item:hover,html.theme--catppuccin-mocha button.dropdown-item:hover{background-color:#181825;color:#0a0a0a}html.theme--catppuccin-mocha a.dropdown-item.is-active,html.theme--catppuccin-mocha button.dropdown-item.is-active{background-color:#89b4fa;color:#fff}html.theme--catppuccin-mocha .dropdown-divider{background-color:#ededed;border:none;display:block;height:1px;margin:0.5rem 0}html.theme--catppuccin-mocha .level{align-items:center;justify-content:space-between}html.theme--catppuccin-mocha .level code{border-radius:.4em}html.theme--catppuccin-mocha .level img{display:inline-block;vertical-align:top}html.theme--catppuccin-mocha .level.is-mobile{display:flex}html.theme--catppuccin-mocha .level.is-mobile .level-left,html.theme--catppuccin-mocha .level.is-mobile .level-right{display:flex}html.theme--catppuccin-mocha .level.is-mobile .level-left+.level-right{margin-top:0}html.theme--catppuccin-mocha .level.is-mobile .level-item:not(:last-child){margin-bottom:0;margin-right:.75rem}html.theme--catppuccin-mocha .level.is-mobile .level-item:not(.is-narrow){flex-grow:1}@media screen and (min-width: 769px),print{html.theme--catppuccin-mocha .level{display:flex}html.theme--catppuccin-mocha .level>.level-item:not(.is-narrow){flex-grow:1}}html.theme--catppuccin-mocha .level-item{align-items:center;display:flex;flex-basis:auto;flex-grow:0;flex-shrink:0;justify-content:center}html.theme--catppuccin-mocha .level-item .title,html.theme--catppuccin-mocha .level-item .subtitle{margin-bottom:0}@media screen and (max-width: 768px){html.theme--catppuccin-mocha .level-item:not(:last-child){margin-bottom:.75rem}}html.theme--catppuccin-mocha .level-left,html.theme--catppuccin-mocha .level-right{flex-basis:auto;flex-grow:0;flex-shrink:0}html.theme--catppuccin-mocha .level-left .level-item.is-flexible,html.theme--catppuccin-mocha .level-right .level-item.is-flexible{flex-grow:1}@media screen and (min-width: 769px),print{html.theme--catppuccin-mocha .level-left .level-item:not(:last-child),html.theme--catppuccin-mocha .level-right .level-item:not(:last-child){margin-right:.75rem}}html.theme--catppuccin-mocha .level-left{align-items:center;justify-content:flex-start}@media screen and (max-width: 768px){html.theme--catppuccin-mocha .level-left+.level-right{margin-top:1.5rem}}@media screen and (min-width: 769px),print{html.theme--catppuccin-mocha .level-left{display:flex}}html.theme--catppuccin-mocha .level-right{align-items:center;justify-content:flex-end}@media screen and (min-width: 769px),print{html.theme--catppuccin-mocha .level-right{display:flex}}html.theme--catppuccin-mocha .media{align-items:flex-start;display:flex;text-align:inherit}html.theme--catppuccin-mocha .media .content:not(:last-child){margin-bottom:.75rem}html.theme--catppuccin-mocha .media .media{border-top:1px solid rgba(88,91,112,0.5);display:flex;padding-top:.75rem}html.theme--catppuccin-mocha .media .media .content:not(:last-child),html.theme--catppuccin-mocha .media .media .control:not(:last-child){margin-bottom:.5rem}html.theme--catppuccin-mocha .media .media .media{padding-top:.5rem}html.theme--catppuccin-mocha .media .media .media+.media{margin-top:.5rem}html.theme--catppuccin-mocha .media+.media{border-top:1px solid rgba(88,91,112,0.5);margin-top:1rem;padding-top:1rem}html.theme--catppuccin-mocha .media.is-large+.media{margin-top:1.5rem;padding-top:1.5rem}html.theme--catppuccin-mocha .media-left,html.theme--catppuccin-mocha .media-right{flex-basis:auto;flex-grow:0;flex-shrink:0}html.theme--catppuccin-mocha .media-left{margin-right:1rem}html.theme--catppuccin-mocha .media-right{margin-left:1rem}html.theme--catppuccin-mocha .media-content{flex-basis:auto;flex-grow:1;flex-shrink:1;text-align:inherit}@media screen and (max-width: 768px){html.theme--catppuccin-mocha .media-content{overflow-x:auto}}html.theme--catppuccin-mocha .menu{font-size:1rem}html.theme--catppuccin-mocha .menu.is-small,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.menu{font-size:.75rem}html.theme--catppuccin-mocha .menu.is-medium{font-size:1.25rem}html.theme--catppuccin-mocha .menu.is-large{font-size:1.5rem}html.theme--catppuccin-mocha .menu-list{line-height:1.25}html.theme--catppuccin-mocha .menu-list a{border-radius:3px;color:#cdd6f4;display:block;padding:0.5em 0.75em}html.theme--catppuccin-mocha .menu-list a:hover{background-color:#181825;color:#b8c5ef}html.theme--catppuccin-mocha .menu-list a.is-active{background-color:#89b4fa;color:#fff}html.theme--catppuccin-mocha .menu-list li ul{border-left:1px solid #585b70;margin:.75em;padding-left:.75em}html.theme--catppuccin-mocha .menu-label{color:#f7f8fd;font-size:.75em;letter-spacing:.1em;text-transform:uppercase}html.theme--catppuccin-mocha .menu-label:not(:first-child){margin-top:1em}html.theme--catppuccin-mocha .menu-label:not(:last-child){margin-bottom:1em}html.theme--catppuccin-mocha .message{background-color:#181825;border-radius:.4em;font-size:1rem}html.theme--catppuccin-mocha .message strong{color:currentColor}html.theme--catppuccin-mocha .message a:not(.button):not(.tag):not(.dropdown-item){color:currentColor;text-decoration:underline}html.theme--catppuccin-mocha .message.is-small,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.message{font-size:.75rem}html.theme--catppuccin-mocha .message.is-medium{font-size:1.25rem}html.theme--catppuccin-mocha .message.is-large{font-size:1.5rem}html.theme--catppuccin-mocha .message.is-white{background-color:#fff}html.theme--catppuccin-mocha .message.is-white .message-header{background-color:#fff;color:#0a0a0a}html.theme--catppuccin-mocha .message.is-white .message-body{border-color:#fff}html.theme--catppuccin-mocha .message.is-black{background-color:#fafafa}html.theme--catppuccin-mocha .message.is-black .message-header{background-color:#0a0a0a;color:#fff}html.theme--catppuccin-mocha .message.is-black .message-body{border-color:#0a0a0a}html.theme--catppuccin-mocha .message.is-light{background-color:#fafafa}html.theme--catppuccin-mocha .message.is-light .message-header{background-color:#f5f5f5;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .message.is-light .message-body{border-color:#f5f5f5}html.theme--catppuccin-mocha .message.is-dark,html.theme--catppuccin-mocha .content kbd.message{background-color:#f9f9fb}html.theme--catppuccin-mocha .message.is-dark .message-header,html.theme--catppuccin-mocha .content kbd.message .message-header{background-color:#313244;color:#fff}html.theme--catppuccin-mocha .message.is-dark .message-body,html.theme--catppuccin-mocha .content kbd.message .message-body{border-color:#313244}html.theme--catppuccin-mocha .message.is-primary,html.theme--catppuccin-mocha .docstring>section>a.message.docs-sourcelink{background-color:#ebf3fe}html.theme--catppuccin-mocha .message.is-primary .message-header,html.theme--catppuccin-mocha .docstring>section>a.message.docs-sourcelink .message-header{background-color:#89b4fa;color:#fff}html.theme--catppuccin-mocha .message.is-primary .message-body,html.theme--catppuccin-mocha .docstring>section>a.message.docs-sourcelink .message-body{border-color:#89b4fa;color:#063c93}html.theme--catppuccin-mocha .message.is-link{background-color:#ebf3fe}html.theme--catppuccin-mocha .message.is-link .message-header{background-color:#89b4fa;color:#fff}html.theme--catppuccin-mocha .message.is-link .message-body{border-color:#89b4fa;color:#063c93}html.theme--catppuccin-mocha .message.is-info{background-color:#effbf9}html.theme--catppuccin-mocha .message.is-info .message-header{background-color:#94e2d5;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .message.is-info .message-body{border-color:#94e2d5;color:#207466}html.theme--catppuccin-mocha .message.is-success{background-color:#f0faef}html.theme--catppuccin-mocha .message.is-success .message-header{background-color:#a6e3a1;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .message.is-success .message-body{border-color:#a6e3a1;color:#287222}html.theme--catppuccin-mocha .message.is-warning{background-color:#fef8ec}html.theme--catppuccin-mocha .message.is-warning .message-header{background-color:#f9e2af;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .message.is-warning .message-body{border-color:#f9e2af;color:#8a620a}html.theme--catppuccin-mocha .message.is-danger{background-color:#fdedf1}html.theme--catppuccin-mocha .message.is-danger .message-header{background-color:#f38ba8;color:#fff}html.theme--catppuccin-mocha .message.is-danger .message-body{border-color:#f38ba8;color:#991036}html.theme--catppuccin-mocha .message-header{align-items:center;background-color:#cdd6f4;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--catppuccin-mocha .message-header .delete{flex-grow:0;flex-shrink:0;margin-left:.75em}html.theme--catppuccin-mocha .message-header+.message-body{border-width:0;border-top-left-radius:0;border-top-right-radius:0}html.theme--catppuccin-mocha .message-body{border-color:#585b70;border-radius:.4em;border-style:solid;border-width:0 0 0 4px;color:#cdd6f4;padding:1.25em 1.5em}html.theme--catppuccin-mocha .message-body code,html.theme--catppuccin-mocha .message-body pre{background-color:#fff}html.theme--catppuccin-mocha .message-body pre code{background-color:rgba(0,0,0,0)}html.theme--catppuccin-mocha .modal{align-items:center;display:none;flex-direction:column;justify-content:center;overflow:hidden;position:fixed;z-index:40}html.theme--catppuccin-mocha .modal.is-active{display:flex}html.theme--catppuccin-mocha .modal-background{background-color:rgba(10,10,10,0.86)}html.theme--catppuccin-mocha .modal-content,html.theme--catppuccin-mocha .modal-card{margin:0 20px;max-height:calc(100vh - 160px);overflow:auto;position:relative;width:100%}@media screen and (min-width: 769px){html.theme--catppuccin-mocha .modal-content,html.theme--catppuccin-mocha .modal-card{margin:0 auto;max-height:calc(100vh - 40px);width:640px}}html.theme--catppuccin-mocha .modal-close{background:none;height:40px;position:fixed;right:20px;top:20px;width:40px}html.theme--catppuccin-mocha .modal-card{display:flex;flex-direction:column;max-height:calc(100vh - 40px);overflow:hidden;-ms-overflow-y:visible}html.theme--catppuccin-mocha .modal-card-head,html.theme--catppuccin-mocha .modal-card-foot{align-items:center;background-color:#181825;display:flex;flex-shrink:0;justify-content:flex-start;padding:20px;position:relative}html.theme--catppuccin-mocha .modal-card-head{border-bottom:1px solid #585b70;border-top-left-radius:8px;border-top-right-radius:8px}html.theme--catppuccin-mocha .modal-card-title{color:#cdd6f4;flex-grow:1;flex-shrink:0;font-size:1.5rem;line-height:1}html.theme--catppuccin-mocha .modal-card-foot{border-bottom-left-radius:8px;border-bottom-right-radius:8px;border-top:1px solid #585b70}html.theme--catppuccin-mocha .modal-card-foot .button:not(:last-child){margin-right:.5em}html.theme--catppuccin-mocha .modal-card-body{-webkit-overflow-scrolling:touch;background-color:#1e1e2e;flex-grow:1;flex-shrink:1;overflow:auto;padding:20px}html.theme--catppuccin-mocha .navbar{background-color:#89b4fa;min-height:4rem;position:relative;z-index:30}html.theme--catppuccin-mocha .navbar.is-white{background-color:#fff;color:#0a0a0a}html.theme--catppuccin-mocha .navbar.is-white .navbar-brand>.navbar-item,html.theme--catppuccin-mocha .navbar.is-white .navbar-brand .navbar-link{color:#0a0a0a}html.theme--catppuccin-mocha .navbar.is-white .navbar-brand>a.navbar-item:focus,html.theme--catppuccin-mocha .navbar.is-white .navbar-brand>a.navbar-item:hover,html.theme--catppuccin-mocha .navbar.is-white .navbar-brand>a.navbar-item.is-active,html.theme--catppuccin-mocha .navbar.is-white .navbar-brand .navbar-link:focus,html.theme--catppuccin-mocha .navbar.is-white .navbar-brand .navbar-link:hover,html.theme--catppuccin-mocha .navbar.is-white .navbar-brand .navbar-link.is-active{background-color:#f2f2f2;color:#0a0a0a}html.theme--catppuccin-mocha .navbar.is-white .navbar-brand .navbar-link::after{border-color:#0a0a0a}html.theme--catppuccin-mocha .navbar.is-white .navbar-burger{color:#0a0a0a}@media screen and (min-width: 1056px){html.theme--catppuccin-mocha .navbar.is-white .navbar-start>.navbar-item,html.theme--catppuccin-mocha .navbar.is-white .navbar-start .navbar-link,html.theme--catppuccin-mocha .navbar.is-white .navbar-end>.navbar-item,html.theme--catppuccin-mocha .navbar.is-white .navbar-end .navbar-link{color:#0a0a0a}html.theme--catppuccin-mocha .navbar.is-white .navbar-start>a.navbar-item:focus,html.theme--catppuccin-mocha .navbar.is-white .navbar-start>a.navbar-item:hover,html.theme--catppuccin-mocha .navbar.is-white .navbar-start>a.navbar-item.is-active,html.theme--catppuccin-mocha .navbar.is-white .navbar-start .navbar-link:focus,html.theme--catppuccin-mocha .navbar.is-white .navbar-start .navbar-link:hover,html.theme--catppuccin-mocha .navbar.is-white .navbar-start .navbar-link.is-active,html.theme--catppuccin-mocha .navbar.is-white .navbar-end>a.navbar-item:focus,html.theme--catppuccin-mocha .navbar.is-white .navbar-end>a.navbar-item:hover,html.theme--catppuccin-mocha .navbar.is-white .navbar-end>a.navbar-item.is-active,html.theme--catppuccin-mocha .navbar.is-white .navbar-end .navbar-link:focus,html.theme--catppuccin-mocha .navbar.is-white .navbar-end .navbar-link:hover,html.theme--catppuccin-mocha .navbar.is-white .navbar-end .navbar-link.is-active{background-color:#f2f2f2;color:#0a0a0a}html.theme--catppuccin-mocha .navbar.is-white .navbar-start .navbar-link::after,html.theme--catppuccin-mocha .navbar.is-white .navbar-end .navbar-link::after{border-color:#0a0a0a}html.theme--catppuccin-mocha .navbar.is-white .navbar-item.has-dropdown:focus .navbar-link,html.theme--catppuccin-mocha .navbar.is-white .navbar-item.has-dropdown:hover .navbar-link,html.theme--catppuccin-mocha .navbar.is-white .navbar-item.has-dropdown.is-active .navbar-link{background-color:#f2f2f2;color:#0a0a0a}html.theme--catppuccin-mocha .navbar.is-white .navbar-dropdown a.navbar-item.is-active{background-color:#fff;color:#0a0a0a}}html.theme--catppuccin-mocha .navbar.is-black{background-color:#0a0a0a;color:#fff}html.theme--catppuccin-mocha .navbar.is-black .navbar-brand>.navbar-item,html.theme--catppuccin-mocha .navbar.is-black .navbar-brand .navbar-link{color:#fff}html.theme--catppuccin-mocha .navbar.is-black .navbar-brand>a.navbar-item:focus,html.theme--catppuccin-mocha .navbar.is-black .navbar-brand>a.navbar-item:hover,html.theme--catppuccin-mocha .navbar.is-black .navbar-brand>a.navbar-item.is-active,html.theme--catppuccin-mocha .navbar.is-black .navbar-brand .navbar-link:focus,html.theme--catppuccin-mocha .navbar.is-black .navbar-brand .navbar-link:hover,html.theme--catppuccin-mocha .navbar.is-black .navbar-brand .navbar-link.is-active{background-color:#000;color:#fff}html.theme--catppuccin-mocha .navbar.is-black .navbar-brand .navbar-link::after{border-color:#fff}html.theme--catppuccin-mocha .navbar.is-black .navbar-burger{color:#fff}@media screen and (min-width: 1056px){html.theme--catppuccin-mocha .navbar.is-black .navbar-start>.navbar-item,html.theme--catppuccin-mocha .navbar.is-black .navbar-start .navbar-link,html.theme--catppuccin-mocha .navbar.is-black .navbar-end>.navbar-item,html.theme--catppuccin-mocha .navbar.is-black .navbar-end .navbar-link{color:#fff}html.theme--catppuccin-mocha .navbar.is-black .navbar-start>a.navbar-item:focus,html.theme--catppuccin-mocha .navbar.is-black .navbar-start>a.navbar-item:hover,html.theme--catppuccin-mocha .navbar.is-black .navbar-start>a.navbar-item.is-active,html.theme--catppuccin-mocha .navbar.is-black .navbar-start .navbar-link:focus,html.theme--catppuccin-mocha .navbar.is-black .navbar-start .navbar-link:hover,html.theme--catppuccin-mocha .navbar.is-black .navbar-start .navbar-link.is-active,html.theme--catppuccin-mocha .navbar.is-black .navbar-end>a.navbar-item:focus,html.theme--catppuccin-mocha .navbar.is-black .navbar-end>a.navbar-item:hover,html.theme--catppuccin-mocha .navbar.is-black .navbar-end>a.navbar-item.is-active,html.theme--catppuccin-mocha .navbar.is-black .navbar-end .navbar-link:focus,html.theme--catppuccin-mocha .navbar.is-black .navbar-end .navbar-link:hover,html.theme--catppuccin-mocha .navbar.is-black .navbar-end .navbar-link.is-active{background-color:#000;color:#fff}html.theme--catppuccin-mocha .navbar.is-black .navbar-start .navbar-link::after,html.theme--catppuccin-mocha .navbar.is-black .navbar-end .navbar-link::after{border-color:#fff}html.theme--catppuccin-mocha .navbar.is-black .navbar-item.has-dropdown:focus .navbar-link,html.theme--catppuccin-mocha .navbar.is-black .navbar-item.has-dropdown:hover .navbar-link,html.theme--catppuccin-mocha .navbar.is-black .navbar-item.has-dropdown.is-active .navbar-link{background-color:#000;color:#fff}html.theme--catppuccin-mocha .navbar.is-black .navbar-dropdown a.navbar-item.is-active{background-color:#0a0a0a;color:#fff}}html.theme--catppuccin-mocha .navbar.is-light{background-color:#f5f5f5;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .navbar.is-light .navbar-brand>.navbar-item,html.theme--catppuccin-mocha .navbar.is-light .navbar-brand .navbar-link{color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .navbar.is-light .navbar-brand>a.navbar-item:focus,html.theme--catppuccin-mocha .navbar.is-light .navbar-brand>a.navbar-item:hover,html.theme--catppuccin-mocha .navbar.is-light .navbar-brand>a.navbar-item.is-active,html.theme--catppuccin-mocha .navbar.is-light .navbar-brand .navbar-link:focus,html.theme--catppuccin-mocha .navbar.is-light .navbar-brand .navbar-link:hover,html.theme--catppuccin-mocha .navbar.is-light .navbar-brand .navbar-link.is-active{background-color:#e8e8e8;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .navbar.is-light .navbar-brand .navbar-link::after{border-color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .navbar.is-light .navbar-burger{color:rgba(0,0,0,0.7)}@media screen and (min-width: 1056px){html.theme--catppuccin-mocha .navbar.is-light .navbar-start>.navbar-item,html.theme--catppuccin-mocha .navbar.is-light .navbar-start .navbar-link,html.theme--catppuccin-mocha .navbar.is-light .navbar-end>.navbar-item,html.theme--catppuccin-mocha .navbar.is-light .navbar-end .navbar-link{color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .navbar.is-light .navbar-start>a.navbar-item:focus,html.theme--catppuccin-mocha .navbar.is-light .navbar-start>a.navbar-item:hover,html.theme--catppuccin-mocha .navbar.is-light .navbar-start>a.navbar-item.is-active,html.theme--catppuccin-mocha .navbar.is-light .navbar-start .navbar-link:focus,html.theme--catppuccin-mocha .navbar.is-light .navbar-start .navbar-link:hover,html.theme--catppuccin-mocha .navbar.is-light .navbar-start .navbar-link.is-active,html.theme--catppuccin-mocha .navbar.is-light .navbar-end>a.navbar-item:focus,html.theme--catppuccin-mocha .navbar.is-light .navbar-end>a.navbar-item:hover,html.theme--catppuccin-mocha .navbar.is-light .navbar-end>a.navbar-item.is-active,html.theme--catppuccin-mocha .navbar.is-light .navbar-end .navbar-link:focus,html.theme--catppuccin-mocha .navbar.is-light .navbar-end .navbar-link:hover,html.theme--catppuccin-mocha .navbar.is-light .navbar-end .navbar-link.is-active{background-color:#e8e8e8;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .navbar.is-light .navbar-start .navbar-link::after,html.theme--catppuccin-mocha .navbar.is-light .navbar-end .navbar-link::after{border-color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .navbar.is-light .navbar-item.has-dropdown:focus .navbar-link,html.theme--catppuccin-mocha .navbar.is-light .navbar-item.has-dropdown:hover .navbar-link,html.theme--catppuccin-mocha .navbar.is-light .navbar-item.has-dropdown.is-active .navbar-link{background-color:#e8e8e8;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .navbar.is-light .navbar-dropdown a.navbar-item.is-active{background-color:#f5f5f5;color:rgba(0,0,0,0.7)}}html.theme--catppuccin-mocha .navbar.is-dark,html.theme--catppuccin-mocha .content kbd.navbar{background-color:#313244;color:#fff}html.theme--catppuccin-mocha .navbar.is-dark .navbar-brand>.navbar-item,html.theme--catppuccin-mocha .content kbd.navbar .navbar-brand>.navbar-item,html.theme--catppuccin-mocha .navbar.is-dark .navbar-brand .navbar-link,html.theme--catppuccin-mocha .content kbd.navbar .navbar-brand .navbar-link{color:#fff}html.theme--catppuccin-mocha .navbar.is-dark .navbar-brand>a.navbar-item:focus,html.theme--catppuccin-mocha .content kbd.navbar .navbar-brand>a.navbar-item:focus,html.theme--catppuccin-mocha .navbar.is-dark .navbar-brand>a.navbar-item:hover,html.theme--catppuccin-mocha .content kbd.navbar .navbar-brand>a.navbar-item:hover,html.theme--catppuccin-mocha .navbar.is-dark .navbar-brand>a.navbar-item.is-active,html.theme--catppuccin-mocha .content kbd.navbar .navbar-brand>a.navbar-item.is-active,html.theme--catppuccin-mocha .navbar.is-dark .navbar-brand .navbar-link:focus,html.theme--catppuccin-mocha .content kbd.navbar .navbar-brand .navbar-link:focus,html.theme--catppuccin-mocha .navbar.is-dark .navbar-brand .navbar-link:hover,html.theme--catppuccin-mocha .content kbd.navbar .navbar-brand .navbar-link:hover,html.theme--catppuccin-mocha .navbar.is-dark .navbar-brand .navbar-link.is-active,html.theme--catppuccin-mocha .content kbd.navbar .navbar-brand .navbar-link.is-active{background-color:#262735;color:#fff}html.theme--catppuccin-mocha .navbar.is-dark .navbar-brand .navbar-link::after,html.theme--catppuccin-mocha .content kbd.navbar .navbar-brand .navbar-link::after{border-color:#fff}html.theme--catppuccin-mocha .navbar.is-dark .navbar-burger,html.theme--catppuccin-mocha .content kbd.navbar .navbar-burger{color:#fff}@media screen and (min-width: 1056px){html.theme--catppuccin-mocha .navbar.is-dark .navbar-start>.navbar-item,html.theme--catppuccin-mocha .content kbd.navbar .navbar-start>.navbar-item,html.theme--catppuccin-mocha .navbar.is-dark .navbar-start .navbar-link,html.theme--catppuccin-mocha .content kbd.navbar .navbar-start .navbar-link,html.theme--catppuccin-mocha .navbar.is-dark .navbar-end>.navbar-item,html.theme--catppuccin-mocha .content kbd.navbar .navbar-end>.navbar-item,html.theme--catppuccin-mocha .navbar.is-dark .navbar-end .navbar-link,html.theme--catppuccin-mocha .content kbd.navbar .navbar-end .navbar-link{color:#fff}html.theme--catppuccin-mocha .navbar.is-dark .navbar-start>a.navbar-item:focus,html.theme--catppuccin-mocha .content kbd.navbar .navbar-start>a.navbar-item:focus,html.theme--catppuccin-mocha .navbar.is-dark .navbar-start>a.navbar-item:hover,html.theme--catppuccin-mocha .content kbd.navbar .navbar-start>a.navbar-item:hover,html.theme--catppuccin-mocha .navbar.is-dark .navbar-start>a.navbar-item.is-active,html.theme--catppuccin-mocha .content kbd.navbar .navbar-start>a.navbar-item.is-active,html.theme--catppuccin-mocha .navbar.is-dark .navbar-start .navbar-link:focus,html.theme--catppuccin-mocha .content kbd.navbar .navbar-start .navbar-link:focus,html.theme--catppuccin-mocha .navbar.is-dark .navbar-start .navbar-link:hover,html.theme--catppuccin-mocha .content kbd.navbar .navbar-start .navbar-link:hover,html.theme--catppuccin-mocha .navbar.is-dark .navbar-start .navbar-link.is-active,html.theme--catppuccin-mocha .content kbd.navbar .navbar-start .navbar-link.is-active,html.theme--catppuccin-mocha .navbar.is-dark .navbar-end>a.navbar-item:focus,html.theme--catppuccin-mocha .content kbd.navbar .navbar-end>a.navbar-item:focus,html.theme--catppuccin-mocha .navbar.is-dark .navbar-end>a.navbar-item:hover,html.theme--catppuccin-mocha .content kbd.navbar .navbar-end>a.navbar-item:hover,html.theme--catppuccin-mocha .navbar.is-dark .navbar-end>a.navbar-item.is-active,html.theme--catppuccin-mocha .content kbd.navbar .navbar-end>a.navbar-item.is-active,html.theme--catppuccin-mocha .navbar.is-dark .navbar-end .navbar-link:focus,html.theme--catppuccin-mocha .content kbd.navbar .navbar-end .navbar-link:focus,html.theme--catppuccin-mocha .navbar.is-dark .navbar-end .navbar-link:hover,html.theme--catppuccin-mocha .content kbd.navbar .navbar-end .navbar-link:hover,html.theme--catppuccin-mocha .navbar.is-dark .navbar-end .navbar-link.is-active,html.theme--catppuccin-mocha .content kbd.navbar .navbar-end .navbar-link.is-active{background-color:#262735;color:#fff}html.theme--catppuccin-mocha .navbar.is-dark .navbar-start .navbar-link::after,html.theme--catppuccin-mocha .content kbd.navbar .navbar-start .navbar-link::after,html.theme--catppuccin-mocha .navbar.is-dark .navbar-end .navbar-link::after,html.theme--catppuccin-mocha .content kbd.navbar .navbar-end .navbar-link::after{border-color:#fff}html.theme--catppuccin-mocha .navbar.is-dark .navbar-item.has-dropdown:focus .navbar-link,html.theme--catppuccin-mocha .content kbd.navbar .navbar-item.has-dropdown:focus .navbar-link,html.theme--catppuccin-mocha .navbar.is-dark .navbar-item.has-dropdown:hover .navbar-link,html.theme--catppuccin-mocha .content kbd.navbar .navbar-item.has-dropdown:hover .navbar-link,html.theme--catppuccin-mocha .navbar.is-dark .navbar-item.has-dropdown.is-active .navbar-link,html.theme--catppuccin-mocha .content kbd.navbar .navbar-item.has-dropdown.is-active .navbar-link{background-color:#262735;color:#fff}html.theme--catppuccin-mocha .navbar.is-dark .navbar-dropdown a.navbar-item.is-active,html.theme--catppuccin-mocha .content kbd.navbar .navbar-dropdown a.navbar-item.is-active{background-color:#313244;color:#fff}}html.theme--catppuccin-mocha .navbar.is-primary,html.theme--catppuccin-mocha .docstring>section>a.navbar.docs-sourcelink{background-color:#89b4fa;color:#fff}html.theme--catppuccin-mocha .navbar.is-primary .navbar-brand>.navbar-item,html.theme--catppuccin-mocha .docstring>section>a.navbar.docs-sourcelink .navbar-brand>.navbar-item,html.theme--catppuccin-mocha .navbar.is-primary .navbar-brand .navbar-link,html.theme--catppuccin-mocha .docstring>section>a.navbar.docs-sourcelink .navbar-brand .navbar-link{color:#fff}html.theme--catppuccin-mocha .navbar.is-primary .navbar-brand>a.navbar-item:focus,html.theme--catppuccin-mocha .docstring>section>a.navbar.docs-sourcelink .navbar-brand>a.navbar-item:focus,html.theme--catppuccin-mocha .navbar.is-primary .navbar-brand>a.navbar-item:hover,html.theme--catppuccin-mocha .docstring>section>a.navbar.docs-sourcelink .navbar-brand>a.navbar-item:hover,html.theme--catppuccin-mocha .navbar.is-primary .navbar-brand>a.navbar-item.is-active,html.theme--catppuccin-mocha .docstring>section>a.navbar.docs-sourcelink .navbar-brand>a.navbar-item.is-active,html.theme--catppuccin-mocha .navbar.is-primary .navbar-brand .navbar-link:focus,html.theme--catppuccin-mocha .docstring>section>a.navbar.docs-sourcelink .navbar-brand .navbar-link:focus,html.theme--catppuccin-mocha .navbar.is-primary .navbar-brand .navbar-link:hover,html.theme--catppuccin-mocha .docstring>section>a.navbar.docs-sourcelink .navbar-brand .navbar-link:hover,html.theme--catppuccin-mocha .navbar.is-primary .navbar-brand .navbar-link.is-active,html.theme--catppuccin-mocha .docstring>section>a.navbar.docs-sourcelink .navbar-brand .navbar-link.is-active{background-color:#71a4f9;color:#fff}html.theme--catppuccin-mocha .navbar.is-primary .navbar-brand .navbar-link::after,html.theme--catppuccin-mocha .docstring>section>a.navbar.docs-sourcelink .navbar-brand .navbar-link::after{border-color:#fff}html.theme--catppuccin-mocha .navbar.is-primary .navbar-burger,html.theme--catppuccin-mocha .docstring>section>a.navbar.docs-sourcelink .navbar-burger{color:#fff}@media screen and (min-width: 1056px){html.theme--catppuccin-mocha .navbar.is-primary .navbar-start>.navbar-item,html.theme--catppuccin-mocha .docstring>section>a.navbar.docs-sourcelink .navbar-start>.navbar-item,html.theme--catppuccin-mocha .navbar.is-primary .navbar-start .navbar-link,html.theme--catppuccin-mocha .docstring>section>a.navbar.docs-sourcelink .navbar-start .navbar-link,html.theme--catppuccin-mocha .navbar.is-primary .navbar-end>.navbar-item,html.theme--catppuccin-mocha .docstring>section>a.navbar.docs-sourcelink .navbar-end>.navbar-item,html.theme--catppuccin-mocha .navbar.is-primary .navbar-end .navbar-link,html.theme--catppuccin-mocha .docstring>section>a.navbar.docs-sourcelink .navbar-end .navbar-link{color:#fff}html.theme--catppuccin-mocha .navbar.is-primary .navbar-start>a.navbar-item:focus,html.theme--catppuccin-mocha .docstring>section>a.navbar.docs-sourcelink .navbar-start>a.navbar-item:focus,html.theme--catppuccin-mocha .navbar.is-primary .navbar-start>a.navbar-item:hover,html.theme--catppuccin-mocha .docstring>section>a.navbar.docs-sourcelink .navbar-start>a.navbar-item:hover,html.theme--catppuccin-mocha .navbar.is-primary .navbar-start>a.navbar-item.is-active,html.theme--catppuccin-mocha .docstring>section>a.navbar.docs-sourcelink .navbar-start>a.navbar-item.is-active,html.theme--catppuccin-mocha .navbar.is-primary .navbar-start .navbar-link:focus,html.theme--catppuccin-mocha .docstring>section>a.navbar.docs-sourcelink .navbar-start .navbar-link:focus,html.theme--catppuccin-mocha .navbar.is-primary .navbar-start .navbar-link:hover,html.theme--catppuccin-mocha .docstring>section>a.navbar.docs-sourcelink .navbar-start .navbar-link:hover,html.theme--catppuccin-mocha .navbar.is-primary .navbar-start .navbar-link.is-active,html.theme--catppuccin-mocha .docstring>section>a.navbar.docs-sourcelink .navbar-start .navbar-link.is-active,html.theme--catppuccin-mocha .navbar.is-primary .navbar-end>a.navbar-item:focus,html.theme--catppuccin-mocha .docstring>section>a.navbar.docs-sourcelink .navbar-end>a.navbar-item:focus,html.theme--catppuccin-mocha .navbar.is-primary .navbar-end>a.navbar-item:hover,html.theme--catppuccin-mocha .docstring>section>a.navbar.docs-sourcelink .navbar-end>a.navbar-item:hover,html.theme--catppuccin-mocha .navbar.is-primary .navbar-end>a.navbar-item.is-active,html.theme--catppuccin-mocha .docstring>section>a.navbar.docs-sourcelink .navbar-end>a.navbar-item.is-active,html.theme--catppuccin-mocha .navbar.is-primary .navbar-end .navbar-link:focus,html.theme--catppuccin-mocha .docstring>section>a.navbar.docs-sourcelink .navbar-end .navbar-link:focus,html.theme--catppuccin-mocha .navbar.is-primary .navbar-end .navbar-link:hover,html.theme--catppuccin-mocha .docstring>section>a.navbar.docs-sourcelink .navbar-end .navbar-link:hover,html.theme--catppuccin-mocha .navbar.is-primary .navbar-end .navbar-link.is-active,html.theme--catppuccin-mocha .docstring>section>a.navbar.docs-sourcelink .navbar-end .navbar-link.is-active{background-color:#71a4f9;color:#fff}html.theme--catppuccin-mocha .navbar.is-primary .navbar-start .navbar-link::after,html.theme--catppuccin-mocha .docstring>section>a.navbar.docs-sourcelink .navbar-start .navbar-link::after,html.theme--catppuccin-mocha .navbar.is-primary .navbar-end .navbar-link::after,html.theme--catppuccin-mocha .docstring>section>a.navbar.docs-sourcelink .navbar-end .navbar-link::after{border-color:#fff}html.theme--catppuccin-mocha .navbar.is-primary .navbar-item.has-dropdown:focus .navbar-link,html.theme--catppuccin-mocha .docstring>section>a.navbar.docs-sourcelink .navbar-item.has-dropdown:focus .navbar-link,html.theme--catppuccin-mocha .navbar.is-primary .navbar-item.has-dropdown:hover .navbar-link,html.theme--catppuccin-mocha .docstring>section>a.navbar.docs-sourcelink .navbar-item.has-dropdown:hover .navbar-link,html.theme--catppuccin-mocha .navbar.is-primary .navbar-item.has-dropdown.is-active .navbar-link,html.theme--catppuccin-mocha .docstring>section>a.navbar.docs-sourcelink .navbar-item.has-dropdown.is-active .navbar-link{background-color:#71a4f9;color:#fff}html.theme--catppuccin-mocha .navbar.is-primary .navbar-dropdown a.navbar-item.is-active,html.theme--catppuccin-mocha .docstring>section>a.navbar.docs-sourcelink .navbar-dropdown a.navbar-item.is-active{background-color:#89b4fa;color:#fff}}html.theme--catppuccin-mocha .navbar.is-link{background-color:#89b4fa;color:#fff}html.theme--catppuccin-mocha .navbar.is-link .navbar-brand>.navbar-item,html.theme--catppuccin-mocha .navbar.is-link .navbar-brand .navbar-link{color:#fff}html.theme--catppuccin-mocha .navbar.is-link .navbar-brand>a.navbar-item:focus,html.theme--catppuccin-mocha .navbar.is-link .navbar-brand>a.navbar-item:hover,html.theme--catppuccin-mocha .navbar.is-link .navbar-brand>a.navbar-item.is-active,html.theme--catppuccin-mocha .navbar.is-link .navbar-brand .navbar-link:focus,html.theme--catppuccin-mocha .navbar.is-link .navbar-brand .navbar-link:hover,html.theme--catppuccin-mocha .navbar.is-link .navbar-brand .navbar-link.is-active{background-color:#71a4f9;color:#fff}html.theme--catppuccin-mocha .navbar.is-link .navbar-brand .navbar-link::after{border-color:#fff}html.theme--catppuccin-mocha .navbar.is-link .navbar-burger{color:#fff}@media screen and (min-width: 1056px){html.theme--catppuccin-mocha .navbar.is-link .navbar-start>.navbar-item,html.theme--catppuccin-mocha .navbar.is-link .navbar-start .navbar-link,html.theme--catppuccin-mocha .navbar.is-link .navbar-end>.navbar-item,html.theme--catppuccin-mocha .navbar.is-link .navbar-end .navbar-link{color:#fff}html.theme--catppuccin-mocha .navbar.is-link .navbar-start>a.navbar-item:focus,html.theme--catppuccin-mocha .navbar.is-link .navbar-start>a.navbar-item:hover,html.theme--catppuccin-mocha .navbar.is-link .navbar-start>a.navbar-item.is-active,html.theme--catppuccin-mocha .navbar.is-link .navbar-start .navbar-link:focus,html.theme--catppuccin-mocha .navbar.is-link .navbar-start .navbar-link:hover,html.theme--catppuccin-mocha .navbar.is-link .navbar-start .navbar-link.is-active,html.theme--catppuccin-mocha .navbar.is-link .navbar-end>a.navbar-item:focus,html.theme--catppuccin-mocha .navbar.is-link .navbar-end>a.navbar-item:hover,html.theme--catppuccin-mocha .navbar.is-link .navbar-end>a.navbar-item.is-active,html.theme--catppuccin-mocha .navbar.is-link .navbar-end .navbar-link:focus,html.theme--catppuccin-mocha .navbar.is-link .navbar-end .navbar-link:hover,html.theme--catppuccin-mocha .navbar.is-link .navbar-end .navbar-link.is-active{background-color:#71a4f9;color:#fff}html.theme--catppuccin-mocha .navbar.is-link .navbar-start .navbar-link::after,html.theme--catppuccin-mocha .navbar.is-link .navbar-end .navbar-link::after{border-color:#fff}html.theme--catppuccin-mocha .navbar.is-link .navbar-item.has-dropdown:focus .navbar-link,html.theme--catppuccin-mocha .navbar.is-link .navbar-item.has-dropdown:hover .navbar-link,html.theme--catppuccin-mocha .navbar.is-link .navbar-item.has-dropdown.is-active .navbar-link{background-color:#71a4f9;color:#fff}html.theme--catppuccin-mocha .navbar.is-link .navbar-dropdown a.navbar-item.is-active{background-color:#89b4fa;color:#fff}}html.theme--catppuccin-mocha .navbar.is-info{background-color:#94e2d5;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .navbar.is-info .navbar-brand>.navbar-item,html.theme--catppuccin-mocha .navbar.is-info .navbar-brand .navbar-link{color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .navbar.is-info .navbar-brand>a.navbar-item:focus,html.theme--catppuccin-mocha .navbar.is-info .navbar-brand>a.navbar-item:hover,html.theme--catppuccin-mocha .navbar.is-info .navbar-brand>a.navbar-item.is-active,html.theme--catppuccin-mocha .navbar.is-info .navbar-brand .navbar-link:focus,html.theme--catppuccin-mocha .navbar.is-info .navbar-brand .navbar-link:hover,html.theme--catppuccin-mocha .navbar.is-info .navbar-brand .navbar-link.is-active{background-color:#80ddcd;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .navbar.is-info .navbar-brand .navbar-link::after{border-color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .navbar.is-info .navbar-burger{color:rgba(0,0,0,0.7)}@media screen and (min-width: 1056px){html.theme--catppuccin-mocha .navbar.is-info .navbar-start>.navbar-item,html.theme--catppuccin-mocha .navbar.is-info .navbar-start .navbar-link,html.theme--catppuccin-mocha .navbar.is-info .navbar-end>.navbar-item,html.theme--catppuccin-mocha .navbar.is-info .navbar-end .navbar-link{color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .navbar.is-info .navbar-start>a.navbar-item:focus,html.theme--catppuccin-mocha .navbar.is-info .navbar-start>a.navbar-item:hover,html.theme--catppuccin-mocha .navbar.is-info .navbar-start>a.navbar-item.is-active,html.theme--catppuccin-mocha .navbar.is-info .navbar-start .navbar-link:focus,html.theme--catppuccin-mocha .navbar.is-info .navbar-start .navbar-link:hover,html.theme--catppuccin-mocha .navbar.is-info .navbar-start .navbar-link.is-active,html.theme--catppuccin-mocha .navbar.is-info .navbar-end>a.navbar-item:focus,html.theme--catppuccin-mocha .navbar.is-info .navbar-end>a.navbar-item:hover,html.theme--catppuccin-mocha .navbar.is-info .navbar-end>a.navbar-item.is-active,html.theme--catppuccin-mocha .navbar.is-info .navbar-end .navbar-link:focus,html.theme--catppuccin-mocha .navbar.is-info .navbar-end .navbar-link:hover,html.theme--catppuccin-mocha .navbar.is-info .navbar-end .navbar-link.is-active{background-color:#80ddcd;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .navbar.is-info .navbar-start .navbar-link::after,html.theme--catppuccin-mocha .navbar.is-info .navbar-end .navbar-link::after{border-color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .navbar.is-info .navbar-item.has-dropdown:focus .navbar-link,html.theme--catppuccin-mocha .navbar.is-info .navbar-item.has-dropdown:hover .navbar-link,html.theme--catppuccin-mocha .navbar.is-info .navbar-item.has-dropdown.is-active .navbar-link{background-color:#80ddcd;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .navbar.is-info .navbar-dropdown a.navbar-item.is-active{background-color:#94e2d5;color:rgba(0,0,0,0.7)}}html.theme--catppuccin-mocha .navbar.is-success{background-color:#a6e3a1;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .navbar.is-success .navbar-brand>.navbar-item,html.theme--catppuccin-mocha .navbar.is-success .navbar-brand .navbar-link{color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .navbar.is-success .navbar-brand>a.navbar-item:focus,html.theme--catppuccin-mocha .navbar.is-success .navbar-brand>a.navbar-item:hover,html.theme--catppuccin-mocha .navbar.is-success .navbar-brand>a.navbar-item.is-active,html.theme--catppuccin-mocha .navbar.is-success .navbar-brand .navbar-link:focus,html.theme--catppuccin-mocha .navbar.is-success .navbar-brand .navbar-link:hover,html.theme--catppuccin-mocha .navbar.is-success .navbar-brand .navbar-link.is-active{background-color:#93dd8d;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .navbar.is-success .navbar-brand .navbar-link::after{border-color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .navbar.is-success .navbar-burger{color:rgba(0,0,0,0.7)}@media screen and (min-width: 1056px){html.theme--catppuccin-mocha .navbar.is-success .navbar-start>.navbar-item,html.theme--catppuccin-mocha .navbar.is-success .navbar-start .navbar-link,html.theme--catppuccin-mocha .navbar.is-success .navbar-end>.navbar-item,html.theme--catppuccin-mocha .navbar.is-success .navbar-end .navbar-link{color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .navbar.is-success .navbar-start>a.navbar-item:focus,html.theme--catppuccin-mocha .navbar.is-success .navbar-start>a.navbar-item:hover,html.theme--catppuccin-mocha .navbar.is-success .navbar-start>a.navbar-item.is-active,html.theme--catppuccin-mocha .navbar.is-success .navbar-start .navbar-link:focus,html.theme--catppuccin-mocha .navbar.is-success .navbar-start .navbar-link:hover,html.theme--catppuccin-mocha .navbar.is-success .navbar-start .navbar-link.is-active,html.theme--catppuccin-mocha .navbar.is-success .navbar-end>a.navbar-item:focus,html.theme--catppuccin-mocha .navbar.is-success .navbar-end>a.navbar-item:hover,html.theme--catppuccin-mocha .navbar.is-success .navbar-end>a.navbar-item.is-active,html.theme--catppuccin-mocha .navbar.is-success .navbar-end .navbar-link:focus,html.theme--catppuccin-mocha .navbar.is-success .navbar-end .navbar-link:hover,html.theme--catppuccin-mocha .navbar.is-success .navbar-end .navbar-link.is-active{background-color:#93dd8d;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .navbar.is-success .navbar-start .navbar-link::after,html.theme--catppuccin-mocha .navbar.is-success .navbar-end .navbar-link::after{border-color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .navbar.is-success .navbar-item.has-dropdown:focus .navbar-link,html.theme--catppuccin-mocha .navbar.is-success .navbar-item.has-dropdown:hover .navbar-link,html.theme--catppuccin-mocha .navbar.is-success .navbar-item.has-dropdown.is-active .navbar-link{background-color:#93dd8d;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .navbar.is-success .navbar-dropdown a.navbar-item.is-active{background-color:#a6e3a1;color:rgba(0,0,0,0.7)}}html.theme--catppuccin-mocha .navbar.is-warning{background-color:#f9e2af;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .navbar.is-warning .navbar-brand>.navbar-item,html.theme--catppuccin-mocha .navbar.is-warning .navbar-brand .navbar-link{color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .navbar.is-warning .navbar-brand>a.navbar-item:focus,html.theme--catppuccin-mocha .navbar.is-warning .navbar-brand>a.navbar-item:hover,html.theme--catppuccin-mocha .navbar.is-warning .navbar-brand>a.navbar-item.is-active,html.theme--catppuccin-mocha .navbar.is-warning .navbar-brand .navbar-link:focus,html.theme--catppuccin-mocha .navbar.is-warning .navbar-brand .navbar-link:hover,html.theme--catppuccin-mocha .navbar.is-warning .navbar-brand .navbar-link.is-active{background-color:#f7d997;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .navbar.is-warning .navbar-brand .navbar-link::after{border-color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .navbar.is-warning .navbar-burger{color:rgba(0,0,0,0.7)}@media screen and (min-width: 1056px){html.theme--catppuccin-mocha .navbar.is-warning .navbar-start>.navbar-item,html.theme--catppuccin-mocha .navbar.is-warning .navbar-start .navbar-link,html.theme--catppuccin-mocha .navbar.is-warning .navbar-end>.navbar-item,html.theme--catppuccin-mocha .navbar.is-warning .navbar-end .navbar-link{color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .navbar.is-warning .navbar-start>a.navbar-item:focus,html.theme--catppuccin-mocha .navbar.is-warning .navbar-start>a.navbar-item:hover,html.theme--catppuccin-mocha .navbar.is-warning .navbar-start>a.navbar-item.is-active,html.theme--catppuccin-mocha .navbar.is-warning .navbar-start .navbar-link:focus,html.theme--catppuccin-mocha .navbar.is-warning .navbar-start .navbar-link:hover,html.theme--catppuccin-mocha .navbar.is-warning .navbar-start .navbar-link.is-active,html.theme--catppuccin-mocha .navbar.is-warning .navbar-end>a.navbar-item:focus,html.theme--catppuccin-mocha .navbar.is-warning .navbar-end>a.navbar-item:hover,html.theme--catppuccin-mocha .navbar.is-warning .navbar-end>a.navbar-item.is-active,html.theme--catppuccin-mocha .navbar.is-warning .navbar-end .navbar-link:focus,html.theme--catppuccin-mocha .navbar.is-warning .navbar-end .navbar-link:hover,html.theme--catppuccin-mocha .navbar.is-warning .navbar-end .navbar-link.is-active{background-color:#f7d997;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .navbar.is-warning .navbar-start .navbar-link::after,html.theme--catppuccin-mocha .navbar.is-warning .navbar-end .navbar-link::after{border-color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .navbar.is-warning .navbar-item.has-dropdown:focus .navbar-link,html.theme--catppuccin-mocha .navbar.is-warning .navbar-item.has-dropdown:hover .navbar-link,html.theme--catppuccin-mocha .navbar.is-warning .navbar-item.has-dropdown.is-active .navbar-link{background-color:#f7d997;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .navbar.is-warning .navbar-dropdown a.navbar-item.is-active{background-color:#f9e2af;color:rgba(0,0,0,0.7)}}html.theme--catppuccin-mocha .navbar.is-danger{background-color:#f38ba8;color:#fff}html.theme--catppuccin-mocha .navbar.is-danger .navbar-brand>.navbar-item,html.theme--catppuccin-mocha .navbar.is-danger .navbar-brand .navbar-link{color:#fff}html.theme--catppuccin-mocha .navbar.is-danger .navbar-brand>a.navbar-item:focus,html.theme--catppuccin-mocha .navbar.is-danger .navbar-brand>a.navbar-item:hover,html.theme--catppuccin-mocha .navbar.is-danger .navbar-brand>a.navbar-item.is-active,html.theme--catppuccin-mocha .navbar.is-danger .navbar-brand .navbar-link:focus,html.theme--catppuccin-mocha .navbar.is-danger .navbar-brand .navbar-link:hover,html.theme--catppuccin-mocha .navbar.is-danger .navbar-brand .navbar-link.is-active{background-color:#f17497;color:#fff}html.theme--catppuccin-mocha .navbar.is-danger .navbar-brand .navbar-link::after{border-color:#fff}html.theme--catppuccin-mocha .navbar.is-danger .navbar-burger{color:#fff}@media screen and (min-width: 1056px){html.theme--catppuccin-mocha .navbar.is-danger .navbar-start>.navbar-item,html.theme--catppuccin-mocha .navbar.is-danger .navbar-start .navbar-link,html.theme--catppuccin-mocha .navbar.is-danger .navbar-end>.navbar-item,html.theme--catppuccin-mocha .navbar.is-danger .navbar-end .navbar-link{color:#fff}html.theme--catppuccin-mocha .navbar.is-danger .navbar-start>a.navbar-item:focus,html.theme--catppuccin-mocha .navbar.is-danger .navbar-start>a.navbar-item:hover,html.theme--catppuccin-mocha .navbar.is-danger .navbar-start>a.navbar-item.is-active,html.theme--catppuccin-mocha .navbar.is-danger .navbar-start .navbar-link:focus,html.theme--catppuccin-mocha .navbar.is-danger .navbar-start .navbar-link:hover,html.theme--catppuccin-mocha .navbar.is-danger .navbar-start .navbar-link.is-active,html.theme--catppuccin-mocha .navbar.is-danger .navbar-end>a.navbar-item:focus,html.theme--catppuccin-mocha .navbar.is-danger .navbar-end>a.navbar-item:hover,html.theme--catppuccin-mocha .navbar.is-danger .navbar-end>a.navbar-item.is-active,html.theme--catppuccin-mocha .navbar.is-danger .navbar-end .navbar-link:focus,html.theme--catppuccin-mocha .navbar.is-danger .navbar-end .navbar-link:hover,html.theme--catppuccin-mocha .navbar.is-danger .navbar-end .navbar-link.is-active{background-color:#f17497;color:#fff}html.theme--catppuccin-mocha .navbar.is-danger .navbar-start .navbar-link::after,html.theme--catppuccin-mocha .navbar.is-danger .navbar-end .navbar-link::after{border-color:#fff}html.theme--catppuccin-mocha .navbar.is-danger .navbar-item.has-dropdown:focus .navbar-link,html.theme--catppuccin-mocha .navbar.is-danger .navbar-item.has-dropdown:hover .navbar-link,html.theme--catppuccin-mocha .navbar.is-danger .navbar-item.has-dropdown.is-active .navbar-link{background-color:#f17497;color:#fff}html.theme--catppuccin-mocha .navbar.is-danger .navbar-dropdown a.navbar-item.is-active{background-color:#f38ba8;color:#fff}}html.theme--catppuccin-mocha .navbar>.container{align-items:stretch;display:flex;min-height:4rem;width:100%}html.theme--catppuccin-mocha .navbar.has-shadow{box-shadow:0 2px 0 0 #181825}html.theme--catppuccin-mocha .navbar.is-fixed-bottom,html.theme--catppuccin-mocha .navbar.is-fixed-top{left:0;position:fixed;right:0;z-index:30}html.theme--catppuccin-mocha .navbar.is-fixed-bottom{bottom:0}html.theme--catppuccin-mocha .navbar.is-fixed-bottom.has-shadow{box-shadow:0 -2px 0 0 #181825}html.theme--catppuccin-mocha .navbar.is-fixed-top{top:0}html.theme--catppuccin-mocha html.has-navbar-fixed-top,html.theme--catppuccin-mocha body.has-navbar-fixed-top{padding-top:4rem}html.theme--catppuccin-mocha html.has-navbar-fixed-bottom,html.theme--catppuccin-mocha body.has-navbar-fixed-bottom{padding-bottom:4rem}html.theme--catppuccin-mocha .navbar-brand,html.theme--catppuccin-mocha .navbar-tabs{align-items:stretch;display:flex;flex-shrink:0;min-height:4rem}html.theme--catppuccin-mocha .navbar-brand a.navbar-item:focus,html.theme--catppuccin-mocha .navbar-brand a.navbar-item:hover{background-color:transparent}html.theme--catppuccin-mocha .navbar-tabs{-webkit-overflow-scrolling:touch;max-width:100vw;overflow-x:auto;overflow-y:hidden}html.theme--catppuccin-mocha .navbar-burger{color:#cdd6f4;-moz-appearance:none;-webkit-appearance:none;appearance:none;background:none;border:none;cursor:pointer;display:block;height:4rem;position:relative;width:4rem;margin-left:auto}html.theme--catppuccin-mocha .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--catppuccin-mocha .navbar-burger span:nth-child(1){top:calc(50% - 6px)}html.theme--catppuccin-mocha .navbar-burger span:nth-child(2){top:calc(50% - 1px)}html.theme--catppuccin-mocha .navbar-burger span:nth-child(3){top:calc(50% + 4px)}html.theme--catppuccin-mocha .navbar-burger:hover{background-color:rgba(0,0,0,0.05)}html.theme--catppuccin-mocha .navbar-burger.is-active span:nth-child(1){transform:translateY(5px) rotate(45deg)}html.theme--catppuccin-mocha .navbar-burger.is-active span:nth-child(2){opacity:0}html.theme--catppuccin-mocha .navbar-burger.is-active span:nth-child(3){transform:translateY(-5px) rotate(-45deg)}html.theme--catppuccin-mocha .navbar-menu{display:none}html.theme--catppuccin-mocha .navbar-item,html.theme--catppuccin-mocha .navbar-link{color:#cdd6f4;display:block;line-height:1.5;padding:0.5rem 0.75rem;position:relative}html.theme--catppuccin-mocha .navbar-item .icon:only-child,html.theme--catppuccin-mocha .navbar-link .icon:only-child{margin-left:-0.25rem;margin-right:-0.25rem}html.theme--catppuccin-mocha a.navbar-item,html.theme--catppuccin-mocha .navbar-link{cursor:pointer}html.theme--catppuccin-mocha a.navbar-item:focus,html.theme--catppuccin-mocha a.navbar-item:focus-within,html.theme--catppuccin-mocha a.navbar-item:hover,html.theme--catppuccin-mocha a.navbar-item.is-active,html.theme--catppuccin-mocha .navbar-link:focus,html.theme--catppuccin-mocha .navbar-link:focus-within,html.theme--catppuccin-mocha .navbar-link:hover,html.theme--catppuccin-mocha .navbar-link.is-active{background-color:rgba(0,0,0,0);color:#89b4fa}html.theme--catppuccin-mocha .navbar-item{flex-grow:0;flex-shrink:0}html.theme--catppuccin-mocha .navbar-item img{max-height:1.75rem}html.theme--catppuccin-mocha .navbar-item.has-dropdown{padding:0}html.theme--catppuccin-mocha .navbar-item.is-expanded{flex-grow:1;flex-shrink:1}html.theme--catppuccin-mocha .navbar-item.is-tab{border-bottom:1px solid transparent;min-height:4rem;padding-bottom:calc(0.5rem - 1px)}html.theme--catppuccin-mocha .navbar-item.is-tab:focus,html.theme--catppuccin-mocha .navbar-item.is-tab:hover{background-color:rgba(0,0,0,0);border-bottom-color:#89b4fa}html.theme--catppuccin-mocha .navbar-item.is-tab.is-active{background-color:rgba(0,0,0,0);border-bottom-color:#89b4fa;border-bottom-style:solid;border-bottom-width:3px;color:#89b4fa;padding-bottom:calc(0.5rem - 3px)}html.theme--catppuccin-mocha .navbar-content{flex-grow:1;flex-shrink:1}html.theme--catppuccin-mocha .navbar-link:not(.is-arrowless){padding-right:2.5em}html.theme--catppuccin-mocha .navbar-link:not(.is-arrowless)::after{border-color:#fff;margin-top:-0.375em;right:1.125em}html.theme--catppuccin-mocha .navbar-dropdown{font-size:0.875rem;padding-bottom:0.5rem;padding-top:0.5rem}html.theme--catppuccin-mocha .navbar-dropdown .navbar-item{padding-left:1.5rem;padding-right:1.5rem}html.theme--catppuccin-mocha .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--catppuccin-mocha .navbar>.container{display:block}html.theme--catppuccin-mocha .navbar-brand .navbar-item,html.theme--catppuccin-mocha .navbar-tabs .navbar-item{align-items:center;display:flex}html.theme--catppuccin-mocha .navbar-link::after{display:none}html.theme--catppuccin-mocha .navbar-menu{background-color:#89b4fa;box-shadow:0 8px 16px rgba(10,10,10,0.1);padding:0.5rem 0}html.theme--catppuccin-mocha .navbar-menu.is-active{display:block}html.theme--catppuccin-mocha .navbar.is-fixed-bottom-touch,html.theme--catppuccin-mocha .navbar.is-fixed-top-touch{left:0;position:fixed;right:0;z-index:30}html.theme--catppuccin-mocha .navbar.is-fixed-bottom-touch{bottom:0}html.theme--catppuccin-mocha .navbar.is-fixed-bottom-touch.has-shadow{box-shadow:0 -2px 3px rgba(10,10,10,0.1)}html.theme--catppuccin-mocha .navbar.is-fixed-top-touch{top:0}html.theme--catppuccin-mocha .navbar.is-fixed-top .navbar-menu,html.theme--catppuccin-mocha .navbar.is-fixed-top-touch .navbar-menu{-webkit-overflow-scrolling:touch;max-height:calc(100vh - 4rem);overflow:auto}html.theme--catppuccin-mocha html.has-navbar-fixed-top-touch,html.theme--catppuccin-mocha body.has-navbar-fixed-top-touch{padding-top:4rem}html.theme--catppuccin-mocha html.has-navbar-fixed-bottom-touch,html.theme--catppuccin-mocha body.has-navbar-fixed-bottom-touch{padding-bottom:4rem}}@media screen and (min-width: 1056px){html.theme--catppuccin-mocha .navbar,html.theme--catppuccin-mocha .navbar-menu,html.theme--catppuccin-mocha .navbar-start,html.theme--catppuccin-mocha .navbar-end{align-items:stretch;display:flex}html.theme--catppuccin-mocha .navbar{min-height:4rem}html.theme--catppuccin-mocha .navbar.is-spaced{padding:1rem 2rem}html.theme--catppuccin-mocha .navbar.is-spaced .navbar-start,html.theme--catppuccin-mocha .navbar.is-spaced .navbar-end{align-items:center}html.theme--catppuccin-mocha .navbar.is-spaced a.navbar-item,html.theme--catppuccin-mocha .navbar.is-spaced .navbar-link{border-radius:.4em}html.theme--catppuccin-mocha .navbar.is-transparent a.navbar-item:focus,html.theme--catppuccin-mocha .navbar.is-transparent a.navbar-item:hover,html.theme--catppuccin-mocha .navbar.is-transparent a.navbar-item.is-active,html.theme--catppuccin-mocha .navbar.is-transparent .navbar-link:focus,html.theme--catppuccin-mocha .navbar.is-transparent .navbar-link:hover,html.theme--catppuccin-mocha .navbar.is-transparent .navbar-link.is-active{background-color:transparent !important}html.theme--catppuccin-mocha .navbar.is-transparent .navbar-item.has-dropdown.is-active .navbar-link,html.theme--catppuccin-mocha .navbar.is-transparent .navbar-item.has-dropdown.is-hoverable:focus .navbar-link,html.theme--catppuccin-mocha .navbar.is-transparent .navbar-item.has-dropdown.is-hoverable:focus-within .navbar-link,html.theme--catppuccin-mocha .navbar.is-transparent .navbar-item.has-dropdown.is-hoverable:hover .navbar-link{background-color:transparent !important}html.theme--catppuccin-mocha .navbar.is-transparent .navbar-dropdown a.navbar-item:focus,html.theme--catppuccin-mocha .navbar.is-transparent .navbar-dropdown a.navbar-item:hover{background-color:rgba(0,0,0,0);color:#7f849c}html.theme--catppuccin-mocha .navbar.is-transparent .navbar-dropdown a.navbar-item.is-active{background-color:rgba(0,0,0,0);color:#89b4fa}html.theme--catppuccin-mocha .navbar-burger{display:none}html.theme--catppuccin-mocha .navbar-item,html.theme--catppuccin-mocha .navbar-link{align-items:center;display:flex}html.theme--catppuccin-mocha .navbar-item.has-dropdown{align-items:stretch}html.theme--catppuccin-mocha .navbar-item.has-dropdown-up .navbar-link::after{transform:rotate(135deg) translate(0.25em, -0.25em)}html.theme--catppuccin-mocha .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--catppuccin-mocha .navbar-item.is-active .navbar-dropdown,html.theme--catppuccin-mocha .navbar-item.is-hoverable:focus .navbar-dropdown,html.theme--catppuccin-mocha .navbar-item.is-hoverable:focus-within .navbar-dropdown,html.theme--catppuccin-mocha .navbar-item.is-hoverable:hover .navbar-dropdown{display:block}.navbar.is-spaced html.theme--catppuccin-mocha .navbar-item.is-active .navbar-dropdown,html.theme--catppuccin-mocha .navbar-item.is-active .navbar-dropdown.is-boxed,.navbar.is-spaced html.theme--catppuccin-mocha .navbar-item.is-hoverable:focus .navbar-dropdown,html.theme--catppuccin-mocha .navbar-item.is-hoverable:focus .navbar-dropdown.is-boxed,.navbar.is-spaced html.theme--catppuccin-mocha .navbar-item.is-hoverable:focus-within .navbar-dropdown,html.theme--catppuccin-mocha .navbar-item.is-hoverable:focus-within .navbar-dropdown.is-boxed,.navbar.is-spaced html.theme--catppuccin-mocha .navbar-item.is-hoverable:hover .navbar-dropdown,html.theme--catppuccin-mocha .navbar-item.is-hoverable:hover .navbar-dropdown.is-boxed{opacity:1;pointer-events:auto;transform:translateY(0)}html.theme--catppuccin-mocha .navbar-menu{flex-grow:1;flex-shrink:0}html.theme--catppuccin-mocha .navbar-start{justify-content:flex-start;margin-right:auto}html.theme--catppuccin-mocha .navbar-end{justify-content:flex-end;margin-left:auto}html.theme--catppuccin-mocha .navbar-dropdown{background-color:#89b4fa;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--catppuccin-mocha .navbar-dropdown .navbar-item{padding:0.375rem 1rem;white-space:nowrap}html.theme--catppuccin-mocha .navbar-dropdown a.navbar-item{padding-right:3rem}html.theme--catppuccin-mocha .navbar-dropdown a.navbar-item:focus,html.theme--catppuccin-mocha .navbar-dropdown a.navbar-item:hover{background-color:rgba(0,0,0,0);color:#7f849c}html.theme--catppuccin-mocha .navbar-dropdown a.navbar-item.is-active{background-color:rgba(0,0,0,0);color:#89b4fa}.navbar.is-spaced html.theme--catppuccin-mocha .navbar-dropdown,html.theme--catppuccin-mocha .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--catppuccin-mocha .navbar-dropdown.is-right{left:auto;right:0}html.theme--catppuccin-mocha .navbar-divider{display:block}html.theme--catppuccin-mocha .navbar>.container .navbar-brand,html.theme--catppuccin-mocha .container>.navbar .navbar-brand{margin-left:-.75rem}html.theme--catppuccin-mocha .navbar>.container .navbar-menu,html.theme--catppuccin-mocha .container>.navbar .navbar-menu{margin-right:-.75rem}html.theme--catppuccin-mocha .navbar.is-fixed-bottom-desktop,html.theme--catppuccin-mocha .navbar.is-fixed-top-desktop{left:0;position:fixed;right:0;z-index:30}html.theme--catppuccin-mocha .navbar.is-fixed-bottom-desktop{bottom:0}html.theme--catppuccin-mocha .navbar.is-fixed-bottom-desktop.has-shadow{box-shadow:0 -2px 3px rgba(10,10,10,0.1)}html.theme--catppuccin-mocha .navbar.is-fixed-top-desktop{top:0}html.theme--catppuccin-mocha html.has-navbar-fixed-top-desktop,html.theme--catppuccin-mocha body.has-navbar-fixed-top-desktop{padding-top:4rem}html.theme--catppuccin-mocha html.has-navbar-fixed-bottom-desktop,html.theme--catppuccin-mocha body.has-navbar-fixed-bottom-desktop{padding-bottom:4rem}html.theme--catppuccin-mocha html.has-spaced-navbar-fixed-top,html.theme--catppuccin-mocha body.has-spaced-navbar-fixed-top{padding-top:6rem}html.theme--catppuccin-mocha html.has-spaced-navbar-fixed-bottom,html.theme--catppuccin-mocha body.has-spaced-navbar-fixed-bottom{padding-bottom:6rem}html.theme--catppuccin-mocha a.navbar-item.is-active,html.theme--catppuccin-mocha .navbar-link.is-active{color:#89b4fa}html.theme--catppuccin-mocha a.navbar-item.is-active:not(:focus):not(:hover),html.theme--catppuccin-mocha .navbar-link.is-active:not(:focus):not(:hover){background-color:rgba(0,0,0,0)}html.theme--catppuccin-mocha .navbar-item.has-dropdown:focus .navbar-link,html.theme--catppuccin-mocha .navbar-item.has-dropdown:hover .navbar-link,html.theme--catppuccin-mocha .navbar-item.has-dropdown.is-active .navbar-link{background-color:rgba(0,0,0,0)}}html.theme--catppuccin-mocha .hero.is-fullheight-with-navbar{min-height:calc(100vh - 4rem)}html.theme--catppuccin-mocha .pagination{font-size:1rem;margin:-.25rem}html.theme--catppuccin-mocha .pagination.is-small,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.pagination{font-size:.75rem}html.theme--catppuccin-mocha .pagination.is-medium{font-size:1.25rem}html.theme--catppuccin-mocha .pagination.is-large{font-size:1.5rem}html.theme--catppuccin-mocha .pagination.is-rounded .pagination-previous,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.pagination .pagination-previous,html.theme--catppuccin-mocha .pagination.is-rounded .pagination-next,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.pagination .pagination-next{padding-left:1em;padding-right:1em;border-radius:9999px}html.theme--catppuccin-mocha .pagination.is-rounded .pagination-link,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.pagination .pagination-link{border-radius:9999px}html.theme--catppuccin-mocha .pagination,html.theme--catppuccin-mocha .pagination-list{align-items:center;display:flex;justify-content:center;text-align:center}html.theme--catppuccin-mocha .pagination-previous,html.theme--catppuccin-mocha .pagination-next,html.theme--catppuccin-mocha .pagination-link,html.theme--catppuccin-mocha .pagination-ellipsis{font-size:1em;justify-content:center;margin:.25rem;padding-left:.5em;padding-right:.5em;text-align:center}html.theme--catppuccin-mocha .pagination-previous,html.theme--catppuccin-mocha .pagination-next,html.theme--catppuccin-mocha .pagination-link{border-color:#585b70;color:#89b4fa;min-width:2.5em}html.theme--catppuccin-mocha .pagination-previous:hover,html.theme--catppuccin-mocha .pagination-next:hover,html.theme--catppuccin-mocha .pagination-link:hover{border-color:#6c7086;color:#89dceb}html.theme--catppuccin-mocha .pagination-previous:focus,html.theme--catppuccin-mocha .pagination-next:focus,html.theme--catppuccin-mocha .pagination-link:focus{border-color:#6c7086}html.theme--catppuccin-mocha .pagination-previous:active,html.theme--catppuccin-mocha .pagination-next:active,html.theme--catppuccin-mocha .pagination-link:active{box-shadow:inset 0 1px 2px rgba(10,10,10,0.2)}html.theme--catppuccin-mocha .pagination-previous[disabled],html.theme--catppuccin-mocha .pagination-previous.is-disabled,html.theme--catppuccin-mocha .pagination-next[disabled],html.theme--catppuccin-mocha .pagination-next.is-disabled,html.theme--catppuccin-mocha .pagination-link[disabled],html.theme--catppuccin-mocha .pagination-link.is-disabled{background-color:#585b70;border-color:#585b70;box-shadow:none;color:#f7f8fd;opacity:0.5}html.theme--catppuccin-mocha .pagination-previous,html.theme--catppuccin-mocha .pagination-next{padding-left:.75em;padding-right:.75em;white-space:nowrap}html.theme--catppuccin-mocha .pagination-link.is-current{background-color:#89b4fa;border-color:#89b4fa;color:#fff}html.theme--catppuccin-mocha .pagination-ellipsis{color:#6c7086;pointer-events:none}html.theme--catppuccin-mocha .pagination-list{flex-wrap:wrap}html.theme--catppuccin-mocha .pagination-list li{list-style:none}@media screen and (max-width: 768px){html.theme--catppuccin-mocha .pagination{flex-wrap:wrap}html.theme--catppuccin-mocha .pagination-previous,html.theme--catppuccin-mocha .pagination-next{flex-grow:1;flex-shrink:1}html.theme--catppuccin-mocha .pagination-list li{flex-grow:1;flex-shrink:1}}@media screen and (min-width: 769px),print{html.theme--catppuccin-mocha .pagination-list{flex-grow:1;flex-shrink:1;justify-content:flex-start;order:1}html.theme--catppuccin-mocha .pagination-previous,html.theme--catppuccin-mocha .pagination-next,html.theme--catppuccin-mocha .pagination-link,html.theme--catppuccin-mocha .pagination-ellipsis{margin-bottom:0;margin-top:0}html.theme--catppuccin-mocha .pagination-previous{order:2}html.theme--catppuccin-mocha .pagination-next{order:3}html.theme--catppuccin-mocha .pagination{justify-content:space-between;margin-bottom:0;margin-top:0}html.theme--catppuccin-mocha .pagination.is-centered .pagination-previous{order:1}html.theme--catppuccin-mocha .pagination.is-centered .pagination-list{justify-content:center;order:2}html.theme--catppuccin-mocha .pagination.is-centered .pagination-next{order:3}html.theme--catppuccin-mocha .pagination.is-right .pagination-previous{order:1}html.theme--catppuccin-mocha .pagination.is-right .pagination-next{order:2}html.theme--catppuccin-mocha .pagination.is-right .pagination-list{justify-content:flex-end;order:3}}html.theme--catppuccin-mocha .panel{border-radius:8px;box-shadow:#171717;font-size:1rem}html.theme--catppuccin-mocha .panel:not(:last-child){margin-bottom:1.5rem}html.theme--catppuccin-mocha .panel.is-white .panel-heading{background-color:#fff;color:#0a0a0a}html.theme--catppuccin-mocha .panel.is-white .panel-tabs a.is-active{border-bottom-color:#fff}html.theme--catppuccin-mocha .panel.is-white .panel-block.is-active .panel-icon{color:#fff}html.theme--catppuccin-mocha .panel.is-black .panel-heading{background-color:#0a0a0a;color:#fff}html.theme--catppuccin-mocha .panel.is-black .panel-tabs a.is-active{border-bottom-color:#0a0a0a}html.theme--catppuccin-mocha .panel.is-black .panel-block.is-active .panel-icon{color:#0a0a0a}html.theme--catppuccin-mocha .panel.is-light .panel-heading{background-color:#f5f5f5;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .panel.is-light .panel-tabs a.is-active{border-bottom-color:#f5f5f5}html.theme--catppuccin-mocha .panel.is-light .panel-block.is-active .panel-icon{color:#f5f5f5}html.theme--catppuccin-mocha .panel.is-dark .panel-heading,html.theme--catppuccin-mocha .content kbd.panel .panel-heading{background-color:#313244;color:#fff}html.theme--catppuccin-mocha .panel.is-dark .panel-tabs a.is-active,html.theme--catppuccin-mocha .content kbd.panel .panel-tabs a.is-active{border-bottom-color:#313244}html.theme--catppuccin-mocha .panel.is-dark .panel-block.is-active .panel-icon,html.theme--catppuccin-mocha .content kbd.panel .panel-block.is-active .panel-icon{color:#313244}html.theme--catppuccin-mocha .panel.is-primary .panel-heading,html.theme--catppuccin-mocha .docstring>section>a.panel.docs-sourcelink .panel-heading{background-color:#89b4fa;color:#fff}html.theme--catppuccin-mocha .panel.is-primary .panel-tabs a.is-active,html.theme--catppuccin-mocha .docstring>section>a.panel.docs-sourcelink .panel-tabs a.is-active{border-bottom-color:#89b4fa}html.theme--catppuccin-mocha .panel.is-primary .panel-block.is-active .panel-icon,html.theme--catppuccin-mocha .docstring>section>a.panel.docs-sourcelink .panel-block.is-active .panel-icon{color:#89b4fa}html.theme--catppuccin-mocha .panel.is-link .panel-heading{background-color:#89b4fa;color:#fff}html.theme--catppuccin-mocha .panel.is-link .panel-tabs a.is-active{border-bottom-color:#89b4fa}html.theme--catppuccin-mocha .panel.is-link .panel-block.is-active .panel-icon{color:#89b4fa}html.theme--catppuccin-mocha .panel.is-info .panel-heading{background-color:#94e2d5;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .panel.is-info .panel-tabs a.is-active{border-bottom-color:#94e2d5}html.theme--catppuccin-mocha .panel.is-info .panel-block.is-active .panel-icon{color:#94e2d5}html.theme--catppuccin-mocha .panel.is-success .panel-heading{background-color:#a6e3a1;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .panel.is-success .panel-tabs a.is-active{border-bottom-color:#a6e3a1}html.theme--catppuccin-mocha .panel.is-success .panel-block.is-active .panel-icon{color:#a6e3a1}html.theme--catppuccin-mocha .panel.is-warning .panel-heading{background-color:#f9e2af;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .panel.is-warning .panel-tabs a.is-active{border-bottom-color:#f9e2af}html.theme--catppuccin-mocha .panel.is-warning .panel-block.is-active .panel-icon{color:#f9e2af}html.theme--catppuccin-mocha .panel.is-danger .panel-heading{background-color:#f38ba8;color:#fff}html.theme--catppuccin-mocha .panel.is-danger .panel-tabs a.is-active{border-bottom-color:#f38ba8}html.theme--catppuccin-mocha .panel.is-danger .panel-block.is-active .panel-icon{color:#f38ba8}html.theme--catppuccin-mocha .panel-tabs:not(:last-child),html.theme--catppuccin-mocha .panel-block:not(:last-child){border-bottom:1px solid #ededed}html.theme--catppuccin-mocha .panel-heading{background-color:#45475a;border-radius:8px 8px 0 0;color:#b8c5ef;font-size:1.25em;font-weight:700;line-height:1.25;padding:0.75em 1em}html.theme--catppuccin-mocha .panel-tabs{align-items:flex-end;display:flex;font-size:.875em;justify-content:center}html.theme--catppuccin-mocha .panel-tabs a{border-bottom:1px solid #585b70;margin-bottom:-1px;padding:0.5em}html.theme--catppuccin-mocha .panel-tabs a.is-active{border-bottom-color:#45475a;color:#71a4f9}html.theme--catppuccin-mocha .panel-list a{color:#cdd6f4}html.theme--catppuccin-mocha .panel-list a:hover{color:#89b4fa}html.theme--catppuccin-mocha .panel-block{align-items:center;color:#b8c5ef;display:flex;justify-content:flex-start;padding:0.5em 0.75em}html.theme--catppuccin-mocha .panel-block input[type="checkbox"]{margin-right:.75em}html.theme--catppuccin-mocha .panel-block>.control{flex-grow:1;flex-shrink:1;width:100%}html.theme--catppuccin-mocha .panel-block.is-wrapped{flex-wrap:wrap}html.theme--catppuccin-mocha .panel-block.is-active{border-left-color:#89b4fa;color:#71a4f9}html.theme--catppuccin-mocha .panel-block.is-active .panel-icon{color:#89b4fa}html.theme--catppuccin-mocha .panel-block:last-child{border-bottom-left-radius:8px;border-bottom-right-radius:8px}html.theme--catppuccin-mocha a.panel-block,html.theme--catppuccin-mocha label.panel-block{cursor:pointer}html.theme--catppuccin-mocha a.panel-block:hover,html.theme--catppuccin-mocha label.panel-block:hover{background-color:#181825}html.theme--catppuccin-mocha .panel-icon{display:inline-block;font-size:14px;height:1em;line-height:1em;text-align:center;vertical-align:top;width:1em;color:#f7f8fd;margin-right:.75em}html.theme--catppuccin-mocha .panel-icon .fa{font-size:inherit;line-height:inherit}html.theme--catppuccin-mocha .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}html.theme--catppuccin-mocha .tabs a{align-items:center;border-bottom-color:#585b70;border-bottom-style:solid;border-bottom-width:1px;color:#cdd6f4;display:flex;justify-content:center;margin-bottom:-1px;padding:0.5em 1em;vertical-align:top}html.theme--catppuccin-mocha .tabs a:hover{border-bottom-color:#b8c5ef;color:#b8c5ef}html.theme--catppuccin-mocha .tabs li{display:block}html.theme--catppuccin-mocha .tabs li.is-active a{border-bottom-color:#89b4fa;color:#89b4fa}html.theme--catppuccin-mocha .tabs ul{align-items:center;border-bottom-color:#585b70;border-bottom-style:solid;border-bottom-width:1px;display:flex;flex-grow:1;flex-shrink:0;justify-content:flex-start}html.theme--catppuccin-mocha .tabs ul.is-left{padding-right:0.75em}html.theme--catppuccin-mocha .tabs ul.is-center{flex:none;justify-content:center;padding-left:0.75em;padding-right:0.75em}html.theme--catppuccin-mocha .tabs ul.is-right{justify-content:flex-end;padding-left:0.75em}html.theme--catppuccin-mocha .tabs .icon:first-child{margin-right:.5em}html.theme--catppuccin-mocha .tabs .icon:last-child{margin-left:.5em}html.theme--catppuccin-mocha .tabs.is-centered ul{justify-content:center}html.theme--catppuccin-mocha .tabs.is-right ul{justify-content:flex-end}html.theme--catppuccin-mocha .tabs.is-boxed a{border:1px solid transparent;border-radius:.4em .4em 0 0}html.theme--catppuccin-mocha .tabs.is-boxed a:hover{background-color:#181825;border-bottom-color:#585b70}html.theme--catppuccin-mocha .tabs.is-boxed li.is-active a{background-color:#fff;border-color:#585b70;border-bottom-color:rgba(0,0,0,0) !important}html.theme--catppuccin-mocha .tabs.is-fullwidth li{flex-grow:1;flex-shrink:0}html.theme--catppuccin-mocha .tabs.is-toggle a{border-color:#585b70;border-style:solid;border-width:1px;margin-bottom:0;position:relative}html.theme--catppuccin-mocha .tabs.is-toggle a:hover{background-color:#181825;border-color:#6c7086;z-index:2}html.theme--catppuccin-mocha .tabs.is-toggle li+li{margin-left:-1px}html.theme--catppuccin-mocha .tabs.is-toggle li:first-child a{border-top-left-radius:.4em;border-bottom-left-radius:.4em}html.theme--catppuccin-mocha .tabs.is-toggle li:last-child a{border-top-right-radius:.4em;border-bottom-right-radius:.4em}html.theme--catppuccin-mocha .tabs.is-toggle li.is-active a{background-color:#89b4fa;border-color:#89b4fa;color:#fff;z-index:1}html.theme--catppuccin-mocha .tabs.is-toggle ul{border-bottom:none}html.theme--catppuccin-mocha .tabs.is-toggle.is-toggle-rounded li:first-child a{border-bottom-left-radius:9999px;border-top-left-radius:9999px;padding-left:1.25em}html.theme--catppuccin-mocha .tabs.is-toggle.is-toggle-rounded li:last-child a{border-bottom-right-radius:9999px;border-top-right-radius:9999px;padding-right:1.25em}html.theme--catppuccin-mocha .tabs.is-small,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.tabs{font-size:.75rem}html.theme--catppuccin-mocha .tabs.is-medium{font-size:1.25rem}html.theme--catppuccin-mocha .tabs.is-large{font-size:1.5rem}html.theme--catppuccin-mocha .column{display:block;flex-basis:0;flex-grow:1;flex-shrink:1;padding:.75rem}.columns.is-mobile>html.theme--catppuccin-mocha .column.is-narrow{flex:none;width:unset}.columns.is-mobile>html.theme--catppuccin-mocha .column.is-full{flex:none;width:100%}.columns.is-mobile>html.theme--catppuccin-mocha .column.is-three-quarters{flex:none;width:75%}.columns.is-mobile>html.theme--catppuccin-mocha .column.is-two-thirds{flex:none;width:66.6666%}.columns.is-mobile>html.theme--catppuccin-mocha .column.is-half{flex:none;width:50%}.columns.is-mobile>html.theme--catppuccin-mocha .column.is-one-third{flex:none;width:33.3333%}.columns.is-mobile>html.theme--catppuccin-mocha .column.is-one-quarter{flex:none;width:25%}.columns.is-mobile>html.theme--catppuccin-mocha .column.is-one-fifth{flex:none;width:20%}.columns.is-mobile>html.theme--catppuccin-mocha .column.is-two-fifths{flex:none;width:40%}.columns.is-mobile>html.theme--catppuccin-mocha .column.is-three-fifths{flex:none;width:60%}.columns.is-mobile>html.theme--catppuccin-mocha .column.is-four-fifths{flex:none;width:80%}.columns.is-mobile>html.theme--catppuccin-mocha .column.is-offset-three-quarters{margin-left:75%}.columns.is-mobile>html.theme--catppuccin-mocha .column.is-offset-two-thirds{margin-left:66.6666%}.columns.is-mobile>html.theme--catppuccin-mocha .column.is-offset-half{margin-left:50%}.columns.is-mobile>html.theme--catppuccin-mocha .column.is-offset-one-third{margin-left:33.3333%}.columns.is-mobile>html.theme--catppuccin-mocha .column.is-offset-one-quarter{margin-left:25%}.columns.is-mobile>html.theme--catppuccin-mocha .column.is-offset-one-fifth{margin-left:20%}.columns.is-mobile>html.theme--catppuccin-mocha .column.is-offset-two-fifths{margin-left:40%}.columns.is-mobile>html.theme--catppuccin-mocha .column.is-offset-three-fifths{margin-left:60%}.columns.is-mobile>html.theme--catppuccin-mocha .column.is-offset-four-fifths{margin-left:80%}.columns.is-mobile>html.theme--catppuccin-mocha .column.is-0{flex:none;width:0%}.columns.is-mobile>html.theme--catppuccin-mocha .column.is-offset-0{margin-left:0%}.columns.is-mobile>html.theme--catppuccin-mocha .column.is-1{flex:none;width:8.33333337%}.columns.is-mobile>html.theme--catppuccin-mocha .column.is-offset-1{margin-left:8.33333337%}.columns.is-mobile>html.theme--catppuccin-mocha .column.is-2{flex:none;width:16.66666674%}.columns.is-mobile>html.theme--catppuccin-mocha .column.is-offset-2{margin-left:16.66666674%}.columns.is-mobile>html.theme--catppuccin-mocha .column.is-3{flex:none;width:25%}.columns.is-mobile>html.theme--catppuccin-mocha .column.is-offset-3{margin-left:25%}.columns.is-mobile>html.theme--catppuccin-mocha .column.is-4{flex:none;width:33.33333337%}.columns.is-mobile>html.theme--catppuccin-mocha .column.is-offset-4{margin-left:33.33333337%}.columns.is-mobile>html.theme--catppuccin-mocha .column.is-5{flex:none;width:41.66666674%}.columns.is-mobile>html.theme--catppuccin-mocha .column.is-offset-5{margin-left:41.66666674%}.columns.is-mobile>html.theme--catppuccin-mocha .column.is-6{flex:none;width:50%}.columns.is-mobile>html.theme--catppuccin-mocha .column.is-offset-6{margin-left:50%}.columns.is-mobile>html.theme--catppuccin-mocha .column.is-7{flex:none;width:58.33333337%}.columns.is-mobile>html.theme--catppuccin-mocha .column.is-offset-7{margin-left:58.33333337%}.columns.is-mobile>html.theme--catppuccin-mocha .column.is-8{flex:none;width:66.66666674%}.columns.is-mobile>html.theme--catppuccin-mocha .column.is-offset-8{margin-left:66.66666674%}.columns.is-mobile>html.theme--catppuccin-mocha .column.is-9{flex:none;width:75%}.columns.is-mobile>html.theme--catppuccin-mocha .column.is-offset-9{margin-left:75%}.columns.is-mobile>html.theme--catppuccin-mocha .column.is-10{flex:none;width:83.33333337%}.columns.is-mobile>html.theme--catppuccin-mocha .column.is-offset-10{margin-left:83.33333337%}.columns.is-mobile>html.theme--catppuccin-mocha .column.is-11{flex:none;width:91.66666674%}.columns.is-mobile>html.theme--catppuccin-mocha .column.is-offset-11{margin-left:91.66666674%}.columns.is-mobile>html.theme--catppuccin-mocha .column.is-12{flex:none;width:100%}.columns.is-mobile>html.theme--catppuccin-mocha .column.is-offset-12{margin-left:100%}@media screen and (max-width: 768px){html.theme--catppuccin-mocha .column.is-narrow-mobile{flex:none;width:unset}html.theme--catppuccin-mocha .column.is-full-mobile{flex:none;width:100%}html.theme--catppuccin-mocha .column.is-three-quarters-mobile{flex:none;width:75%}html.theme--catppuccin-mocha .column.is-two-thirds-mobile{flex:none;width:66.6666%}html.theme--catppuccin-mocha .column.is-half-mobile{flex:none;width:50%}html.theme--catppuccin-mocha .column.is-one-third-mobile{flex:none;width:33.3333%}html.theme--catppuccin-mocha .column.is-one-quarter-mobile{flex:none;width:25%}html.theme--catppuccin-mocha .column.is-one-fifth-mobile{flex:none;width:20%}html.theme--catppuccin-mocha .column.is-two-fifths-mobile{flex:none;width:40%}html.theme--catppuccin-mocha .column.is-three-fifths-mobile{flex:none;width:60%}html.theme--catppuccin-mocha .column.is-four-fifths-mobile{flex:none;width:80%}html.theme--catppuccin-mocha .column.is-offset-three-quarters-mobile{margin-left:75%}html.theme--catppuccin-mocha .column.is-offset-two-thirds-mobile{margin-left:66.6666%}html.theme--catppuccin-mocha .column.is-offset-half-mobile{margin-left:50%}html.theme--catppuccin-mocha .column.is-offset-one-third-mobile{margin-left:33.3333%}html.theme--catppuccin-mocha .column.is-offset-one-quarter-mobile{margin-left:25%}html.theme--catppuccin-mocha .column.is-offset-one-fifth-mobile{margin-left:20%}html.theme--catppuccin-mocha .column.is-offset-two-fifths-mobile{margin-left:40%}html.theme--catppuccin-mocha .column.is-offset-three-fifths-mobile{margin-left:60%}html.theme--catppuccin-mocha .column.is-offset-four-fifths-mobile{margin-left:80%}html.theme--catppuccin-mocha .column.is-0-mobile{flex:none;width:0%}html.theme--catppuccin-mocha .column.is-offset-0-mobile{margin-left:0%}html.theme--catppuccin-mocha .column.is-1-mobile{flex:none;width:8.33333337%}html.theme--catppuccin-mocha .column.is-offset-1-mobile{margin-left:8.33333337%}html.theme--catppuccin-mocha .column.is-2-mobile{flex:none;width:16.66666674%}html.theme--catppuccin-mocha .column.is-offset-2-mobile{margin-left:16.66666674%}html.theme--catppuccin-mocha .column.is-3-mobile{flex:none;width:25%}html.theme--catppuccin-mocha .column.is-offset-3-mobile{margin-left:25%}html.theme--catppuccin-mocha .column.is-4-mobile{flex:none;width:33.33333337%}html.theme--catppuccin-mocha .column.is-offset-4-mobile{margin-left:33.33333337%}html.theme--catppuccin-mocha .column.is-5-mobile{flex:none;width:41.66666674%}html.theme--catppuccin-mocha .column.is-offset-5-mobile{margin-left:41.66666674%}html.theme--catppuccin-mocha .column.is-6-mobile{flex:none;width:50%}html.theme--catppuccin-mocha .column.is-offset-6-mobile{margin-left:50%}html.theme--catppuccin-mocha .column.is-7-mobile{flex:none;width:58.33333337%}html.theme--catppuccin-mocha .column.is-offset-7-mobile{margin-left:58.33333337%}html.theme--catppuccin-mocha .column.is-8-mobile{flex:none;width:66.66666674%}html.theme--catppuccin-mocha .column.is-offset-8-mobile{margin-left:66.66666674%}html.theme--catppuccin-mocha .column.is-9-mobile{flex:none;width:75%}html.theme--catppuccin-mocha .column.is-offset-9-mobile{margin-left:75%}html.theme--catppuccin-mocha .column.is-10-mobile{flex:none;width:83.33333337%}html.theme--catppuccin-mocha .column.is-offset-10-mobile{margin-left:83.33333337%}html.theme--catppuccin-mocha .column.is-11-mobile{flex:none;width:91.66666674%}html.theme--catppuccin-mocha .column.is-offset-11-mobile{margin-left:91.66666674%}html.theme--catppuccin-mocha .column.is-12-mobile{flex:none;width:100%}html.theme--catppuccin-mocha .column.is-offset-12-mobile{margin-left:100%}}@media screen and (min-width: 769px),print{html.theme--catppuccin-mocha .column.is-narrow,html.theme--catppuccin-mocha .column.is-narrow-tablet{flex:none;width:unset}html.theme--catppuccin-mocha .column.is-full,html.theme--catppuccin-mocha .column.is-full-tablet{flex:none;width:100%}html.theme--catppuccin-mocha .column.is-three-quarters,html.theme--catppuccin-mocha .column.is-three-quarters-tablet{flex:none;width:75%}html.theme--catppuccin-mocha .column.is-two-thirds,html.theme--catppuccin-mocha .column.is-two-thirds-tablet{flex:none;width:66.6666%}html.theme--catppuccin-mocha .column.is-half,html.theme--catppuccin-mocha .column.is-half-tablet{flex:none;width:50%}html.theme--catppuccin-mocha .column.is-one-third,html.theme--catppuccin-mocha .column.is-one-third-tablet{flex:none;width:33.3333%}html.theme--catppuccin-mocha .column.is-one-quarter,html.theme--catppuccin-mocha .column.is-one-quarter-tablet{flex:none;width:25%}html.theme--catppuccin-mocha .column.is-one-fifth,html.theme--catppuccin-mocha .column.is-one-fifth-tablet{flex:none;width:20%}html.theme--catppuccin-mocha .column.is-two-fifths,html.theme--catppuccin-mocha .column.is-two-fifths-tablet{flex:none;width:40%}html.theme--catppuccin-mocha .column.is-three-fifths,html.theme--catppuccin-mocha .column.is-three-fifths-tablet{flex:none;width:60%}html.theme--catppuccin-mocha .column.is-four-fifths,html.theme--catppuccin-mocha .column.is-four-fifths-tablet{flex:none;width:80%}html.theme--catppuccin-mocha .column.is-offset-three-quarters,html.theme--catppuccin-mocha .column.is-offset-three-quarters-tablet{margin-left:75%}html.theme--catppuccin-mocha .column.is-offset-two-thirds,html.theme--catppuccin-mocha .column.is-offset-two-thirds-tablet{margin-left:66.6666%}html.theme--catppuccin-mocha .column.is-offset-half,html.theme--catppuccin-mocha .column.is-offset-half-tablet{margin-left:50%}html.theme--catppuccin-mocha .column.is-offset-one-third,html.theme--catppuccin-mocha .column.is-offset-one-third-tablet{margin-left:33.3333%}html.theme--catppuccin-mocha .column.is-offset-one-quarter,html.theme--catppuccin-mocha .column.is-offset-one-quarter-tablet{margin-left:25%}html.theme--catppuccin-mocha .column.is-offset-one-fifth,html.theme--catppuccin-mocha .column.is-offset-one-fifth-tablet{margin-left:20%}html.theme--catppuccin-mocha .column.is-offset-two-fifths,html.theme--catppuccin-mocha .column.is-offset-two-fifths-tablet{margin-left:40%}html.theme--catppuccin-mocha .column.is-offset-three-fifths,html.theme--catppuccin-mocha .column.is-offset-three-fifths-tablet{margin-left:60%}html.theme--catppuccin-mocha .column.is-offset-four-fifths,html.theme--catppuccin-mocha .column.is-offset-four-fifths-tablet{margin-left:80%}html.theme--catppuccin-mocha .column.is-0,html.theme--catppuccin-mocha .column.is-0-tablet{flex:none;width:0%}html.theme--catppuccin-mocha .column.is-offset-0,html.theme--catppuccin-mocha .column.is-offset-0-tablet{margin-left:0%}html.theme--catppuccin-mocha .column.is-1,html.theme--catppuccin-mocha .column.is-1-tablet{flex:none;width:8.33333337%}html.theme--catppuccin-mocha .column.is-offset-1,html.theme--catppuccin-mocha .column.is-offset-1-tablet{margin-left:8.33333337%}html.theme--catppuccin-mocha .column.is-2,html.theme--catppuccin-mocha .column.is-2-tablet{flex:none;width:16.66666674%}html.theme--catppuccin-mocha .column.is-offset-2,html.theme--catppuccin-mocha .column.is-offset-2-tablet{margin-left:16.66666674%}html.theme--catppuccin-mocha .column.is-3,html.theme--catppuccin-mocha .column.is-3-tablet{flex:none;width:25%}html.theme--catppuccin-mocha .column.is-offset-3,html.theme--catppuccin-mocha .column.is-offset-3-tablet{margin-left:25%}html.theme--catppuccin-mocha .column.is-4,html.theme--catppuccin-mocha .column.is-4-tablet{flex:none;width:33.33333337%}html.theme--catppuccin-mocha .column.is-offset-4,html.theme--catppuccin-mocha .column.is-offset-4-tablet{margin-left:33.33333337%}html.theme--catppuccin-mocha .column.is-5,html.theme--catppuccin-mocha .column.is-5-tablet{flex:none;width:41.66666674%}html.theme--catppuccin-mocha .column.is-offset-5,html.theme--catppuccin-mocha .column.is-offset-5-tablet{margin-left:41.66666674%}html.theme--catppuccin-mocha .column.is-6,html.theme--catppuccin-mocha .column.is-6-tablet{flex:none;width:50%}html.theme--catppuccin-mocha .column.is-offset-6,html.theme--catppuccin-mocha .column.is-offset-6-tablet{margin-left:50%}html.theme--catppuccin-mocha .column.is-7,html.theme--catppuccin-mocha .column.is-7-tablet{flex:none;width:58.33333337%}html.theme--catppuccin-mocha .column.is-offset-7,html.theme--catppuccin-mocha .column.is-offset-7-tablet{margin-left:58.33333337%}html.theme--catppuccin-mocha .column.is-8,html.theme--catppuccin-mocha .column.is-8-tablet{flex:none;width:66.66666674%}html.theme--catppuccin-mocha .column.is-offset-8,html.theme--catppuccin-mocha .column.is-offset-8-tablet{margin-left:66.66666674%}html.theme--catppuccin-mocha .column.is-9,html.theme--catppuccin-mocha .column.is-9-tablet{flex:none;width:75%}html.theme--catppuccin-mocha .column.is-offset-9,html.theme--catppuccin-mocha .column.is-offset-9-tablet{margin-left:75%}html.theme--catppuccin-mocha .column.is-10,html.theme--catppuccin-mocha .column.is-10-tablet{flex:none;width:83.33333337%}html.theme--catppuccin-mocha .column.is-offset-10,html.theme--catppuccin-mocha .column.is-offset-10-tablet{margin-left:83.33333337%}html.theme--catppuccin-mocha .column.is-11,html.theme--catppuccin-mocha .column.is-11-tablet{flex:none;width:91.66666674%}html.theme--catppuccin-mocha .column.is-offset-11,html.theme--catppuccin-mocha .column.is-offset-11-tablet{margin-left:91.66666674%}html.theme--catppuccin-mocha .column.is-12,html.theme--catppuccin-mocha .column.is-12-tablet{flex:none;width:100%}html.theme--catppuccin-mocha .column.is-offset-12,html.theme--catppuccin-mocha .column.is-offset-12-tablet{margin-left:100%}}@media screen and (max-width: 1055px){html.theme--catppuccin-mocha .column.is-narrow-touch{flex:none;width:unset}html.theme--catppuccin-mocha .column.is-full-touch{flex:none;width:100%}html.theme--catppuccin-mocha .column.is-three-quarters-touch{flex:none;width:75%}html.theme--catppuccin-mocha .column.is-two-thirds-touch{flex:none;width:66.6666%}html.theme--catppuccin-mocha .column.is-half-touch{flex:none;width:50%}html.theme--catppuccin-mocha .column.is-one-third-touch{flex:none;width:33.3333%}html.theme--catppuccin-mocha .column.is-one-quarter-touch{flex:none;width:25%}html.theme--catppuccin-mocha .column.is-one-fifth-touch{flex:none;width:20%}html.theme--catppuccin-mocha .column.is-two-fifths-touch{flex:none;width:40%}html.theme--catppuccin-mocha .column.is-three-fifths-touch{flex:none;width:60%}html.theme--catppuccin-mocha .column.is-four-fifths-touch{flex:none;width:80%}html.theme--catppuccin-mocha .column.is-offset-three-quarters-touch{margin-left:75%}html.theme--catppuccin-mocha .column.is-offset-two-thirds-touch{margin-left:66.6666%}html.theme--catppuccin-mocha .column.is-offset-half-touch{margin-left:50%}html.theme--catppuccin-mocha .column.is-offset-one-third-touch{margin-left:33.3333%}html.theme--catppuccin-mocha .column.is-offset-one-quarter-touch{margin-left:25%}html.theme--catppuccin-mocha .column.is-offset-one-fifth-touch{margin-left:20%}html.theme--catppuccin-mocha .column.is-offset-two-fifths-touch{margin-left:40%}html.theme--catppuccin-mocha .column.is-offset-three-fifths-touch{margin-left:60%}html.theme--catppuccin-mocha .column.is-offset-four-fifths-touch{margin-left:80%}html.theme--catppuccin-mocha .column.is-0-touch{flex:none;width:0%}html.theme--catppuccin-mocha .column.is-offset-0-touch{margin-left:0%}html.theme--catppuccin-mocha .column.is-1-touch{flex:none;width:8.33333337%}html.theme--catppuccin-mocha .column.is-offset-1-touch{margin-left:8.33333337%}html.theme--catppuccin-mocha .column.is-2-touch{flex:none;width:16.66666674%}html.theme--catppuccin-mocha .column.is-offset-2-touch{margin-left:16.66666674%}html.theme--catppuccin-mocha .column.is-3-touch{flex:none;width:25%}html.theme--catppuccin-mocha .column.is-offset-3-touch{margin-left:25%}html.theme--catppuccin-mocha .column.is-4-touch{flex:none;width:33.33333337%}html.theme--catppuccin-mocha .column.is-offset-4-touch{margin-left:33.33333337%}html.theme--catppuccin-mocha .column.is-5-touch{flex:none;width:41.66666674%}html.theme--catppuccin-mocha .column.is-offset-5-touch{margin-left:41.66666674%}html.theme--catppuccin-mocha .column.is-6-touch{flex:none;width:50%}html.theme--catppuccin-mocha .column.is-offset-6-touch{margin-left:50%}html.theme--catppuccin-mocha .column.is-7-touch{flex:none;width:58.33333337%}html.theme--catppuccin-mocha .column.is-offset-7-touch{margin-left:58.33333337%}html.theme--catppuccin-mocha .column.is-8-touch{flex:none;width:66.66666674%}html.theme--catppuccin-mocha .column.is-offset-8-touch{margin-left:66.66666674%}html.theme--catppuccin-mocha .column.is-9-touch{flex:none;width:75%}html.theme--catppuccin-mocha .column.is-offset-9-touch{margin-left:75%}html.theme--catppuccin-mocha .column.is-10-touch{flex:none;width:83.33333337%}html.theme--catppuccin-mocha .column.is-offset-10-touch{margin-left:83.33333337%}html.theme--catppuccin-mocha .column.is-11-touch{flex:none;width:91.66666674%}html.theme--catppuccin-mocha .column.is-offset-11-touch{margin-left:91.66666674%}html.theme--catppuccin-mocha .column.is-12-touch{flex:none;width:100%}html.theme--catppuccin-mocha .column.is-offset-12-touch{margin-left:100%}}@media screen and (min-width: 1056px){html.theme--catppuccin-mocha .column.is-narrow-desktop{flex:none;width:unset}html.theme--catppuccin-mocha .column.is-full-desktop{flex:none;width:100%}html.theme--catppuccin-mocha .column.is-three-quarters-desktop{flex:none;width:75%}html.theme--catppuccin-mocha .column.is-two-thirds-desktop{flex:none;width:66.6666%}html.theme--catppuccin-mocha .column.is-half-desktop{flex:none;width:50%}html.theme--catppuccin-mocha .column.is-one-third-desktop{flex:none;width:33.3333%}html.theme--catppuccin-mocha .column.is-one-quarter-desktop{flex:none;width:25%}html.theme--catppuccin-mocha .column.is-one-fifth-desktop{flex:none;width:20%}html.theme--catppuccin-mocha .column.is-two-fifths-desktop{flex:none;width:40%}html.theme--catppuccin-mocha .column.is-three-fifths-desktop{flex:none;width:60%}html.theme--catppuccin-mocha .column.is-four-fifths-desktop{flex:none;width:80%}html.theme--catppuccin-mocha .column.is-offset-three-quarters-desktop{margin-left:75%}html.theme--catppuccin-mocha .column.is-offset-two-thirds-desktop{margin-left:66.6666%}html.theme--catppuccin-mocha .column.is-offset-half-desktop{margin-left:50%}html.theme--catppuccin-mocha .column.is-offset-one-third-desktop{margin-left:33.3333%}html.theme--catppuccin-mocha .column.is-offset-one-quarter-desktop{margin-left:25%}html.theme--catppuccin-mocha .column.is-offset-one-fifth-desktop{margin-left:20%}html.theme--catppuccin-mocha .column.is-offset-two-fifths-desktop{margin-left:40%}html.theme--catppuccin-mocha .column.is-offset-three-fifths-desktop{margin-left:60%}html.theme--catppuccin-mocha .column.is-offset-four-fifths-desktop{margin-left:80%}html.theme--catppuccin-mocha .column.is-0-desktop{flex:none;width:0%}html.theme--catppuccin-mocha .column.is-offset-0-desktop{margin-left:0%}html.theme--catppuccin-mocha .column.is-1-desktop{flex:none;width:8.33333337%}html.theme--catppuccin-mocha .column.is-offset-1-desktop{margin-left:8.33333337%}html.theme--catppuccin-mocha .column.is-2-desktop{flex:none;width:16.66666674%}html.theme--catppuccin-mocha .column.is-offset-2-desktop{margin-left:16.66666674%}html.theme--catppuccin-mocha .column.is-3-desktop{flex:none;width:25%}html.theme--catppuccin-mocha .column.is-offset-3-desktop{margin-left:25%}html.theme--catppuccin-mocha .column.is-4-desktop{flex:none;width:33.33333337%}html.theme--catppuccin-mocha .column.is-offset-4-desktop{margin-left:33.33333337%}html.theme--catppuccin-mocha .column.is-5-desktop{flex:none;width:41.66666674%}html.theme--catppuccin-mocha .column.is-offset-5-desktop{margin-left:41.66666674%}html.theme--catppuccin-mocha .column.is-6-desktop{flex:none;width:50%}html.theme--catppuccin-mocha .column.is-offset-6-desktop{margin-left:50%}html.theme--catppuccin-mocha .column.is-7-desktop{flex:none;width:58.33333337%}html.theme--catppuccin-mocha .column.is-offset-7-desktop{margin-left:58.33333337%}html.theme--catppuccin-mocha .column.is-8-desktop{flex:none;width:66.66666674%}html.theme--catppuccin-mocha .column.is-offset-8-desktop{margin-left:66.66666674%}html.theme--catppuccin-mocha .column.is-9-desktop{flex:none;width:75%}html.theme--catppuccin-mocha .column.is-offset-9-desktop{margin-left:75%}html.theme--catppuccin-mocha .column.is-10-desktop{flex:none;width:83.33333337%}html.theme--catppuccin-mocha .column.is-offset-10-desktop{margin-left:83.33333337%}html.theme--catppuccin-mocha .column.is-11-desktop{flex:none;width:91.66666674%}html.theme--catppuccin-mocha .column.is-offset-11-desktop{margin-left:91.66666674%}html.theme--catppuccin-mocha .column.is-12-desktop{flex:none;width:100%}html.theme--catppuccin-mocha .column.is-offset-12-desktop{margin-left:100%}}@media screen and (min-width: 1216px){html.theme--catppuccin-mocha .column.is-narrow-widescreen{flex:none;width:unset}html.theme--catppuccin-mocha .column.is-full-widescreen{flex:none;width:100%}html.theme--catppuccin-mocha .column.is-three-quarters-widescreen{flex:none;width:75%}html.theme--catppuccin-mocha .column.is-two-thirds-widescreen{flex:none;width:66.6666%}html.theme--catppuccin-mocha .column.is-half-widescreen{flex:none;width:50%}html.theme--catppuccin-mocha .column.is-one-third-widescreen{flex:none;width:33.3333%}html.theme--catppuccin-mocha .column.is-one-quarter-widescreen{flex:none;width:25%}html.theme--catppuccin-mocha .column.is-one-fifth-widescreen{flex:none;width:20%}html.theme--catppuccin-mocha .column.is-two-fifths-widescreen{flex:none;width:40%}html.theme--catppuccin-mocha .column.is-three-fifths-widescreen{flex:none;width:60%}html.theme--catppuccin-mocha .column.is-four-fifths-widescreen{flex:none;width:80%}html.theme--catppuccin-mocha .column.is-offset-three-quarters-widescreen{margin-left:75%}html.theme--catppuccin-mocha .column.is-offset-two-thirds-widescreen{margin-left:66.6666%}html.theme--catppuccin-mocha .column.is-offset-half-widescreen{margin-left:50%}html.theme--catppuccin-mocha .column.is-offset-one-third-widescreen{margin-left:33.3333%}html.theme--catppuccin-mocha .column.is-offset-one-quarter-widescreen{margin-left:25%}html.theme--catppuccin-mocha .column.is-offset-one-fifth-widescreen{margin-left:20%}html.theme--catppuccin-mocha .column.is-offset-two-fifths-widescreen{margin-left:40%}html.theme--catppuccin-mocha .column.is-offset-three-fifths-widescreen{margin-left:60%}html.theme--catppuccin-mocha .column.is-offset-four-fifths-widescreen{margin-left:80%}html.theme--catppuccin-mocha .column.is-0-widescreen{flex:none;width:0%}html.theme--catppuccin-mocha .column.is-offset-0-widescreen{margin-left:0%}html.theme--catppuccin-mocha .column.is-1-widescreen{flex:none;width:8.33333337%}html.theme--catppuccin-mocha .column.is-offset-1-widescreen{margin-left:8.33333337%}html.theme--catppuccin-mocha .column.is-2-widescreen{flex:none;width:16.66666674%}html.theme--catppuccin-mocha .column.is-offset-2-widescreen{margin-left:16.66666674%}html.theme--catppuccin-mocha .column.is-3-widescreen{flex:none;width:25%}html.theme--catppuccin-mocha .column.is-offset-3-widescreen{margin-left:25%}html.theme--catppuccin-mocha .column.is-4-widescreen{flex:none;width:33.33333337%}html.theme--catppuccin-mocha .column.is-offset-4-widescreen{margin-left:33.33333337%}html.theme--catppuccin-mocha .column.is-5-widescreen{flex:none;width:41.66666674%}html.theme--catppuccin-mocha .column.is-offset-5-widescreen{margin-left:41.66666674%}html.theme--catppuccin-mocha .column.is-6-widescreen{flex:none;width:50%}html.theme--catppuccin-mocha .column.is-offset-6-widescreen{margin-left:50%}html.theme--catppuccin-mocha .column.is-7-widescreen{flex:none;width:58.33333337%}html.theme--catppuccin-mocha .column.is-offset-7-widescreen{margin-left:58.33333337%}html.theme--catppuccin-mocha .column.is-8-widescreen{flex:none;width:66.66666674%}html.theme--catppuccin-mocha .column.is-offset-8-widescreen{margin-left:66.66666674%}html.theme--catppuccin-mocha .column.is-9-widescreen{flex:none;width:75%}html.theme--catppuccin-mocha .column.is-offset-9-widescreen{margin-left:75%}html.theme--catppuccin-mocha .column.is-10-widescreen{flex:none;width:83.33333337%}html.theme--catppuccin-mocha .column.is-offset-10-widescreen{margin-left:83.33333337%}html.theme--catppuccin-mocha .column.is-11-widescreen{flex:none;width:91.66666674%}html.theme--catppuccin-mocha .column.is-offset-11-widescreen{margin-left:91.66666674%}html.theme--catppuccin-mocha .column.is-12-widescreen{flex:none;width:100%}html.theme--catppuccin-mocha .column.is-offset-12-widescreen{margin-left:100%}}@media screen and (min-width: 1408px){html.theme--catppuccin-mocha .column.is-narrow-fullhd{flex:none;width:unset}html.theme--catppuccin-mocha .column.is-full-fullhd{flex:none;width:100%}html.theme--catppuccin-mocha .column.is-three-quarters-fullhd{flex:none;width:75%}html.theme--catppuccin-mocha .column.is-two-thirds-fullhd{flex:none;width:66.6666%}html.theme--catppuccin-mocha .column.is-half-fullhd{flex:none;width:50%}html.theme--catppuccin-mocha .column.is-one-third-fullhd{flex:none;width:33.3333%}html.theme--catppuccin-mocha .column.is-one-quarter-fullhd{flex:none;width:25%}html.theme--catppuccin-mocha .column.is-one-fifth-fullhd{flex:none;width:20%}html.theme--catppuccin-mocha .column.is-two-fifths-fullhd{flex:none;width:40%}html.theme--catppuccin-mocha .column.is-three-fifths-fullhd{flex:none;width:60%}html.theme--catppuccin-mocha .column.is-four-fifths-fullhd{flex:none;width:80%}html.theme--catppuccin-mocha .column.is-offset-three-quarters-fullhd{margin-left:75%}html.theme--catppuccin-mocha .column.is-offset-two-thirds-fullhd{margin-left:66.6666%}html.theme--catppuccin-mocha .column.is-offset-half-fullhd{margin-left:50%}html.theme--catppuccin-mocha .column.is-offset-one-third-fullhd{margin-left:33.3333%}html.theme--catppuccin-mocha .column.is-offset-one-quarter-fullhd{margin-left:25%}html.theme--catppuccin-mocha .column.is-offset-one-fifth-fullhd{margin-left:20%}html.theme--catppuccin-mocha .column.is-offset-two-fifths-fullhd{margin-left:40%}html.theme--catppuccin-mocha .column.is-offset-three-fifths-fullhd{margin-left:60%}html.theme--catppuccin-mocha .column.is-offset-four-fifths-fullhd{margin-left:80%}html.theme--catppuccin-mocha .column.is-0-fullhd{flex:none;width:0%}html.theme--catppuccin-mocha .column.is-offset-0-fullhd{margin-left:0%}html.theme--catppuccin-mocha .column.is-1-fullhd{flex:none;width:8.33333337%}html.theme--catppuccin-mocha .column.is-offset-1-fullhd{margin-left:8.33333337%}html.theme--catppuccin-mocha .column.is-2-fullhd{flex:none;width:16.66666674%}html.theme--catppuccin-mocha .column.is-offset-2-fullhd{margin-left:16.66666674%}html.theme--catppuccin-mocha .column.is-3-fullhd{flex:none;width:25%}html.theme--catppuccin-mocha .column.is-offset-3-fullhd{margin-left:25%}html.theme--catppuccin-mocha .column.is-4-fullhd{flex:none;width:33.33333337%}html.theme--catppuccin-mocha .column.is-offset-4-fullhd{margin-left:33.33333337%}html.theme--catppuccin-mocha .column.is-5-fullhd{flex:none;width:41.66666674%}html.theme--catppuccin-mocha .column.is-offset-5-fullhd{margin-left:41.66666674%}html.theme--catppuccin-mocha .column.is-6-fullhd{flex:none;width:50%}html.theme--catppuccin-mocha .column.is-offset-6-fullhd{margin-left:50%}html.theme--catppuccin-mocha .column.is-7-fullhd{flex:none;width:58.33333337%}html.theme--catppuccin-mocha .column.is-offset-7-fullhd{margin-left:58.33333337%}html.theme--catppuccin-mocha .column.is-8-fullhd{flex:none;width:66.66666674%}html.theme--catppuccin-mocha .column.is-offset-8-fullhd{margin-left:66.66666674%}html.theme--catppuccin-mocha .column.is-9-fullhd{flex:none;width:75%}html.theme--catppuccin-mocha .column.is-offset-9-fullhd{margin-left:75%}html.theme--catppuccin-mocha .column.is-10-fullhd{flex:none;width:83.33333337%}html.theme--catppuccin-mocha .column.is-offset-10-fullhd{margin-left:83.33333337%}html.theme--catppuccin-mocha .column.is-11-fullhd{flex:none;width:91.66666674%}html.theme--catppuccin-mocha .column.is-offset-11-fullhd{margin-left:91.66666674%}html.theme--catppuccin-mocha .column.is-12-fullhd{flex:none;width:100%}html.theme--catppuccin-mocha .column.is-offset-12-fullhd{margin-left:100%}}html.theme--catppuccin-mocha .columns{margin-left:-.75rem;margin-right:-.75rem;margin-top:-.75rem}html.theme--catppuccin-mocha .columns:last-child{margin-bottom:-.75rem}html.theme--catppuccin-mocha .columns:not(:last-child){margin-bottom:calc(1.5rem - .75rem)}html.theme--catppuccin-mocha .columns.is-centered{justify-content:center}html.theme--catppuccin-mocha .columns.is-gapless{margin-left:0;margin-right:0;margin-top:0}html.theme--catppuccin-mocha .columns.is-gapless>.column{margin:0;padding:0 !important}html.theme--catppuccin-mocha .columns.is-gapless:not(:last-child){margin-bottom:1.5rem}html.theme--catppuccin-mocha .columns.is-gapless:last-child{margin-bottom:0}html.theme--catppuccin-mocha .columns.is-mobile{display:flex}html.theme--catppuccin-mocha .columns.is-multiline{flex-wrap:wrap}html.theme--catppuccin-mocha .columns.is-vcentered{align-items:center}@media screen and (min-width: 769px),print{html.theme--catppuccin-mocha .columns:not(.is-desktop){display:flex}}@media screen and (min-width: 1056px){html.theme--catppuccin-mocha .columns.is-desktop{display:flex}}html.theme--catppuccin-mocha .columns.is-variable{--columnGap: 0.75rem;margin-left:calc(-1 * var(--columnGap));margin-right:calc(-1 * var(--columnGap))}html.theme--catppuccin-mocha .columns.is-variable>.column{padding-left:var(--columnGap);padding-right:var(--columnGap)}html.theme--catppuccin-mocha .columns.is-variable.is-0{--columnGap: 0rem}@media screen and (max-width: 768px){html.theme--catppuccin-mocha .columns.is-variable.is-0-mobile{--columnGap: 0rem}}@media screen and (min-width: 769px),print{html.theme--catppuccin-mocha .columns.is-variable.is-0-tablet{--columnGap: 0rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--catppuccin-mocha .columns.is-variable.is-0-tablet-only{--columnGap: 0rem}}@media screen and (max-width: 1055px){html.theme--catppuccin-mocha .columns.is-variable.is-0-touch{--columnGap: 0rem}}@media screen and (min-width: 1056px){html.theme--catppuccin-mocha .columns.is-variable.is-0-desktop{--columnGap: 0rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){html.theme--catppuccin-mocha .columns.is-variable.is-0-desktop-only{--columnGap: 0rem}}@media screen and (min-width: 1216px){html.theme--catppuccin-mocha .columns.is-variable.is-0-widescreen{--columnGap: 0rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){html.theme--catppuccin-mocha .columns.is-variable.is-0-widescreen-only{--columnGap: 0rem}}@media screen and (min-width: 1408px){html.theme--catppuccin-mocha .columns.is-variable.is-0-fullhd{--columnGap: 0rem}}html.theme--catppuccin-mocha .columns.is-variable.is-1{--columnGap: .25rem}@media screen and (max-width: 768px){html.theme--catppuccin-mocha .columns.is-variable.is-1-mobile{--columnGap: .25rem}}@media screen and (min-width: 769px),print{html.theme--catppuccin-mocha .columns.is-variable.is-1-tablet{--columnGap: .25rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--catppuccin-mocha .columns.is-variable.is-1-tablet-only{--columnGap: .25rem}}@media screen and (max-width: 1055px){html.theme--catppuccin-mocha .columns.is-variable.is-1-touch{--columnGap: .25rem}}@media screen and (min-width: 1056px){html.theme--catppuccin-mocha .columns.is-variable.is-1-desktop{--columnGap: .25rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){html.theme--catppuccin-mocha .columns.is-variable.is-1-desktop-only{--columnGap: .25rem}}@media screen and (min-width: 1216px){html.theme--catppuccin-mocha .columns.is-variable.is-1-widescreen{--columnGap: .25rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){html.theme--catppuccin-mocha .columns.is-variable.is-1-widescreen-only{--columnGap: .25rem}}@media screen and (min-width: 1408px){html.theme--catppuccin-mocha .columns.is-variable.is-1-fullhd{--columnGap: .25rem}}html.theme--catppuccin-mocha .columns.is-variable.is-2{--columnGap: .5rem}@media screen and (max-width: 768px){html.theme--catppuccin-mocha .columns.is-variable.is-2-mobile{--columnGap: .5rem}}@media screen and (min-width: 769px),print{html.theme--catppuccin-mocha .columns.is-variable.is-2-tablet{--columnGap: .5rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--catppuccin-mocha .columns.is-variable.is-2-tablet-only{--columnGap: .5rem}}@media screen and (max-width: 1055px){html.theme--catppuccin-mocha .columns.is-variable.is-2-touch{--columnGap: .5rem}}@media screen and (min-width: 1056px){html.theme--catppuccin-mocha .columns.is-variable.is-2-desktop{--columnGap: .5rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){html.theme--catppuccin-mocha .columns.is-variable.is-2-desktop-only{--columnGap: .5rem}}@media screen and (min-width: 1216px){html.theme--catppuccin-mocha .columns.is-variable.is-2-widescreen{--columnGap: .5rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){html.theme--catppuccin-mocha .columns.is-variable.is-2-widescreen-only{--columnGap: .5rem}}@media screen and (min-width: 1408px){html.theme--catppuccin-mocha .columns.is-variable.is-2-fullhd{--columnGap: .5rem}}html.theme--catppuccin-mocha .columns.is-variable.is-3{--columnGap: .75rem}@media screen and (max-width: 768px){html.theme--catppuccin-mocha .columns.is-variable.is-3-mobile{--columnGap: .75rem}}@media screen and (min-width: 769px),print{html.theme--catppuccin-mocha .columns.is-variable.is-3-tablet{--columnGap: .75rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--catppuccin-mocha .columns.is-variable.is-3-tablet-only{--columnGap: .75rem}}@media screen and (max-width: 1055px){html.theme--catppuccin-mocha .columns.is-variable.is-3-touch{--columnGap: .75rem}}@media screen and (min-width: 1056px){html.theme--catppuccin-mocha .columns.is-variable.is-3-desktop{--columnGap: .75rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){html.theme--catppuccin-mocha .columns.is-variable.is-3-desktop-only{--columnGap: .75rem}}@media screen and (min-width: 1216px){html.theme--catppuccin-mocha .columns.is-variable.is-3-widescreen{--columnGap: .75rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){html.theme--catppuccin-mocha .columns.is-variable.is-3-widescreen-only{--columnGap: .75rem}}@media screen and (min-width: 1408px){html.theme--catppuccin-mocha .columns.is-variable.is-3-fullhd{--columnGap: .75rem}}html.theme--catppuccin-mocha .columns.is-variable.is-4{--columnGap: 1rem}@media screen and (max-width: 768px){html.theme--catppuccin-mocha .columns.is-variable.is-4-mobile{--columnGap: 1rem}}@media screen and (min-width: 769px),print{html.theme--catppuccin-mocha .columns.is-variable.is-4-tablet{--columnGap: 1rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--catppuccin-mocha .columns.is-variable.is-4-tablet-only{--columnGap: 1rem}}@media screen and (max-width: 1055px){html.theme--catppuccin-mocha .columns.is-variable.is-4-touch{--columnGap: 1rem}}@media screen and (min-width: 1056px){html.theme--catppuccin-mocha .columns.is-variable.is-4-desktop{--columnGap: 1rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){html.theme--catppuccin-mocha .columns.is-variable.is-4-desktop-only{--columnGap: 1rem}}@media screen and (min-width: 1216px){html.theme--catppuccin-mocha .columns.is-variable.is-4-widescreen{--columnGap: 1rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){html.theme--catppuccin-mocha .columns.is-variable.is-4-widescreen-only{--columnGap: 1rem}}@media screen and (min-width: 1408px){html.theme--catppuccin-mocha .columns.is-variable.is-4-fullhd{--columnGap: 1rem}}html.theme--catppuccin-mocha .columns.is-variable.is-5{--columnGap: 1.25rem}@media screen and (max-width: 768px){html.theme--catppuccin-mocha .columns.is-variable.is-5-mobile{--columnGap: 1.25rem}}@media screen and (min-width: 769px),print{html.theme--catppuccin-mocha .columns.is-variable.is-5-tablet{--columnGap: 1.25rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--catppuccin-mocha .columns.is-variable.is-5-tablet-only{--columnGap: 1.25rem}}@media screen and (max-width: 1055px){html.theme--catppuccin-mocha .columns.is-variable.is-5-touch{--columnGap: 1.25rem}}@media screen and (min-width: 1056px){html.theme--catppuccin-mocha .columns.is-variable.is-5-desktop{--columnGap: 1.25rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){html.theme--catppuccin-mocha .columns.is-variable.is-5-desktop-only{--columnGap: 1.25rem}}@media screen and (min-width: 1216px){html.theme--catppuccin-mocha .columns.is-variable.is-5-widescreen{--columnGap: 1.25rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){html.theme--catppuccin-mocha .columns.is-variable.is-5-widescreen-only{--columnGap: 1.25rem}}@media screen and (min-width: 1408px){html.theme--catppuccin-mocha .columns.is-variable.is-5-fullhd{--columnGap: 1.25rem}}html.theme--catppuccin-mocha .columns.is-variable.is-6{--columnGap: 1.5rem}@media screen and (max-width: 768px){html.theme--catppuccin-mocha .columns.is-variable.is-6-mobile{--columnGap: 1.5rem}}@media screen and (min-width: 769px),print{html.theme--catppuccin-mocha .columns.is-variable.is-6-tablet{--columnGap: 1.5rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--catppuccin-mocha .columns.is-variable.is-6-tablet-only{--columnGap: 1.5rem}}@media screen and (max-width: 1055px){html.theme--catppuccin-mocha .columns.is-variable.is-6-touch{--columnGap: 1.5rem}}@media screen and (min-width: 1056px){html.theme--catppuccin-mocha .columns.is-variable.is-6-desktop{--columnGap: 1.5rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){html.theme--catppuccin-mocha .columns.is-variable.is-6-desktop-only{--columnGap: 1.5rem}}@media screen and (min-width: 1216px){html.theme--catppuccin-mocha .columns.is-variable.is-6-widescreen{--columnGap: 1.5rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){html.theme--catppuccin-mocha .columns.is-variable.is-6-widescreen-only{--columnGap: 1.5rem}}@media screen and (min-width: 1408px){html.theme--catppuccin-mocha .columns.is-variable.is-6-fullhd{--columnGap: 1.5rem}}html.theme--catppuccin-mocha .columns.is-variable.is-7{--columnGap: 1.75rem}@media screen and (max-width: 768px){html.theme--catppuccin-mocha .columns.is-variable.is-7-mobile{--columnGap: 1.75rem}}@media screen and (min-width: 769px),print{html.theme--catppuccin-mocha .columns.is-variable.is-7-tablet{--columnGap: 1.75rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--catppuccin-mocha .columns.is-variable.is-7-tablet-only{--columnGap: 1.75rem}}@media screen and (max-width: 1055px){html.theme--catppuccin-mocha .columns.is-variable.is-7-touch{--columnGap: 1.75rem}}@media screen and (min-width: 1056px){html.theme--catppuccin-mocha .columns.is-variable.is-7-desktop{--columnGap: 1.75rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){html.theme--catppuccin-mocha .columns.is-variable.is-7-desktop-only{--columnGap: 1.75rem}}@media screen and (min-width: 1216px){html.theme--catppuccin-mocha .columns.is-variable.is-7-widescreen{--columnGap: 1.75rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){html.theme--catppuccin-mocha .columns.is-variable.is-7-widescreen-only{--columnGap: 1.75rem}}@media screen and (min-width: 1408px){html.theme--catppuccin-mocha .columns.is-variable.is-7-fullhd{--columnGap: 1.75rem}}html.theme--catppuccin-mocha .columns.is-variable.is-8{--columnGap: 2rem}@media screen and (max-width: 768px){html.theme--catppuccin-mocha .columns.is-variable.is-8-mobile{--columnGap: 2rem}}@media screen and (min-width: 769px),print{html.theme--catppuccin-mocha .columns.is-variable.is-8-tablet{--columnGap: 2rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--catppuccin-mocha .columns.is-variable.is-8-tablet-only{--columnGap: 2rem}}@media screen and (max-width: 1055px){html.theme--catppuccin-mocha .columns.is-variable.is-8-touch{--columnGap: 2rem}}@media screen and (min-width: 1056px){html.theme--catppuccin-mocha .columns.is-variable.is-8-desktop{--columnGap: 2rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){html.theme--catppuccin-mocha .columns.is-variable.is-8-desktop-only{--columnGap: 2rem}}@media screen and (min-width: 1216px){html.theme--catppuccin-mocha .columns.is-variable.is-8-widescreen{--columnGap: 2rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){html.theme--catppuccin-mocha .columns.is-variable.is-8-widescreen-only{--columnGap: 2rem}}@media screen and (min-width: 1408px){html.theme--catppuccin-mocha .columns.is-variable.is-8-fullhd{--columnGap: 2rem}}html.theme--catppuccin-mocha .tile{align-items:stretch;display:block;flex-basis:0;flex-grow:1;flex-shrink:1;min-height:min-content}html.theme--catppuccin-mocha .tile.is-ancestor{margin-left:-.75rem;margin-right:-.75rem;margin-top:-.75rem}html.theme--catppuccin-mocha .tile.is-ancestor:last-child{margin-bottom:-.75rem}html.theme--catppuccin-mocha .tile.is-ancestor:not(:last-child){margin-bottom:.75rem}html.theme--catppuccin-mocha .tile.is-child{margin:0 !important}html.theme--catppuccin-mocha .tile.is-parent{padding:.75rem}html.theme--catppuccin-mocha .tile.is-vertical{flex-direction:column}html.theme--catppuccin-mocha .tile.is-vertical>.tile.is-child:not(:last-child){margin-bottom:1.5rem !important}@media screen and (min-width: 769px),print{html.theme--catppuccin-mocha .tile:not(.is-child){display:flex}html.theme--catppuccin-mocha .tile.is-1{flex:none;width:8.33333337%}html.theme--catppuccin-mocha .tile.is-2{flex:none;width:16.66666674%}html.theme--catppuccin-mocha .tile.is-3{flex:none;width:25%}html.theme--catppuccin-mocha .tile.is-4{flex:none;width:33.33333337%}html.theme--catppuccin-mocha .tile.is-5{flex:none;width:41.66666674%}html.theme--catppuccin-mocha .tile.is-6{flex:none;width:50%}html.theme--catppuccin-mocha .tile.is-7{flex:none;width:58.33333337%}html.theme--catppuccin-mocha .tile.is-8{flex:none;width:66.66666674%}html.theme--catppuccin-mocha .tile.is-9{flex:none;width:75%}html.theme--catppuccin-mocha .tile.is-10{flex:none;width:83.33333337%}html.theme--catppuccin-mocha .tile.is-11{flex:none;width:91.66666674%}html.theme--catppuccin-mocha .tile.is-12{flex:none;width:100%}}html.theme--catppuccin-mocha .hero{align-items:stretch;display:flex;flex-direction:column;justify-content:space-between}html.theme--catppuccin-mocha .hero .navbar{background:none}html.theme--catppuccin-mocha .hero .tabs ul{border-bottom:none}html.theme--catppuccin-mocha .hero.is-white{background-color:#fff;color:#0a0a0a}html.theme--catppuccin-mocha .hero.is-white a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--catppuccin-mocha .hero.is-white strong{color:inherit}html.theme--catppuccin-mocha .hero.is-white .title{color:#0a0a0a}html.theme--catppuccin-mocha .hero.is-white .subtitle{color:rgba(10,10,10,0.9)}html.theme--catppuccin-mocha .hero.is-white .subtitle a:not(.button),html.theme--catppuccin-mocha .hero.is-white .subtitle strong{color:#0a0a0a}@media screen and (max-width: 1055px){html.theme--catppuccin-mocha .hero.is-white .navbar-menu{background-color:#fff}}html.theme--catppuccin-mocha .hero.is-white .navbar-item,html.theme--catppuccin-mocha .hero.is-white .navbar-link{color:rgba(10,10,10,0.7)}html.theme--catppuccin-mocha .hero.is-white a.navbar-item:hover,html.theme--catppuccin-mocha .hero.is-white a.navbar-item.is-active,html.theme--catppuccin-mocha .hero.is-white .navbar-link:hover,html.theme--catppuccin-mocha .hero.is-white .navbar-link.is-active{background-color:#f2f2f2;color:#0a0a0a}html.theme--catppuccin-mocha .hero.is-white .tabs a{color:#0a0a0a;opacity:0.9}html.theme--catppuccin-mocha .hero.is-white .tabs a:hover{opacity:1}html.theme--catppuccin-mocha .hero.is-white .tabs li.is-active a{color:#fff !important;opacity:1}html.theme--catppuccin-mocha .hero.is-white .tabs.is-boxed a,html.theme--catppuccin-mocha .hero.is-white .tabs.is-toggle a{color:#0a0a0a}html.theme--catppuccin-mocha .hero.is-white .tabs.is-boxed a:hover,html.theme--catppuccin-mocha .hero.is-white .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--catppuccin-mocha .hero.is-white .tabs.is-boxed li.is-active a,html.theme--catppuccin-mocha .hero.is-white .tabs.is-boxed li.is-active a:hover,html.theme--catppuccin-mocha .hero.is-white .tabs.is-toggle li.is-active a,html.theme--catppuccin-mocha .hero.is-white .tabs.is-toggle li.is-active a:hover{background-color:#0a0a0a;border-color:#0a0a0a;color:#fff}html.theme--catppuccin-mocha .hero.is-white.is-bold{background-image:linear-gradient(141deg, #e8e3e4 0%, #fff 71%, #fff 100%)}@media screen and (max-width: 768px){html.theme--catppuccin-mocha .hero.is-white.is-bold .navbar-menu{background-image:linear-gradient(141deg, #e8e3e4 0%, #fff 71%, #fff 100%)}}html.theme--catppuccin-mocha .hero.is-black{background-color:#0a0a0a;color:#fff}html.theme--catppuccin-mocha .hero.is-black a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--catppuccin-mocha .hero.is-black strong{color:inherit}html.theme--catppuccin-mocha .hero.is-black .title{color:#fff}html.theme--catppuccin-mocha .hero.is-black .subtitle{color:rgba(255,255,255,0.9)}html.theme--catppuccin-mocha .hero.is-black .subtitle a:not(.button),html.theme--catppuccin-mocha .hero.is-black .subtitle strong{color:#fff}@media screen and (max-width: 1055px){html.theme--catppuccin-mocha .hero.is-black .navbar-menu{background-color:#0a0a0a}}html.theme--catppuccin-mocha .hero.is-black .navbar-item,html.theme--catppuccin-mocha .hero.is-black .navbar-link{color:rgba(255,255,255,0.7)}html.theme--catppuccin-mocha .hero.is-black a.navbar-item:hover,html.theme--catppuccin-mocha .hero.is-black a.navbar-item.is-active,html.theme--catppuccin-mocha .hero.is-black .navbar-link:hover,html.theme--catppuccin-mocha .hero.is-black .navbar-link.is-active{background-color:#000;color:#fff}html.theme--catppuccin-mocha .hero.is-black .tabs a{color:#fff;opacity:0.9}html.theme--catppuccin-mocha .hero.is-black .tabs a:hover{opacity:1}html.theme--catppuccin-mocha .hero.is-black .tabs li.is-active a{color:#0a0a0a !important;opacity:1}html.theme--catppuccin-mocha .hero.is-black .tabs.is-boxed a,html.theme--catppuccin-mocha .hero.is-black .tabs.is-toggle a{color:#fff}html.theme--catppuccin-mocha .hero.is-black .tabs.is-boxed a:hover,html.theme--catppuccin-mocha .hero.is-black .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--catppuccin-mocha .hero.is-black .tabs.is-boxed li.is-active a,html.theme--catppuccin-mocha .hero.is-black .tabs.is-boxed li.is-active a:hover,html.theme--catppuccin-mocha .hero.is-black .tabs.is-toggle li.is-active a,html.theme--catppuccin-mocha .hero.is-black .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#0a0a0a}html.theme--catppuccin-mocha .hero.is-black.is-bold{background-image:linear-gradient(141deg, #000 0%, #0a0a0a 71%, #181616 100%)}@media screen and (max-width: 768px){html.theme--catppuccin-mocha .hero.is-black.is-bold .navbar-menu{background-image:linear-gradient(141deg, #000 0%, #0a0a0a 71%, #181616 100%)}}html.theme--catppuccin-mocha .hero.is-light{background-color:#f5f5f5;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .hero.is-light a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--catppuccin-mocha .hero.is-light strong{color:inherit}html.theme--catppuccin-mocha .hero.is-light .title{color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .hero.is-light .subtitle{color:rgba(0,0,0,0.9)}html.theme--catppuccin-mocha .hero.is-light .subtitle a:not(.button),html.theme--catppuccin-mocha .hero.is-light .subtitle strong{color:rgba(0,0,0,0.7)}@media screen and (max-width: 1055px){html.theme--catppuccin-mocha .hero.is-light .navbar-menu{background-color:#f5f5f5}}html.theme--catppuccin-mocha .hero.is-light .navbar-item,html.theme--catppuccin-mocha .hero.is-light .navbar-link{color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .hero.is-light a.navbar-item:hover,html.theme--catppuccin-mocha .hero.is-light a.navbar-item.is-active,html.theme--catppuccin-mocha .hero.is-light .navbar-link:hover,html.theme--catppuccin-mocha .hero.is-light .navbar-link.is-active{background-color:#e8e8e8;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .hero.is-light .tabs a{color:rgba(0,0,0,0.7);opacity:0.9}html.theme--catppuccin-mocha .hero.is-light .tabs a:hover{opacity:1}html.theme--catppuccin-mocha .hero.is-light .tabs li.is-active a{color:#f5f5f5 !important;opacity:1}html.theme--catppuccin-mocha .hero.is-light .tabs.is-boxed a,html.theme--catppuccin-mocha .hero.is-light .tabs.is-toggle a{color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .hero.is-light .tabs.is-boxed a:hover,html.theme--catppuccin-mocha .hero.is-light .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--catppuccin-mocha .hero.is-light .tabs.is-boxed li.is-active a,html.theme--catppuccin-mocha .hero.is-light .tabs.is-boxed li.is-active a:hover,html.theme--catppuccin-mocha .hero.is-light .tabs.is-toggle li.is-active a,html.theme--catppuccin-mocha .hero.is-light .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:#f5f5f5}html.theme--catppuccin-mocha .hero.is-light.is-bold{background-image:linear-gradient(141deg, #dfd8d9 0%, #f5f5f5 71%, #fff 100%)}@media screen and (max-width: 768px){html.theme--catppuccin-mocha .hero.is-light.is-bold .navbar-menu{background-image:linear-gradient(141deg, #dfd8d9 0%, #f5f5f5 71%, #fff 100%)}}html.theme--catppuccin-mocha .hero.is-dark,html.theme--catppuccin-mocha .content kbd.hero{background-color:#313244;color:#fff}html.theme--catppuccin-mocha .hero.is-dark a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--catppuccin-mocha .content kbd.hero a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--catppuccin-mocha .hero.is-dark strong,html.theme--catppuccin-mocha .content kbd.hero strong{color:inherit}html.theme--catppuccin-mocha .hero.is-dark .title,html.theme--catppuccin-mocha .content kbd.hero .title{color:#fff}html.theme--catppuccin-mocha .hero.is-dark .subtitle,html.theme--catppuccin-mocha .content kbd.hero .subtitle{color:rgba(255,255,255,0.9)}html.theme--catppuccin-mocha .hero.is-dark .subtitle a:not(.button),html.theme--catppuccin-mocha .content kbd.hero .subtitle a:not(.button),html.theme--catppuccin-mocha .hero.is-dark .subtitle strong,html.theme--catppuccin-mocha .content kbd.hero .subtitle strong{color:#fff}@media screen and (max-width: 1055px){html.theme--catppuccin-mocha .hero.is-dark .navbar-menu,html.theme--catppuccin-mocha .content kbd.hero .navbar-menu{background-color:#313244}}html.theme--catppuccin-mocha .hero.is-dark .navbar-item,html.theme--catppuccin-mocha .content kbd.hero .navbar-item,html.theme--catppuccin-mocha .hero.is-dark .navbar-link,html.theme--catppuccin-mocha .content kbd.hero .navbar-link{color:rgba(255,255,255,0.7)}html.theme--catppuccin-mocha .hero.is-dark a.navbar-item:hover,html.theme--catppuccin-mocha .content kbd.hero a.navbar-item:hover,html.theme--catppuccin-mocha .hero.is-dark a.navbar-item.is-active,html.theme--catppuccin-mocha .content kbd.hero a.navbar-item.is-active,html.theme--catppuccin-mocha .hero.is-dark .navbar-link:hover,html.theme--catppuccin-mocha .content kbd.hero .navbar-link:hover,html.theme--catppuccin-mocha .hero.is-dark .navbar-link.is-active,html.theme--catppuccin-mocha .content kbd.hero .navbar-link.is-active{background-color:#262735;color:#fff}html.theme--catppuccin-mocha .hero.is-dark .tabs a,html.theme--catppuccin-mocha .content kbd.hero .tabs a{color:#fff;opacity:0.9}html.theme--catppuccin-mocha .hero.is-dark .tabs a:hover,html.theme--catppuccin-mocha .content kbd.hero .tabs a:hover{opacity:1}html.theme--catppuccin-mocha .hero.is-dark .tabs li.is-active a,html.theme--catppuccin-mocha .content kbd.hero .tabs li.is-active a{color:#313244 !important;opacity:1}html.theme--catppuccin-mocha .hero.is-dark .tabs.is-boxed a,html.theme--catppuccin-mocha .content kbd.hero .tabs.is-boxed a,html.theme--catppuccin-mocha .hero.is-dark .tabs.is-toggle a,html.theme--catppuccin-mocha .content kbd.hero .tabs.is-toggle a{color:#fff}html.theme--catppuccin-mocha .hero.is-dark .tabs.is-boxed a:hover,html.theme--catppuccin-mocha .content kbd.hero .tabs.is-boxed a:hover,html.theme--catppuccin-mocha .hero.is-dark .tabs.is-toggle a:hover,html.theme--catppuccin-mocha .content kbd.hero .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--catppuccin-mocha .hero.is-dark .tabs.is-boxed li.is-active a,html.theme--catppuccin-mocha .content kbd.hero .tabs.is-boxed li.is-active a,html.theme--catppuccin-mocha .hero.is-dark .tabs.is-boxed li.is-active a:hover,html.theme--catppuccin-mocha .hero.is-dark .tabs.is-toggle li.is-active a,html.theme--catppuccin-mocha .content kbd.hero .tabs.is-toggle li.is-active a,html.theme--catppuccin-mocha .hero.is-dark .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#313244}html.theme--catppuccin-mocha .hero.is-dark.is-bold,html.theme--catppuccin-mocha .content kbd.hero.is-bold{background-image:linear-gradient(141deg, #181c2a 0%, #313244 71%, #3c3856 100%)}@media screen and (max-width: 768px){html.theme--catppuccin-mocha .hero.is-dark.is-bold .navbar-menu,html.theme--catppuccin-mocha .content kbd.hero.is-bold .navbar-menu{background-image:linear-gradient(141deg, #181c2a 0%, #313244 71%, #3c3856 100%)}}html.theme--catppuccin-mocha .hero.is-primary,html.theme--catppuccin-mocha .docstring>section>a.hero.docs-sourcelink{background-color:#89b4fa;color:#fff}html.theme--catppuccin-mocha .hero.is-primary a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--catppuccin-mocha .docstring>section>a.hero.docs-sourcelink a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--catppuccin-mocha .hero.is-primary strong,html.theme--catppuccin-mocha .docstring>section>a.hero.docs-sourcelink strong{color:inherit}html.theme--catppuccin-mocha .hero.is-primary .title,html.theme--catppuccin-mocha .docstring>section>a.hero.docs-sourcelink .title{color:#fff}html.theme--catppuccin-mocha .hero.is-primary .subtitle,html.theme--catppuccin-mocha .docstring>section>a.hero.docs-sourcelink .subtitle{color:rgba(255,255,255,0.9)}html.theme--catppuccin-mocha .hero.is-primary .subtitle a:not(.button),html.theme--catppuccin-mocha .docstring>section>a.hero.docs-sourcelink .subtitle a:not(.button),html.theme--catppuccin-mocha .hero.is-primary .subtitle strong,html.theme--catppuccin-mocha .docstring>section>a.hero.docs-sourcelink .subtitle strong{color:#fff}@media screen and (max-width: 1055px){html.theme--catppuccin-mocha .hero.is-primary .navbar-menu,html.theme--catppuccin-mocha .docstring>section>a.hero.docs-sourcelink .navbar-menu{background-color:#89b4fa}}html.theme--catppuccin-mocha .hero.is-primary .navbar-item,html.theme--catppuccin-mocha .docstring>section>a.hero.docs-sourcelink .navbar-item,html.theme--catppuccin-mocha .hero.is-primary .navbar-link,html.theme--catppuccin-mocha .docstring>section>a.hero.docs-sourcelink .navbar-link{color:rgba(255,255,255,0.7)}html.theme--catppuccin-mocha .hero.is-primary a.navbar-item:hover,html.theme--catppuccin-mocha .docstring>section>a.hero.docs-sourcelink a.navbar-item:hover,html.theme--catppuccin-mocha .hero.is-primary a.navbar-item.is-active,html.theme--catppuccin-mocha .docstring>section>a.hero.docs-sourcelink a.navbar-item.is-active,html.theme--catppuccin-mocha .hero.is-primary .navbar-link:hover,html.theme--catppuccin-mocha .docstring>section>a.hero.docs-sourcelink .navbar-link:hover,html.theme--catppuccin-mocha .hero.is-primary .navbar-link.is-active,html.theme--catppuccin-mocha .docstring>section>a.hero.docs-sourcelink .navbar-link.is-active{background-color:#71a4f9;color:#fff}html.theme--catppuccin-mocha .hero.is-primary .tabs a,html.theme--catppuccin-mocha .docstring>section>a.hero.docs-sourcelink .tabs a{color:#fff;opacity:0.9}html.theme--catppuccin-mocha .hero.is-primary .tabs a:hover,html.theme--catppuccin-mocha .docstring>section>a.hero.docs-sourcelink .tabs a:hover{opacity:1}html.theme--catppuccin-mocha .hero.is-primary .tabs li.is-active a,html.theme--catppuccin-mocha .docstring>section>a.hero.docs-sourcelink .tabs li.is-active a{color:#89b4fa !important;opacity:1}html.theme--catppuccin-mocha .hero.is-primary .tabs.is-boxed a,html.theme--catppuccin-mocha .docstring>section>a.hero.docs-sourcelink .tabs.is-boxed a,html.theme--catppuccin-mocha .hero.is-primary .tabs.is-toggle a,html.theme--catppuccin-mocha .docstring>section>a.hero.docs-sourcelink .tabs.is-toggle a{color:#fff}html.theme--catppuccin-mocha .hero.is-primary .tabs.is-boxed a:hover,html.theme--catppuccin-mocha .docstring>section>a.hero.docs-sourcelink .tabs.is-boxed a:hover,html.theme--catppuccin-mocha .hero.is-primary .tabs.is-toggle a:hover,html.theme--catppuccin-mocha .docstring>section>a.hero.docs-sourcelink .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--catppuccin-mocha .hero.is-primary .tabs.is-boxed li.is-active a,html.theme--catppuccin-mocha .docstring>section>a.hero.docs-sourcelink .tabs.is-boxed li.is-active a,html.theme--catppuccin-mocha .hero.is-primary .tabs.is-boxed li.is-active a:hover,html.theme--catppuccin-mocha .hero.is-primary .tabs.is-toggle li.is-active a,html.theme--catppuccin-mocha .docstring>section>a.hero.docs-sourcelink .tabs.is-toggle li.is-active a,html.theme--catppuccin-mocha .hero.is-primary .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#89b4fa}html.theme--catppuccin-mocha .hero.is-primary.is-bold,html.theme--catppuccin-mocha .docstring>section>a.hero.is-bold.docs-sourcelink{background-image:linear-gradient(141deg, #51b0ff 0%, #89b4fa 71%, #9fb3fd 100%)}@media screen and (max-width: 768px){html.theme--catppuccin-mocha .hero.is-primary.is-bold .navbar-menu,html.theme--catppuccin-mocha .docstring>section>a.hero.is-bold.docs-sourcelink .navbar-menu{background-image:linear-gradient(141deg, #51b0ff 0%, #89b4fa 71%, #9fb3fd 100%)}}html.theme--catppuccin-mocha .hero.is-link{background-color:#89b4fa;color:#fff}html.theme--catppuccin-mocha .hero.is-link a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--catppuccin-mocha .hero.is-link strong{color:inherit}html.theme--catppuccin-mocha .hero.is-link .title{color:#fff}html.theme--catppuccin-mocha .hero.is-link .subtitle{color:rgba(255,255,255,0.9)}html.theme--catppuccin-mocha .hero.is-link .subtitle a:not(.button),html.theme--catppuccin-mocha .hero.is-link .subtitle strong{color:#fff}@media screen and (max-width: 1055px){html.theme--catppuccin-mocha .hero.is-link .navbar-menu{background-color:#89b4fa}}html.theme--catppuccin-mocha .hero.is-link .navbar-item,html.theme--catppuccin-mocha .hero.is-link .navbar-link{color:rgba(255,255,255,0.7)}html.theme--catppuccin-mocha .hero.is-link a.navbar-item:hover,html.theme--catppuccin-mocha .hero.is-link a.navbar-item.is-active,html.theme--catppuccin-mocha .hero.is-link .navbar-link:hover,html.theme--catppuccin-mocha .hero.is-link .navbar-link.is-active{background-color:#71a4f9;color:#fff}html.theme--catppuccin-mocha .hero.is-link .tabs a{color:#fff;opacity:0.9}html.theme--catppuccin-mocha .hero.is-link .tabs a:hover{opacity:1}html.theme--catppuccin-mocha .hero.is-link .tabs li.is-active a{color:#89b4fa !important;opacity:1}html.theme--catppuccin-mocha .hero.is-link .tabs.is-boxed a,html.theme--catppuccin-mocha .hero.is-link .tabs.is-toggle a{color:#fff}html.theme--catppuccin-mocha .hero.is-link .tabs.is-boxed a:hover,html.theme--catppuccin-mocha .hero.is-link .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--catppuccin-mocha .hero.is-link .tabs.is-boxed li.is-active a,html.theme--catppuccin-mocha .hero.is-link .tabs.is-boxed li.is-active a:hover,html.theme--catppuccin-mocha .hero.is-link .tabs.is-toggle li.is-active a,html.theme--catppuccin-mocha .hero.is-link .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#89b4fa}html.theme--catppuccin-mocha .hero.is-link.is-bold{background-image:linear-gradient(141deg, #51b0ff 0%, #89b4fa 71%, #9fb3fd 100%)}@media screen and (max-width: 768px){html.theme--catppuccin-mocha .hero.is-link.is-bold .navbar-menu{background-image:linear-gradient(141deg, #51b0ff 0%, #89b4fa 71%, #9fb3fd 100%)}}html.theme--catppuccin-mocha .hero.is-info{background-color:#94e2d5;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .hero.is-info a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--catppuccin-mocha .hero.is-info strong{color:inherit}html.theme--catppuccin-mocha .hero.is-info .title{color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .hero.is-info .subtitle{color:rgba(0,0,0,0.9)}html.theme--catppuccin-mocha .hero.is-info .subtitle a:not(.button),html.theme--catppuccin-mocha .hero.is-info .subtitle strong{color:rgba(0,0,0,0.7)}@media screen and (max-width: 1055px){html.theme--catppuccin-mocha .hero.is-info .navbar-menu{background-color:#94e2d5}}html.theme--catppuccin-mocha .hero.is-info .navbar-item,html.theme--catppuccin-mocha .hero.is-info .navbar-link{color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .hero.is-info a.navbar-item:hover,html.theme--catppuccin-mocha .hero.is-info a.navbar-item.is-active,html.theme--catppuccin-mocha .hero.is-info .navbar-link:hover,html.theme--catppuccin-mocha .hero.is-info .navbar-link.is-active{background-color:#80ddcd;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .hero.is-info .tabs a{color:rgba(0,0,0,0.7);opacity:0.9}html.theme--catppuccin-mocha .hero.is-info .tabs a:hover{opacity:1}html.theme--catppuccin-mocha .hero.is-info .tabs li.is-active a{color:#94e2d5 !important;opacity:1}html.theme--catppuccin-mocha .hero.is-info .tabs.is-boxed a,html.theme--catppuccin-mocha .hero.is-info .tabs.is-toggle a{color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .hero.is-info .tabs.is-boxed a:hover,html.theme--catppuccin-mocha .hero.is-info .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--catppuccin-mocha .hero.is-info .tabs.is-boxed li.is-active a,html.theme--catppuccin-mocha .hero.is-info .tabs.is-boxed li.is-active a:hover,html.theme--catppuccin-mocha .hero.is-info .tabs.is-toggle li.is-active a,html.theme--catppuccin-mocha .hero.is-info .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:#94e2d5}html.theme--catppuccin-mocha .hero.is-info.is-bold{background-image:linear-gradient(141deg, #63e0b6 0%, #94e2d5 71%, #a5eaea 100%)}@media screen and (max-width: 768px){html.theme--catppuccin-mocha .hero.is-info.is-bold .navbar-menu{background-image:linear-gradient(141deg, #63e0b6 0%, #94e2d5 71%, #a5eaea 100%)}}html.theme--catppuccin-mocha .hero.is-success{background-color:#a6e3a1;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .hero.is-success a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--catppuccin-mocha .hero.is-success strong{color:inherit}html.theme--catppuccin-mocha .hero.is-success .title{color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .hero.is-success .subtitle{color:rgba(0,0,0,0.9)}html.theme--catppuccin-mocha .hero.is-success .subtitle a:not(.button),html.theme--catppuccin-mocha .hero.is-success .subtitle strong{color:rgba(0,0,0,0.7)}@media screen and (max-width: 1055px){html.theme--catppuccin-mocha .hero.is-success .navbar-menu{background-color:#a6e3a1}}html.theme--catppuccin-mocha .hero.is-success .navbar-item,html.theme--catppuccin-mocha .hero.is-success .navbar-link{color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .hero.is-success a.navbar-item:hover,html.theme--catppuccin-mocha .hero.is-success a.navbar-item.is-active,html.theme--catppuccin-mocha .hero.is-success .navbar-link:hover,html.theme--catppuccin-mocha .hero.is-success .navbar-link.is-active{background-color:#93dd8d;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .hero.is-success .tabs a{color:rgba(0,0,0,0.7);opacity:0.9}html.theme--catppuccin-mocha .hero.is-success .tabs a:hover{opacity:1}html.theme--catppuccin-mocha .hero.is-success .tabs li.is-active a{color:#a6e3a1 !important;opacity:1}html.theme--catppuccin-mocha .hero.is-success .tabs.is-boxed a,html.theme--catppuccin-mocha .hero.is-success .tabs.is-toggle a{color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .hero.is-success .tabs.is-boxed a:hover,html.theme--catppuccin-mocha .hero.is-success .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--catppuccin-mocha .hero.is-success .tabs.is-boxed li.is-active a,html.theme--catppuccin-mocha .hero.is-success .tabs.is-boxed li.is-active a:hover,html.theme--catppuccin-mocha .hero.is-success .tabs.is-toggle li.is-active a,html.theme--catppuccin-mocha .hero.is-success .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:#a6e3a1}html.theme--catppuccin-mocha .hero.is-success.is-bold{background-image:linear-gradient(141deg, #8ce071 0%, #a6e3a1 71%, #b2ebb7 100%)}@media screen and (max-width: 768px){html.theme--catppuccin-mocha .hero.is-success.is-bold .navbar-menu{background-image:linear-gradient(141deg, #8ce071 0%, #a6e3a1 71%, #b2ebb7 100%)}}html.theme--catppuccin-mocha .hero.is-warning{background-color:#f9e2af;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .hero.is-warning a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--catppuccin-mocha .hero.is-warning strong{color:inherit}html.theme--catppuccin-mocha .hero.is-warning .title{color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .hero.is-warning .subtitle{color:rgba(0,0,0,0.9)}html.theme--catppuccin-mocha .hero.is-warning .subtitle a:not(.button),html.theme--catppuccin-mocha .hero.is-warning .subtitle strong{color:rgba(0,0,0,0.7)}@media screen and (max-width: 1055px){html.theme--catppuccin-mocha .hero.is-warning .navbar-menu{background-color:#f9e2af}}html.theme--catppuccin-mocha .hero.is-warning .navbar-item,html.theme--catppuccin-mocha .hero.is-warning .navbar-link{color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .hero.is-warning a.navbar-item:hover,html.theme--catppuccin-mocha .hero.is-warning a.navbar-item.is-active,html.theme--catppuccin-mocha .hero.is-warning .navbar-link:hover,html.theme--catppuccin-mocha .hero.is-warning .navbar-link.is-active{background-color:#f7d997;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .hero.is-warning .tabs a{color:rgba(0,0,0,0.7);opacity:0.9}html.theme--catppuccin-mocha .hero.is-warning .tabs a:hover{opacity:1}html.theme--catppuccin-mocha .hero.is-warning .tabs li.is-active a{color:#f9e2af !important;opacity:1}html.theme--catppuccin-mocha .hero.is-warning .tabs.is-boxed a,html.theme--catppuccin-mocha .hero.is-warning .tabs.is-toggle a{color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .hero.is-warning .tabs.is-boxed a:hover,html.theme--catppuccin-mocha .hero.is-warning .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--catppuccin-mocha .hero.is-warning .tabs.is-boxed li.is-active a,html.theme--catppuccin-mocha .hero.is-warning .tabs.is-boxed li.is-active a:hover,html.theme--catppuccin-mocha .hero.is-warning .tabs.is-toggle li.is-active a,html.theme--catppuccin-mocha .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:#f9e2af}html.theme--catppuccin-mocha .hero.is-warning.is-bold{background-image:linear-gradient(141deg, #fcbd79 0%, #f9e2af 71%, #fcf4c5 100%)}@media screen and (max-width: 768px){html.theme--catppuccin-mocha .hero.is-warning.is-bold .navbar-menu{background-image:linear-gradient(141deg, #fcbd79 0%, #f9e2af 71%, #fcf4c5 100%)}}html.theme--catppuccin-mocha .hero.is-danger{background-color:#f38ba8;color:#fff}html.theme--catppuccin-mocha .hero.is-danger a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--catppuccin-mocha .hero.is-danger strong{color:inherit}html.theme--catppuccin-mocha .hero.is-danger .title{color:#fff}html.theme--catppuccin-mocha .hero.is-danger .subtitle{color:rgba(255,255,255,0.9)}html.theme--catppuccin-mocha .hero.is-danger .subtitle a:not(.button),html.theme--catppuccin-mocha .hero.is-danger .subtitle strong{color:#fff}@media screen and (max-width: 1055px){html.theme--catppuccin-mocha .hero.is-danger .navbar-menu{background-color:#f38ba8}}html.theme--catppuccin-mocha .hero.is-danger .navbar-item,html.theme--catppuccin-mocha .hero.is-danger .navbar-link{color:rgba(255,255,255,0.7)}html.theme--catppuccin-mocha .hero.is-danger a.navbar-item:hover,html.theme--catppuccin-mocha .hero.is-danger a.navbar-item.is-active,html.theme--catppuccin-mocha .hero.is-danger .navbar-link:hover,html.theme--catppuccin-mocha .hero.is-danger .navbar-link.is-active{background-color:#f17497;color:#fff}html.theme--catppuccin-mocha .hero.is-danger .tabs a{color:#fff;opacity:0.9}html.theme--catppuccin-mocha .hero.is-danger .tabs a:hover{opacity:1}html.theme--catppuccin-mocha .hero.is-danger .tabs li.is-active a{color:#f38ba8 !important;opacity:1}html.theme--catppuccin-mocha .hero.is-danger .tabs.is-boxed a,html.theme--catppuccin-mocha .hero.is-danger .tabs.is-toggle a{color:#fff}html.theme--catppuccin-mocha .hero.is-danger .tabs.is-boxed a:hover,html.theme--catppuccin-mocha .hero.is-danger .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--catppuccin-mocha .hero.is-danger .tabs.is-boxed li.is-active a,html.theme--catppuccin-mocha .hero.is-danger .tabs.is-boxed li.is-active a:hover,html.theme--catppuccin-mocha .hero.is-danger .tabs.is-toggle li.is-active a,html.theme--catppuccin-mocha .hero.is-danger .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#f38ba8}html.theme--catppuccin-mocha .hero.is-danger.is-bold{background-image:linear-gradient(141deg, #f7549d 0%, #f38ba8 71%, #f8a0a9 100%)}@media screen and (max-width: 768px){html.theme--catppuccin-mocha .hero.is-danger.is-bold .navbar-menu{background-image:linear-gradient(141deg, #f7549d 0%, #f38ba8 71%, #f8a0a9 100%)}}html.theme--catppuccin-mocha .hero.is-small .hero-body,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.hero .hero-body{padding:1.5rem}@media screen and (min-width: 769px),print{html.theme--catppuccin-mocha .hero.is-medium .hero-body{padding:9rem 4.5rem}}@media screen and (min-width: 769px),print{html.theme--catppuccin-mocha .hero.is-large .hero-body{padding:18rem 6rem}}html.theme--catppuccin-mocha .hero.is-halfheight .hero-body,html.theme--catppuccin-mocha .hero.is-fullheight .hero-body,html.theme--catppuccin-mocha .hero.is-fullheight-with-navbar .hero-body{align-items:center;display:flex}html.theme--catppuccin-mocha .hero.is-halfheight .hero-body>.container,html.theme--catppuccin-mocha .hero.is-fullheight .hero-body>.container,html.theme--catppuccin-mocha .hero.is-fullheight-with-navbar .hero-body>.container{flex-grow:1;flex-shrink:1}html.theme--catppuccin-mocha .hero.is-halfheight{min-height:50vh}html.theme--catppuccin-mocha .hero.is-fullheight{min-height:100vh}html.theme--catppuccin-mocha .hero-video{overflow:hidden}html.theme--catppuccin-mocha .hero-video video{left:50%;min-height:100%;min-width:100%;position:absolute;top:50%;transform:translate3d(-50%, -50%, 0)}html.theme--catppuccin-mocha .hero-video.is-transparent{opacity:0.3}@media screen and (max-width: 768px){html.theme--catppuccin-mocha .hero-video{display:none}}html.theme--catppuccin-mocha .hero-buttons{margin-top:1.5rem}@media screen and (max-width: 768px){html.theme--catppuccin-mocha .hero-buttons .button{display:flex}html.theme--catppuccin-mocha .hero-buttons .button:not(:last-child){margin-bottom:0.75rem}}@media screen and (min-width: 769px),print{html.theme--catppuccin-mocha .hero-buttons{display:flex;justify-content:center}html.theme--catppuccin-mocha .hero-buttons .button:not(:last-child){margin-right:1.5rem}}html.theme--catppuccin-mocha .hero-head,html.theme--catppuccin-mocha .hero-foot{flex-grow:0;flex-shrink:0}html.theme--catppuccin-mocha .hero-body{flex-grow:1;flex-shrink:0;padding:3rem 1.5rem}@media screen and (min-width: 769px),print{html.theme--catppuccin-mocha .hero-body{padding:3rem 3rem}}html.theme--catppuccin-mocha .section{padding:3rem 1.5rem}@media screen and (min-width: 1056px){html.theme--catppuccin-mocha .section{padding:3rem 3rem}html.theme--catppuccin-mocha .section.is-medium{padding:9rem 4.5rem}html.theme--catppuccin-mocha .section.is-large{padding:18rem 6rem}}html.theme--catppuccin-mocha .footer{background-color:#181825;padding:3rem 1.5rem 6rem}html.theme--catppuccin-mocha h1 .docs-heading-anchor,html.theme--catppuccin-mocha h1 .docs-heading-anchor:hover,html.theme--catppuccin-mocha h1 .docs-heading-anchor:visited,html.theme--catppuccin-mocha h2 .docs-heading-anchor,html.theme--catppuccin-mocha h2 .docs-heading-anchor:hover,html.theme--catppuccin-mocha h2 .docs-heading-anchor:visited,html.theme--catppuccin-mocha h3 .docs-heading-anchor,html.theme--catppuccin-mocha h3 .docs-heading-anchor:hover,html.theme--catppuccin-mocha h3 .docs-heading-anchor:visited,html.theme--catppuccin-mocha h4 .docs-heading-anchor,html.theme--catppuccin-mocha h4 .docs-heading-anchor:hover,html.theme--catppuccin-mocha h4 .docs-heading-anchor:visited,html.theme--catppuccin-mocha h5 .docs-heading-anchor,html.theme--catppuccin-mocha h5 .docs-heading-anchor:hover,html.theme--catppuccin-mocha h5 .docs-heading-anchor:visited,html.theme--catppuccin-mocha h6 .docs-heading-anchor,html.theme--catppuccin-mocha h6 .docs-heading-anchor:hover,html.theme--catppuccin-mocha h6 .docs-heading-anchor:visited{color:#cdd6f4}html.theme--catppuccin-mocha h1 .docs-heading-anchor-permalink,html.theme--catppuccin-mocha h2 .docs-heading-anchor-permalink,html.theme--catppuccin-mocha h3 .docs-heading-anchor-permalink,html.theme--catppuccin-mocha h4 .docs-heading-anchor-permalink,html.theme--catppuccin-mocha h5 .docs-heading-anchor-permalink,html.theme--catppuccin-mocha h6 .docs-heading-anchor-permalink{visibility:hidden;vertical-align:middle;margin-left:0.5em;font-size:0.7rem}html.theme--catppuccin-mocha h1 .docs-heading-anchor-permalink::before,html.theme--catppuccin-mocha h2 .docs-heading-anchor-permalink::before,html.theme--catppuccin-mocha h3 .docs-heading-anchor-permalink::before,html.theme--catppuccin-mocha h4 .docs-heading-anchor-permalink::before,html.theme--catppuccin-mocha h5 .docs-heading-anchor-permalink::before,html.theme--catppuccin-mocha h6 .docs-heading-anchor-permalink::before{font-family:"Font Awesome 6 Free";font-weight:900;content:"\f0c1"}html.theme--catppuccin-mocha h1:hover .docs-heading-anchor-permalink,html.theme--catppuccin-mocha h2:hover .docs-heading-anchor-permalink,html.theme--catppuccin-mocha h3:hover .docs-heading-anchor-permalink,html.theme--catppuccin-mocha h4:hover .docs-heading-anchor-permalink,html.theme--catppuccin-mocha h5:hover .docs-heading-anchor-permalink,html.theme--catppuccin-mocha h6:hover .docs-heading-anchor-permalink{visibility:visible}html.theme--catppuccin-mocha .docs-light-only{display:none !important}html.theme--catppuccin-mocha pre{position:relative;overflow:hidden}html.theme--catppuccin-mocha pre code,html.theme--catppuccin-mocha pre code.hljs{padding:0 .75rem !important;overflow:auto;display:block}html.theme--catppuccin-mocha pre code:first-of-type,html.theme--catppuccin-mocha pre code.hljs:first-of-type{padding-top:0.5rem !important}html.theme--catppuccin-mocha pre code:last-of-type,html.theme--catppuccin-mocha pre code.hljs:last-of-type{padding-bottom:0.5rem !important}html.theme--catppuccin-mocha 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 6 Free";color:#cdd6f4;cursor:pointer;text-align:center}html.theme--catppuccin-mocha pre .copy-button:focus,html.theme--catppuccin-mocha pre .copy-button:hover{opacity:1;background:rgba(205,214,244,0.1);color:#89b4fa}html.theme--catppuccin-mocha pre .copy-button.success{color:#a6e3a1;opacity:1}html.theme--catppuccin-mocha pre .copy-button.error{color:#f38ba8;opacity:1}html.theme--catppuccin-mocha pre:hover .copy-button{opacity:1}html.theme--catppuccin-mocha .admonition{background-color:#181825;border-style:solid;border-width:2px;border-color:#bac2de;border-radius:4px;font-size:1rem}html.theme--catppuccin-mocha .admonition strong{color:currentColor}html.theme--catppuccin-mocha .admonition.is-small,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.admonition{font-size:.75rem}html.theme--catppuccin-mocha .admonition.is-medium{font-size:1.25rem}html.theme--catppuccin-mocha .admonition.is-large{font-size:1.5rem}html.theme--catppuccin-mocha .admonition.is-default{background-color:#181825;border-color:#bac2de}html.theme--catppuccin-mocha .admonition.is-default>.admonition-header{background-color:rgba(0,0,0,0);color:#bac2de}html.theme--catppuccin-mocha .admonition.is-default>.admonition-body{color:#cdd6f4}html.theme--catppuccin-mocha .admonition.is-info{background-color:#181825;border-color:#94e2d5}html.theme--catppuccin-mocha .admonition.is-info>.admonition-header{background-color:rgba(0,0,0,0);color:#94e2d5}html.theme--catppuccin-mocha .admonition.is-info>.admonition-body{color:#cdd6f4}html.theme--catppuccin-mocha .admonition.is-success{background-color:#181825;border-color:#a6e3a1}html.theme--catppuccin-mocha .admonition.is-success>.admonition-header{background-color:rgba(0,0,0,0);color:#a6e3a1}html.theme--catppuccin-mocha .admonition.is-success>.admonition-body{color:#cdd6f4}html.theme--catppuccin-mocha .admonition.is-warning{background-color:#181825;border-color:#f9e2af}html.theme--catppuccin-mocha .admonition.is-warning>.admonition-header{background-color:rgba(0,0,0,0);color:#f9e2af}html.theme--catppuccin-mocha .admonition.is-warning>.admonition-body{color:#cdd6f4}html.theme--catppuccin-mocha .admonition.is-danger{background-color:#181825;border-color:#f38ba8}html.theme--catppuccin-mocha .admonition.is-danger>.admonition-header{background-color:rgba(0,0,0,0);color:#f38ba8}html.theme--catppuccin-mocha .admonition.is-danger>.admonition-body{color:#cdd6f4}html.theme--catppuccin-mocha .admonition.is-compat{background-color:#181825;border-color:#89dceb}html.theme--catppuccin-mocha .admonition.is-compat>.admonition-header{background-color:rgba(0,0,0,0);color:#89dceb}html.theme--catppuccin-mocha .admonition.is-compat>.admonition-body{color:#cdd6f4}html.theme--catppuccin-mocha .admonition.is-todo{background-color:#181825;border-color:#cba6f7}html.theme--catppuccin-mocha .admonition.is-todo>.admonition-header{background-color:rgba(0,0,0,0);color:#cba6f7}html.theme--catppuccin-mocha .admonition.is-todo>.admonition-body{color:#cdd6f4}html.theme--catppuccin-mocha .admonition-header{color:#bac2de;background-color:rgba(0,0,0,0);align-items:center;font-weight:700;justify-content:space-between;line-height:1.25;padding:0.5rem .75rem;position:relative}html.theme--catppuccin-mocha .admonition-header:before{font-family:"Font Awesome 6 Free";font-weight:900;margin-right:.75rem;content:"\f06a"}html.theme--catppuccin-mocha details.admonition.is-details>.admonition-header{list-style:none}html.theme--catppuccin-mocha details.admonition.is-details>.admonition-header:before{font-family:"Font Awesome 6 Free";font-weight:900;content:"\f055"}html.theme--catppuccin-mocha details.admonition.is-details[open]>.admonition-header:before{font-family:"Font Awesome 6 Free";font-weight:900;content:"\f056"}html.theme--catppuccin-mocha .admonition-body{color:#cdd6f4;padding:0.5rem .75rem}html.theme--catppuccin-mocha .admonition-body pre{background-color:#181825}html.theme--catppuccin-mocha .admonition-body code{background-color:#181825}html.theme--catppuccin-mocha .docstring{margin-bottom:1em;background-color:rgba(0,0,0,0);border:2px solid #585b70;border-radius:4px;box-shadow:none;max-width:100%}html.theme--catppuccin-mocha .docstring>header{cursor:pointer;display:flex;flex-grow:1;align-items:stretch;padding:0.5rem .75rem;background-color:#181825;box-shadow:0 0.125em 0.25em rgba(10,10,10,0.1);box-shadow:none;border-bottom:1px solid #585b70;overflow:auto}html.theme--catppuccin-mocha .docstring>header code{background-color:transparent}html.theme--catppuccin-mocha .docstring>header .docstring-article-toggle-button{min-width:1.1rem;padding:0.2rem 0.2rem 0.2rem 0}html.theme--catppuccin-mocha .docstring>header .docstring-binding{margin-right:0.3em}html.theme--catppuccin-mocha .docstring>header .docstring-category{margin-left:0.3em}html.theme--catppuccin-mocha .docstring>section{position:relative;padding:.75rem .75rem;border-bottom:1px solid #585b70}html.theme--catppuccin-mocha .docstring>section:last-child{border-bottom:none}html.theme--catppuccin-mocha .docstring>section>a.docs-sourcelink{transition:opacity 0.3s;opacity:0;position:absolute;right:.375rem;bottom:.375rem}html.theme--catppuccin-mocha .docstring>section>a.docs-sourcelink:focus{opacity:1 !important}html.theme--catppuccin-mocha .docstring:hover>section>a.docs-sourcelink{opacity:0.2}html.theme--catppuccin-mocha .docstring:focus-within>section>a.docs-sourcelink{opacity:0.2}html.theme--catppuccin-mocha .docstring>section:hover a.docs-sourcelink{opacity:1}html.theme--catppuccin-mocha .documenter-example-output{background-color:#1e1e2e}html.theme--catppuccin-mocha .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:#181825;color:#cdd6f4;border-bottom:3px solid rgba(0,0,0,0);padding:10px 35px;text-align:center;font-size:15px}html.theme--catppuccin-mocha .outdated-warning-overlay .outdated-warning-closer{position:absolute;top:calc(50% - 10px);right:18px;cursor:pointer;width:12px}html.theme--catppuccin-mocha .outdated-warning-overlay a{color:#89b4fa}html.theme--catppuccin-mocha .outdated-warning-overlay a:hover{color:#89dceb}html.theme--catppuccin-mocha .content pre{border:2px solid #585b70;border-radius:4px}html.theme--catppuccin-mocha .content code{font-weight:inherit}html.theme--catppuccin-mocha .content a code{color:#89b4fa}html.theme--catppuccin-mocha .content a:hover code{color:#89dceb}html.theme--catppuccin-mocha .content h1 code,html.theme--catppuccin-mocha .content h2 code,html.theme--catppuccin-mocha .content h3 code,html.theme--catppuccin-mocha .content h4 code,html.theme--catppuccin-mocha .content h5 code,html.theme--catppuccin-mocha .content h6 code{color:#cdd6f4}html.theme--catppuccin-mocha .content table{display:block;width:initial;max-width:100%;overflow-x:auto}html.theme--catppuccin-mocha .content blockquote>ul:first-child,html.theme--catppuccin-mocha .content blockquote>ol:first-child,html.theme--catppuccin-mocha .content .admonition-body>ul:first-child,html.theme--catppuccin-mocha .content .admonition-body>ol:first-child{margin-top:0}html.theme--catppuccin-mocha pre,html.theme--catppuccin-mocha code{font-variant-ligatures:no-contextual}html.theme--catppuccin-mocha .breadcrumb a.is-disabled{cursor:default;pointer-events:none}html.theme--catppuccin-mocha .breadcrumb a.is-disabled,html.theme--catppuccin-mocha .breadcrumb a.is-disabled:hover{color:#b8c5ef}html.theme--catppuccin-mocha .hljs{background:initial !important}html.theme--catppuccin-mocha .katex .katex-mathml{top:0;right:0}html.theme--catppuccin-mocha .katex-display,html.theme--catppuccin-mocha mjx-container,html.theme--catppuccin-mocha .MathJax_Display{margin:0.5em 0 !important}html.theme--catppuccin-mocha html{-moz-osx-font-smoothing:auto;-webkit-font-smoothing:auto}html.theme--catppuccin-mocha li.no-marker{list-style:none}html.theme--catppuccin-mocha #documenter .docs-main>article{overflow-wrap:break-word}html.theme--catppuccin-mocha #documenter .docs-main>article .math-container{overflow-x:auto;overflow-y:hidden}@media screen and (min-width: 1056px){html.theme--catppuccin-mocha #documenter .docs-main{max-width:52rem;margin-left:20rem;padding-right:1rem}}@media screen and (max-width: 1055px){html.theme--catppuccin-mocha #documenter .docs-main{width:100%}html.theme--catppuccin-mocha #documenter .docs-main>article{max-width:52rem;margin-left:auto;margin-right:auto;margin-bottom:1rem;padding:0 1rem}html.theme--catppuccin-mocha #documenter .docs-main>header,html.theme--catppuccin-mocha #documenter .docs-main>nav{max-width:100%;width:100%;margin:0}}html.theme--catppuccin-mocha #documenter .docs-main header.docs-navbar{background-color:#1e1e2e;border-bottom:1px solid #585b70;z-index:2;min-height:4rem;margin-bottom:1rem;display:flex}html.theme--catppuccin-mocha #documenter .docs-main header.docs-navbar .breadcrumb{flex-grow:1;overflow-x:hidden}html.theme--catppuccin-mocha #documenter .docs-main header.docs-navbar .docs-sidebar-button{display:block;font-size:1.5rem;padding-bottom:0.1rem;margin-right:1rem}html.theme--catppuccin-mocha #documenter .docs-main header.docs-navbar .docs-right{display:flex;white-space:nowrap;gap:1rem;align-items:center}html.theme--catppuccin-mocha #documenter .docs-main header.docs-navbar .docs-right .docs-icon,html.theme--catppuccin-mocha #documenter .docs-main header.docs-navbar .docs-right .docs-label{display:inline-block}html.theme--catppuccin-mocha #documenter .docs-main header.docs-navbar .docs-right .docs-label{padding:0;margin-left:0.3em}@media screen and (max-width: 1055px){html.theme--catppuccin-mocha #documenter .docs-main header.docs-navbar .docs-right .docs-navbar-link{margin-left:0.4rem;margin-right:0.4rem}}html.theme--catppuccin-mocha #documenter .docs-main header.docs-navbar>*{margin:auto 0}@media screen and (max-width: 1055px){html.theme--catppuccin-mocha #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--catppuccin-mocha #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--catppuccin-mocha #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--catppuccin-mocha #documenter .docs-main section.footnotes{border-top:1px solid #585b70}html.theme--catppuccin-mocha #documenter .docs-main section.footnotes li .tag:first-child,html.theme--catppuccin-mocha #documenter .docs-main section.footnotes li .docstring>section>a.docs-sourcelink:first-child,html.theme--catppuccin-mocha #documenter .docs-main section.footnotes li .content kbd:first-child,html.theme--catppuccin-mocha .content #documenter .docs-main section.footnotes li kbd:first-child{margin-right:1em;margin-bottom:0.4em}html.theme--catppuccin-mocha #documenter .docs-main .docs-footer{display:flex;flex-wrap:wrap;margin-left:0;margin-right:0;border-top:1px solid #585b70;padding-top:1rem;padding-bottom:1rem}@media screen and (max-width: 1055px){html.theme--catppuccin-mocha #documenter .docs-main .docs-footer{padding-left:1rem;padding-right:1rem}}html.theme--catppuccin-mocha #documenter .docs-main .docs-footer .docs-footer-nextpage,html.theme--catppuccin-mocha #documenter .docs-main .docs-footer .docs-footer-prevpage{flex-grow:1}html.theme--catppuccin-mocha #documenter .docs-main .docs-footer .docs-footer-nextpage{text-align:right}html.theme--catppuccin-mocha #documenter .docs-main .docs-footer .flexbox-break{flex-basis:100%;height:0}html.theme--catppuccin-mocha #documenter .docs-main .docs-footer .footer-message{font-size:0.8em;margin:0.5em auto 0 auto;text-align:center}html.theme--catppuccin-mocha #documenter .docs-sidebar{display:flex;flex-direction:column;color:#cdd6f4;background-color:#181825;border-right:1px solid #585b70;padding:0;flex:0 0 18rem;z-index:5;font-size:1rem;position:fixed;left:-18rem;width:18rem;height:100%;transition:left 0.3s}html.theme--catppuccin-mocha #documenter .docs-sidebar.visible{left:0;box-shadow:.4rem 0rem .8rem #171717}@media screen and (min-width: 1056px){html.theme--catppuccin-mocha #documenter .docs-sidebar.visible{box-shadow:none}}@media screen and (min-width: 1056px){html.theme--catppuccin-mocha #documenter .docs-sidebar{left:0;top:0}}html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo{margin-top:1rem;padding:0 1rem}html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img{max-height:6rem;margin:auto}html.theme--catppuccin-mocha #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--catppuccin-mocha #documenter .docs-sidebar .docs-package-name .docs-autofit{max-width:16.2rem}html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-package-name a,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-package-name a:hover{color:#cdd6f4}html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-version-selector{border-top:1px solid #585b70;display:none;padding:0.5rem}html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-version-selector.visible{display:flex}html.theme--catppuccin-mocha #documenter .docs-sidebar ul.docs-menu{flex-grow:1;user-select:none;border-top:1px solid #585b70;padding-bottom:1.5rem}html.theme--catppuccin-mocha #documenter .docs-sidebar ul.docs-menu>li>.tocitem{font-weight:bold}html.theme--catppuccin-mocha #documenter .docs-sidebar ul.docs-menu>li li{font-size:.95rem;margin-left:1em;border-left:1px solid #585b70}html.theme--catppuccin-mocha #documenter .docs-sidebar ul.docs-menu input.collapse-toggle{display:none}html.theme--catppuccin-mocha #documenter .docs-sidebar ul.docs-menu ul.collapsed{display:none}html.theme--catppuccin-mocha #documenter .docs-sidebar ul.docs-menu input:checked~ul.collapsed{display:block}html.theme--catppuccin-mocha #documenter .docs-sidebar ul.docs-menu label.tocitem{display:flex}html.theme--catppuccin-mocha #documenter .docs-sidebar ul.docs-menu label.tocitem .docs-label{flex-grow:2}html.theme--catppuccin-mocha #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}html.theme--catppuccin-mocha #documenter .docs-sidebar ul.docs-menu label.tocitem .docs-chevron::before{font-family:"Font Awesome 6 Free";font-weight:900;content:"\f054"}html.theme--catppuccin-mocha #documenter .docs-sidebar ul.docs-menu input:checked~label.tocitem .docs-chevron::before{content:"\f078"}html.theme--catppuccin-mocha #documenter .docs-sidebar ul.docs-menu .tocitem{display:block;padding:0.5rem 0.5rem}html.theme--catppuccin-mocha #documenter .docs-sidebar ul.docs-menu .tocitem,html.theme--catppuccin-mocha #documenter .docs-sidebar ul.docs-menu .tocitem:hover{color:#cdd6f4;background:#181825}html.theme--catppuccin-mocha #documenter .docs-sidebar ul.docs-menu a.tocitem:hover,html.theme--catppuccin-mocha #documenter .docs-sidebar ul.docs-menu label.tocitem:hover{color:#cdd6f4;background-color:#202031}html.theme--catppuccin-mocha #documenter .docs-sidebar ul.docs-menu li.is-active{border-top:1px solid #585b70;border-bottom:1px solid #585b70;background-color:#11111b}html.theme--catppuccin-mocha #documenter .docs-sidebar ul.docs-menu li.is-active .tocitem,html.theme--catppuccin-mocha #documenter .docs-sidebar ul.docs-menu li.is-active .tocitem:hover{background-color:#11111b;color:#cdd6f4}html.theme--catppuccin-mocha #documenter .docs-sidebar ul.docs-menu li.is-active ul.internal .tocitem:hover{background-color:#202031;color:#cdd6f4}html.theme--catppuccin-mocha #documenter .docs-sidebar ul.docs-menu>li.is-active:first-child{border-top:none}html.theme--catppuccin-mocha #documenter .docs-sidebar ul.docs-menu ul.internal{margin:0 0.5rem 0.5rem;border-top:1px solid #585b70}html.theme--catppuccin-mocha #documenter .docs-sidebar ul.docs-menu ul.internal li{font-size:.85rem;border-left:none;margin-left:0;margin-top:0.5rem}html.theme--catppuccin-mocha #documenter .docs-sidebar ul.docs-menu ul.internal .tocitem{width:100%;padding:0}html.theme--catppuccin-mocha #documenter .docs-sidebar ul.docs-menu ul.internal .tocitem::before{content:"⚬";margin-right:0.4em}html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search{margin:auto;margin-top:0.5rem;margin-bottom:0.5rem}html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input{width:14.4rem}html.theme--catppuccin-mocha #documenter .docs-sidebar #documenter-search-query{color:#868c98;width:14.4rem;box-shadow:inset 0 1px 2px rgba(10,10,10,0.1)}@media screen and (min-width: 1056px){html.theme--catppuccin-mocha #documenter .docs-sidebar ul.docs-menu{overflow-y:auto;-webkit-overflow-scroll:touch}html.theme--catppuccin-mocha #documenter .docs-sidebar ul.docs-menu::-webkit-scrollbar{width:.3rem;background:none}html.theme--catppuccin-mocha #documenter .docs-sidebar ul.docs-menu::-webkit-scrollbar-thumb{border-radius:5px 0px 0px 5px;background:#28283e}html.theme--catppuccin-mocha #documenter .docs-sidebar ul.docs-menu::-webkit-scrollbar-thumb:hover{background:#383856}}@media screen and (max-width: 1055px){html.theme--catppuccin-mocha #documenter .docs-sidebar{overflow-y:auto;-webkit-overflow-scroll:touch}html.theme--catppuccin-mocha #documenter .docs-sidebar::-webkit-scrollbar{width:.3rem;background:none}html.theme--catppuccin-mocha #documenter .docs-sidebar::-webkit-scrollbar-thumb{border-radius:5px 0px 0px 5px;background:#28283e}html.theme--catppuccin-mocha #documenter .docs-sidebar::-webkit-scrollbar-thumb:hover{background:#383856}}html.theme--catppuccin-mocha kbd.search-modal-key-hints{border-radius:0.25rem;border:1px solid rgba(245,245,245,0.6);box-shadow:0 2px 0 1px rgba(245,245,245,0.6);cursor:default;font-size:0.9rem;line-height:1.5;min-width:0.75rem;text-align:center;padding:0.1rem 0.3rem;position:relative;top:-1px}html.theme--catppuccin-mocha .search-min-width-50{min-width:50%}html.theme--catppuccin-mocha .search-min-height-100{min-height:100%}html.theme--catppuccin-mocha .search-modal-card-body{max-height:calc(100vh - 15rem)}html.theme--catppuccin-mocha .search-result-link{border-radius:0.7em;transition:all 300ms}html.theme--catppuccin-mocha .search-result-link:hover,html.theme--catppuccin-mocha .search-result-link:focus{background-color:rgba(0,128,128,0.1)}html.theme--catppuccin-mocha .search-result-link .property-search-result-badge,html.theme--catppuccin-mocha .search-result-link .search-filter{transition:all 300ms}html.theme--catppuccin-mocha .property-search-result-badge,html.theme--catppuccin-mocha .search-filter{padding:0.15em 0.5em;font-size:0.8em;font-style:italic;text-transform:none !important;line-height:1.5;color:#f5f5f5;background-color:rgba(51,65,85,0.501961);border-radius:0.6rem}html.theme--catppuccin-mocha .search-result-link:hover .property-search-result-badge,html.theme--catppuccin-mocha .search-result-link:hover .search-filter,html.theme--catppuccin-mocha .search-result-link:focus .property-search-result-badge,html.theme--catppuccin-mocha .search-result-link:focus .search-filter{color:#333;background-color:#f1f5f9}html.theme--catppuccin-mocha .search-filter{color:#333;background-color:#f5f5f5;transition:all 300ms}html.theme--catppuccin-mocha .search-filter:hover,html.theme--catppuccin-mocha .search-filter:focus{color:#333}html.theme--catppuccin-mocha .search-filter-selected{color:#313244;background-color:#b4befe}html.theme--catppuccin-mocha .search-filter-selected:hover,html.theme--catppuccin-mocha .search-filter-selected:focus{color:#313244}html.theme--catppuccin-mocha .search-result-highlight{background-color:#ffdd57;color:black}html.theme--catppuccin-mocha .search-divider{border-bottom:1px solid #585b70}html.theme--catppuccin-mocha .search-result-title{width:85%;color:#f5f5f5}html.theme--catppuccin-mocha .search-result-code-title{font-size:0.875rem;font-family:"JuliaMono","SFMono-Regular","Menlo","Consolas","Liberation Mono","DejaVu Sans Mono",monospace}html.theme--catppuccin-mocha #search-modal .modal-card-body::-webkit-scrollbar,html.theme--catppuccin-mocha #search-modal .filter-tabs::-webkit-scrollbar{height:10px;width:10px;background-color:transparent}html.theme--catppuccin-mocha #search-modal .modal-card-body::-webkit-scrollbar-thumb,html.theme--catppuccin-mocha #search-modal .filter-tabs::-webkit-scrollbar-thumb{background-color:gray;border-radius:1rem}html.theme--catppuccin-mocha #search-modal .modal-card-body::-webkit-scrollbar-track,html.theme--catppuccin-mocha #search-modal .filter-tabs::-webkit-scrollbar-track{-webkit-box-shadow:inset 0 0 6px rgba(0,0,0,0.6);background-color:transparent}html.theme--catppuccin-mocha .w-100{width:100%}html.theme--catppuccin-mocha .gap-2{gap:0.5rem}html.theme--catppuccin-mocha .gap-4{gap:1rem}html.theme--catppuccin-mocha .gap-8{gap:2rem}html.theme--catppuccin-mocha{background-color:#1e1e2e;font-size:16px;min-width:300px;overflow-x:auto;overflow-y:scroll;text-rendering:optimizeLegibility;text-size-adjust:100%}html.theme--catppuccin-mocha a{transition:all 200ms ease}html.theme--catppuccin-mocha .label{color:#cdd6f4}html.theme--catppuccin-mocha .button,html.theme--catppuccin-mocha .control.has-icons-left .icon,html.theme--catppuccin-mocha .control.has-icons-right .icon,html.theme--catppuccin-mocha .input,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input,html.theme--catppuccin-mocha .pagination-ellipsis,html.theme--catppuccin-mocha .pagination-link,html.theme--catppuccin-mocha .pagination-next,html.theme--catppuccin-mocha .pagination-previous,html.theme--catppuccin-mocha .select,html.theme--catppuccin-mocha .select select,html.theme--catppuccin-mocha .textarea{height:2.5em;color:#cdd6f4}html.theme--catppuccin-mocha .input,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input,html.theme--catppuccin-mocha .textarea{transition:all 200ms ease;box-shadow:none;border-width:1px;padding-left:1em;padding-right:1em;color:#cdd6f4}html.theme--catppuccin-mocha .select:after,html.theme--catppuccin-mocha .select select{border-width:1px}html.theme--catppuccin-mocha .menu-list a{transition:all 300ms ease}html.theme--catppuccin-mocha .modal-card-foot,html.theme--catppuccin-mocha .modal-card-head{border-color:#585b70}html.theme--catppuccin-mocha .navbar{border-radius:.4em}html.theme--catppuccin-mocha .navbar.is-transparent{background:none}html.theme--catppuccin-mocha .navbar.is-primary .navbar-dropdown a.navbar-item.is-active,html.theme--catppuccin-mocha .docstring>section>a.navbar.docs-sourcelink .navbar-dropdown a.navbar-item.is-active{background-color:#89b4fa}@media screen and (max-width: 1055px){html.theme--catppuccin-mocha .navbar .navbar-menu{background-color:#89b4fa;border-radius:0 0 .4em .4em}}html.theme--catppuccin-mocha .docstring>section>a.docs-sourcelink:not(body){color:#313244}html.theme--catppuccin-mocha .tag.is-link:not(body),html.theme--catppuccin-mocha .docstring>section>a.is-link.docs-sourcelink:not(body),html.theme--catppuccin-mocha .content kbd.is-link:not(body){color:#313244}html.theme--catppuccin-mocha .ansi span.sgr1{font-weight:bolder}html.theme--catppuccin-mocha .ansi span.sgr2{font-weight:lighter}html.theme--catppuccin-mocha .ansi span.sgr3{font-style:italic}html.theme--catppuccin-mocha .ansi span.sgr4{text-decoration:underline}html.theme--catppuccin-mocha .ansi span.sgr7{color:#1e1e2e;background-color:#cdd6f4}html.theme--catppuccin-mocha .ansi span.sgr8{color:transparent}html.theme--catppuccin-mocha .ansi span.sgr8 span{color:transparent}html.theme--catppuccin-mocha .ansi span.sgr9{text-decoration:line-through}html.theme--catppuccin-mocha .ansi span.sgr30{color:#45475a}html.theme--catppuccin-mocha .ansi span.sgr31{color:#f38ba8}html.theme--catppuccin-mocha .ansi span.sgr32{color:#a6e3a1}html.theme--catppuccin-mocha .ansi span.sgr33{color:#f9e2af}html.theme--catppuccin-mocha .ansi span.sgr34{color:#89b4fa}html.theme--catppuccin-mocha .ansi span.sgr35{color:#f5c2e7}html.theme--catppuccin-mocha .ansi span.sgr36{color:#94e2d5}html.theme--catppuccin-mocha .ansi span.sgr37{color:#bac2de}html.theme--catppuccin-mocha .ansi span.sgr40{background-color:#45475a}html.theme--catppuccin-mocha .ansi span.sgr41{background-color:#f38ba8}html.theme--catppuccin-mocha .ansi span.sgr42{background-color:#a6e3a1}html.theme--catppuccin-mocha .ansi span.sgr43{background-color:#f9e2af}html.theme--catppuccin-mocha .ansi span.sgr44{background-color:#89b4fa}html.theme--catppuccin-mocha .ansi span.sgr45{background-color:#f5c2e7}html.theme--catppuccin-mocha .ansi span.sgr46{background-color:#94e2d5}html.theme--catppuccin-mocha .ansi span.sgr47{background-color:#bac2de}html.theme--catppuccin-mocha .ansi span.sgr90{color:#585b70}html.theme--catppuccin-mocha .ansi span.sgr91{color:#f38ba8}html.theme--catppuccin-mocha .ansi span.sgr92{color:#a6e3a1}html.theme--catppuccin-mocha .ansi span.sgr93{color:#f9e2af}html.theme--catppuccin-mocha .ansi span.sgr94{color:#89b4fa}html.theme--catppuccin-mocha .ansi span.sgr95{color:#f5c2e7}html.theme--catppuccin-mocha .ansi span.sgr96{color:#94e2d5}html.theme--catppuccin-mocha .ansi span.sgr97{color:#a6adc8}html.theme--catppuccin-mocha .ansi span.sgr100{background-color:#585b70}html.theme--catppuccin-mocha .ansi span.sgr101{background-color:#f38ba8}html.theme--catppuccin-mocha .ansi span.sgr102{background-color:#a6e3a1}html.theme--catppuccin-mocha .ansi span.sgr103{background-color:#f9e2af}html.theme--catppuccin-mocha .ansi span.sgr104{background-color:#89b4fa}html.theme--catppuccin-mocha .ansi span.sgr105{background-color:#f5c2e7}html.theme--catppuccin-mocha .ansi span.sgr106{background-color:#94e2d5}html.theme--catppuccin-mocha .ansi span.sgr107{background-color:#a6adc8}html.theme--catppuccin-mocha code.language-julia-repl>span.hljs-meta{color:#a6e3a1;font-weight:bolder}html.theme--catppuccin-mocha code .hljs{color:#cdd6f4;background:#1e1e2e}html.theme--catppuccin-mocha code .hljs-keyword{color:#cba6f7}html.theme--catppuccin-mocha code .hljs-built_in{color:#f38ba8}html.theme--catppuccin-mocha code .hljs-type{color:#f9e2af}html.theme--catppuccin-mocha code .hljs-literal{color:#fab387}html.theme--catppuccin-mocha code .hljs-number{color:#fab387}html.theme--catppuccin-mocha code .hljs-operator{color:#94e2d5}html.theme--catppuccin-mocha code .hljs-punctuation{color:#bac2de}html.theme--catppuccin-mocha code .hljs-property{color:#94e2d5}html.theme--catppuccin-mocha code .hljs-regexp{color:#f5c2e7}html.theme--catppuccin-mocha code .hljs-string{color:#a6e3a1}html.theme--catppuccin-mocha code .hljs-char.escape_{color:#a6e3a1}html.theme--catppuccin-mocha code .hljs-subst{color:#a6adc8}html.theme--catppuccin-mocha code .hljs-symbol{color:#f2cdcd}html.theme--catppuccin-mocha code .hljs-variable{color:#cba6f7}html.theme--catppuccin-mocha code .hljs-variable.language_{color:#cba6f7}html.theme--catppuccin-mocha code .hljs-variable.constant_{color:#fab387}html.theme--catppuccin-mocha code .hljs-title{color:#89b4fa}html.theme--catppuccin-mocha code .hljs-title.class_{color:#f9e2af}html.theme--catppuccin-mocha code .hljs-title.function_{color:#89b4fa}html.theme--catppuccin-mocha code .hljs-params{color:#cdd6f4}html.theme--catppuccin-mocha code .hljs-comment{color:#585b70}html.theme--catppuccin-mocha code .hljs-doctag{color:#f38ba8}html.theme--catppuccin-mocha code .hljs-meta{color:#fab387}html.theme--catppuccin-mocha code .hljs-section{color:#89b4fa}html.theme--catppuccin-mocha code .hljs-tag{color:#a6adc8}html.theme--catppuccin-mocha code .hljs-name{color:#cba6f7}html.theme--catppuccin-mocha code .hljs-attr{color:#89b4fa}html.theme--catppuccin-mocha code .hljs-attribute{color:#a6e3a1}html.theme--catppuccin-mocha code .hljs-bullet{color:#94e2d5}html.theme--catppuccin-mocha code .hljs-code{color:#a6e3a1}html.theme--catppuccin-mocha code .hljs-emphasis{color:#f38ba8;font-style:italic}html.theme--catppuccin-mocha code .hljs-strong{color:#f38ba8;font-weight:bold}html.theme--catppuccin-mocha code .hljs-formula{color:#94e2d5}html.theme--catppuccin-mocha code .hljs-link{color:#74c7ec;font-style:italic}html.theme--catppuccin-mocha code .hljs-quote{color:#a6e3a1;font-style:italic}html.theme--catppuccin-mocha code .hljs-selector-tag{color:#f9e2af}html.theme--catppuccin-mocha code .hljs-selector-id{color:#89b4fa}html.theme--catppuccin-mocha code .hljs-selector-class{color:#94e2d5}html.theme--catppuccin-mocha code .hljs-selector-attr{color:#cba6f7}html.theme--catppuccin-mocha code .hljs-selector-pseudo{color:#94e2d5}html.theme--catppuccin-mocha code .hljs-template-tag{color:#f2cdcd}html.theme--catppuccin-mocha code .hljs-template-variable{color:#f2cdcd}html.theme--catppuccin-mocha code .hljs-addition{color:#a6e3a1;background:rgba(166,227,161,0.15)}html.theme--catppuccin-mocha code .hljs-deletion{color:#f38ba8;background:rgba(243,139,168,0.15)}html.theme--catppuccin-mocha .search-result-link{border-radius:0.7em;transition:all 300ms}html.theme--catppuccin-mocha .search-result-link:hover,html.theme--catppuccin-mocha .search-result-link:focus{background-color:#313244}html.theme--catppuccin-mocha .search-result-link .property-search-result-badge,html.theme--catppuccin-mocha .search-result-link .search-filter{transition:all 300ms}html.theme--catppuccin-mocha .search-result-link:hover .property-search-result-badge,html.theme--catppuccin-mocha .search-result-link:hover .search-filter,html.theme--catppuccin-mocha .search-result-link:focus .property-search-result-badge,html.theme--catppuccin-mocha .search-result-link:focus .search-filter{color:#313244 !important;background-color:#b4befe !important}html.theme--catppuccin-mocha .search-result-title{color:#cdd6f4}html.theme--catppuccin-mocha .search-result-highlight{background-color:#f38ba8;color:#181825}html.theme--catppuccin-mocha .search-divider{border-bottom:1px solid #5e6d6f50}html.theme--catppuccin-mocha .w-100{width:100%}html.theme--catppuccin-mocha .gap-2{gap:0.5rem}html.theme--catppuccin-mocha .gap-4{gap:1rem} diff --git a/previews/PR4245/assets/themes/documenter-dark.css b/previews/PR4245/assets/themes/documenter-dark.css deleted file mode 100644 index c41c82f25adc..000000000000 --- a/previews/PR4245/assets/themes/documenter-dark.css +++ /dev/null @@ -1,7 +0,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:1rem;height:2.5em;justify-content:flex-start;line-height:1.5;padding-bottom:calc(0.5em - 1px);padding-left:calc(0.75em - 1px);padding-right:calc(0.75em - 1px);padding-top:calc(0.5em - 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}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{-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 .pagination:not(:last-child),html.theme--documenter-dark .message:not(:last-child),html.theme--documenter-dark .level:not(:last-child),html.theme--documenter-dark .breadcrumb: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{-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-moz-appearance:none;-webkit-appearance:none;background-color:rgba(10,10,10,0.2);border:none;border-radius:9999px;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:9999px;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 .navbar-burger{-moz-appearance:none;-webkit-appearance:none;appearance:none;background:none;border:none;color:currentColor;font-family:inherit;font-size:1em;margin:0;padding:0}/*! minireset.css v0.0.6 | 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,video{height:auto;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:inherit}.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-primary-light{color:#f1f5f9 !important}a.has-text-primary-light:hover,a.has-text-primary-light:focus{color:#cddbe9 !important}.has-background-primary-light{background-color:#f1f5f9 !important}.has-text-primary-dark{color:#4d7eb2 !important}a.has-text-primary-dark:hover,a.has-text-primary-dark:focus{color:#7198c1 !important}.has-background-primary-dark{background-color:#4d7eb2 !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-link-light{color:#edfdf9 !important}a.has-text-link-light:hover,a.has-text-link-light:focus{color:#c0f6ec !important}.has-background-link-light{background-color:#edfdf9 !important}.has-text-link-dark{color:#15987e !important}a.has-text-link-dark:hover,a.has-text-link-dark:focus{color:#1bc5a4 !important}.has-background-link-dark{background-color:#15987e !important}.has-text-info{color:#3c5dcd !important}a.has-text-info:hover,a.has-text-info:focus{color:#2c48aa !important}.has-background-info{background-color:#3c5dcd !important}.has-text-info-light{color:#eff2fb !important}a.has-text-info-light:hover,a.has-text-info-light:focus{color:#c6d0f0 !important}.has-background-info-light{background-color:#eff2fb !important}.has-text-info-dark{color:#3253c3 !important}a.has-text-info-dark:hover,a.has-text-info-dark:focus{color:#5571d3 !important}.has-background-info-dark{background-color:#3253c3 !important}.has-text-success{color:#259a12 !important}a.has-text-success:hover,a.has-text-success:focus{color:#1a6c0d !important}.has-background-success{background-color:#259a12 !important}.has-text-success-light{color:#effded !important}a.has-text-success-light:hover,a.has-text-success-light:focus{color:#c7f8bf !important}.has-background-success-light{background-color:#effded !important}.has-text-success-dark{color:#2ec016 !important}a.has-text-success-dark:hover,a.has-text-success-dark:focus{color:#3fe524 !important}.has-background-success-dark{background-color:#2ec016 !important}.has-text-warning{color:#f4c72f !important}a.has-text-warning:hover,a.has-text-warning:focus{color:#e4b30c !important}.has-background-warning{background-color:#f4c72f !important}.has-text-warning-light{color:#fefaec !important}a.has-text-warning-light:hover,a.has-text-warning-light:focus{color:#fbedbb !important}.has-background-warning-light{background-color:#fefaec !important}.has-text-warning-dark{color:#8c6e07 !important}a.has-text-warning-dark:hover,a.has-text-warning-dark:focus{color:#bd940a !important}.has-background-warning-dark{background-color:#8c6e07 !important}.has-text-danger{color:#cb3c33 !important}a.has-text-danger:hover,a.has-text-danger:focus{color:#a23029 !important}.has-background-danger{background-color:#cb3c33 !important}.has-text-danger-light{color:#fbefef !important}a.has-text-danger-light:hover,a.has-text-danger-light:focus{color:#f1c8c6 !important}.has-background-danger-light{background-color:#fbefef !important}.has-text-danger-dark{color:#c03930 !important}a.has-text-danger-dark:hover,a.has-text-danger-dark:focus{color:#d35850 !important}.has-background-danger-dark{background-color:#c03930 !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}.is-flex-direction-row{flex-direction:row !important}.is-flex-direction-row-reverse{flex-direction:row-reverse !important}.is-flex-direction-column{flex-direction:column !important}.is-flex-direction-column-reverse{flex-direction:column-reverse !important}.is-flex-wrap-nowrap{flex-wrap:nowrap !important}.is-flex-wrap-wrap{flex-wrap:wrap !important}.is-flex-wrap-wrap-reverse{flex-wrap:wrap-reverse !important}.is-justify-content-flex-start{justify-content:flex-start !important}.is-justify-content-flex-end{justify-content:flex-end !important}.is-justify-content-center{justify-content:center !important}.is-justify-content-space-between{justify-content:space-between !important}.is-justify-content-space-around{justify-content:space-around !important}.is-justify-content-space-evenly{justify-content:space-evenly !important}.is-justify-content-start{justify-content:start !important}.is-justify-content-end{justify-content:end !important}.is-justify-content-left{justify-content:left !important}.is-justify-content-right{justify-content:right !important}.is-align-content-flex-start{align-content:flex-start !important}.is-align-content-flex-end{align-content:flex-end !important}.is-align-content-center{align-content:center !important}.is-align-content-space-between{align-content:space-between !important}.is-align-content-space-around{align-content:space-around !important}.is-align-content-space-evenly{align-content:space-evenly !important}.is-align-content-stretch{align-content:stretch !important}.is-align-content-start{align-content:start !important}.is-align-content-end{align-content:end !important}.is-align-content-baseline{align-content:baseline !important}.is-align-items-stretch{align-items:stretch !important}.is-align-items-flex-start{align-items:flex-start !important}.is-align-items-flex-end{align-items:flex-end !important}.is-align-items-center{align-items:center !important}.is-align-items-baseline{align-items:baseline !important}.is-align-items-start{align-items:start !important}.is-align-items-end{align-items:end !important}.is-align-items-self-start{align-items:self-start !important}.is-align-items-self-end{align-items:self-end !important}.is-align-self-auto{align-self:auto !important}.is-align-self-flex-start{align-self:flex-start !important}.is-align-self-flex-end{align-self:flex-end !important}.is-align-self-center{align-self:center !important}.is-align-self-baseline{align-self:baseline !important}.is-align-self-stretch{align-self:stretch !important}.is-flex-grow-0{flex-grow:0 !important}.is-flex-grow-1{flex-grow:1 !important}.is-flex-grow-2{flex-grow:2 !important}.is-flex-grow-3{flex-grow:3 !important}.is-flex-grow-4{flex-grow:4 !important}.is-flex-grow-5{flex-grow:5 !important}.is-flex-shrink-0{flex-shrink:0 !important}.is-flex-shrink-1{flex-shrink:1 !important}.is-flex-shrink-2{flex-shrink:2 !important}.is-flex-shrink-3{flex-shrink:3 !important}.is-flex-shrink-4{flex-shrink:4 !important}.is-flex-shrink-5{flex-shrink:5 !important}.is-clearfix::after{clear:both;content:" ";display:table}.is-pulled-left{float:left !important}.is-pulled-right{float:right !important}.is-radiusless{border-radius:0 !important}.is-shadowless{box-shadow:none !important}.is-clickable{cursor:pointer !important;pointer-events:all !important}.is-clipped{overflow:hidden !important}.is-relative{position:relative !important}.is-marginless{margin:0 !important}.is-paddingless{padding:0 !important}.m-0{margin:0 !important}.mt-0{margin-top:0 !important}.mr-0{margin-right:0 !important}.mb-0{margin-bottom:0 !important}.ml-0{margin-left:0 !important}.mx-0{margin-left:0 !important;margin-right:0 !important}.my-0{margin-top:0 !important;margin-bottom:0 !important}.m-1{margin:.25rem !important}.mt-1{margin-top:.25rem !important}.mr-1{margin-right:.25rem !important}.mb-1{margin-bottom:.25rem !important}.ml-1{margin-left:.25rem !important}.mx-1{margin-left:.25rem !important;margin-right:.25rem !important}.my-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.m-2{margin:.5rem !important}.mt-2{margin-top:.5rem !important}.mr-2{margin-right:.5rem !important}.mb-2{margin-bottom:.5rem !important}.ml-2{margin-left:.5rem !important}.mx-2{margin-left:.5rem !important;margin-right:.5rem !important}.my-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.m-3{margin:.75rem !important}.mt-3{margin-top:.75rem !important}.mr-3{margin-right:.75rem !important}.mb-3{margin-bottom:.75rem !important}.ml-3{margin-left:.75rem !important}.mx-3{margin-left:.75rem !important;margin-right:.75rem !important}.my-3{margin-top:.75rem !important;margin-bottom:.75rem !important}.m-4{margin:1rem !important}.mt-4{margin-top:1rem !important}.mr-4{margin-right:1rem !important}.mb-4{margin-bottom:1rem !important}.ml-4{margin-left:1rem !important}.mx-4{margin-left:1rem !important;margin-right:1rem !important}.my-4{margin-top:1rem !important;margin-bottom:1rem !important}.m-5{margin:1.5rem !important}.mt-5{margin-top:1.5rem !important}.mr-5{margin-right:1.5rem !important}.mb-5{margin-bottom:1.5rem !important}.ml-5{margin-left:1.5rem !important}.mx-5{margin-left:1.5rem !important;margin-right:1.5rem !important}.my-5{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.m-6{margin:3rem !important}.mt-6{margin-top:3rem !important}.mr-6{margin-right:3rem !important}.mb-6{margin-bottom:3rem !important}.ml-6{margin-left:3rem !important}.mx-6{margin-left:3rem !important;margin-right:3rem !important}.my-6{margin-top:3rem !important;margin-bottom:3rem !important}.m-auto{margin:auto !important}.mt-auto{margin-top:auto !important}.mr-auto{margin-right:auto !important}.mb-auto{margin-bottom:auto !important}.ml-auto{margin-left:auto !important}.mx-auto{margin-left:auto !important;margin-right:auto !important}.my-auto{margin-top:auto !important;margin-bottom:auto !important}.p-0{padding:0 !important}.pt-0{padding-top:0 !important}.pr-0{padding-right:0 !important}.pb-0{padding-bottom:0 !important}.pl-0{padding-left:0 !important}.px-0{padding-left:0 !important;padding-right:0 !important}.py-0{padding-top:0 !important;padding-bottom:0 !important}.p-1{padding:.25rem !important}.pt-1{padding-top:.25rem !important}.pr-1{padding-right:.25rem !important}.pb-1{padding-bottom:.25rem !important}.pl-1{padding-left:.25rem !important}.px-1{padding-left:.25rem !important;padding-right:.25rem !important}.py-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.p-2{padding:.5rem !important}.pt-2{padding-top:.5rem !important}.pr-2{padding-right:.5rem !important}.pb-2{padding-bottom:.5rem !important}.pl-2{padding-left:.5rem !important}.px-2{padding-left:.5rem !important;padding-right:.5rem !important}.py-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.p-3{padding:.75rem !important}.pt-3{padding-top:.75rem !important}.pr-3{padding-right:.75rem !important}.pb-3{padding-bottom:.75rem !important}.pl-3{padding-left:.75rem !important}.px-3{padding-left:.75rem !important;padding-right:.75rem !important}.py-3{padding-top:.75rem !important;padding-bottom:.75rem !important}.p-4{padding:1rem !important}.pt-4{padding-top:1rem !important}.pr-4{padding-right:1rem !important}.pb-4{padding-bottom:1rem !important}.pl-4{padding-left:1rem !important}.px-4{padding-left:1rem !important;padding-right:1rem !important}.py-4{padding-top:1rem !important;padding-bottom:1rem !important}.p-5{padding:1.5rem !important}.pt-5{padding-top:1.5rem !important}.pr-5{padding-right:1.5rem !important}.pb-5{padding-bottom:1.5rem !important}.pl-5{padding-left:1.5rem !important}.px-5{padding-left:1.5rem !important;padding-right:1.5rem !important}.py-5{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.p-6{padding:3rem !important}.pt-6{padding-top:3rem !important}.pr-6{padding-right:3rem !important}.pb-6{padding-bottom:3rem !important}.pl-6{padding-left:3rem !important}.px-6{padding-left:3rem !important;padding-right:3rem !important}.py-6{padding-top:3rem !important;padding-bottom:3rem !important}.p-auto{padding:auto !important}.pt-auto{padding-top:auto !important}.pr-auto{padding-right:auto !important}.pb-auto{padding-bottom:auto !important}.pl-auto{padding-left:auto !important}.px-auto{padding-left:auto !important;padding-right:auto !important}.py-auto{padding-top:auto !important;padding-bottom:auto !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,html.theme--documenter-dark .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}.is-underlined{text-decoration:underline !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}}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 optgroup,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:inherit}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 0.5em 1em -0.125em 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.5em - 1px);padding-left:1em;padding-right:1em;padding-top:calc(0.5em - 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.5em - 1px);margin-right:.25em}html.theme--documenter-dark .button .icon:last-child:not(:first-child){margin-left:.25em;margin-right:calc(-0.5em - 1px)}html.theme--documenter-dark .button .icon:first-child:last-child{margin-left:calc(-0.5em - 1px);margin-right:calc(-0.5em - 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-ghost{background:none;border-color:rgba(0,0,0,0);color:#1abc9c;text-decoration:none}html.theme--documenter-dark .button.is-ghost:hover,html.theme--documenter-dark .button.is-ghost.is-hovered{color:#1abc9c;text-decoration:underline}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:#fff;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:#0a0a0a;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:rgba(0,0,0,0.7)}html.theme--documenter-dark .button.is-light:hover,html.theme--documenter-dark .button.is-light.is-hovered{background-color:#e5eaec;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--documenter-dark .button.is-light:focus,html.theme--documenter-dark .button.is-light.is-focused{border-color:transparent;color:rgba(0,0,0,0.7)}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:rgba(0,0,0,0.7)}html.theme--documenter-dark .button.is-light[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-light{background-color:#ecf0f1;border-color:#ecf0f1;box-shadow:none}html.theme--documenter-dark .button.is-light.is-inverted{background-color:rgba(0,0,0,0.7);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:rgba(0,0,0,0.7)}html.theme--documenter-dark .button.is-light.is-inverted[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-light.is-inverted{background-color:rgba(0,0,0,0.7);border-color:transparent;box-shadow:none;color:#ecf0f1}html.theme--documenter-dark .button.is-light.is-loading::after{border-color:transparent transparent rgba(0,0,0,0.7) rgba(0,0,0,0.7) !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:rgba(0,0,0,0.7)}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 rgba(0,0,0,0.7) rgba(0,0,0,0.7) !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:rgba(0,0,0,0.7);color:rgba(0,0,0,0.7)}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:rgba(0,0,0,0.7);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:rgba(0,0,0,0.7);box-shadow:none;color:rgba(0,0,0,0.7)}html.theme--documenter-dark .button.is-dark,html.theme--documenter-dark .content kbd.button{background-color:#282f2f;border-color:transparent;color:#fff}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:#fff}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:#fff}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:#fff}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:#282f2f;box-shadow:none}html.theme--documenter-dark .button.is-dark.is-inverted,html.theme--documenter-dark .content kbd.button.is-inverted{background-color:#fff;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:#f2f2f2}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:#fff;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 #fff #fff !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:#fff}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 #fff #fff !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:#fff;color:#fff}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:#fff;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:#fff;box-shadow:none;color:#fff}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:#375a7f;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-primary.is-light,html.theme--documenter-dark .docstring>section>a.button.is-light.docs-sourcelink{background-color:#f1f5f9;color:#4d7eb2}html.theme--documenter-dark .button.is-primary.is-light:hover,html.theme--documenter-dark .docstring>section>a.button.is-light.docs-sourcelink:hover,html.theme--documenter-dark .button.is-primary.is-light.is-hovered,html.theme--documenter-dark .docstring>section>a.button.is-light.is-hovered.docs-sourcelink{background-color:#e8eef5;border-color:transparent;color:#4d7eb2}html.theme--documenter-dark .button.is-primary.is-light:active,html.theme--documenter-dark .docstring>section>a.button.is-light.docs-sourcelink:active,html.theme--documenter-dark .button.is-primary.is-light.is-active,html.theme--documenter-dark .docstring>section>a.button.is-light.is-active.docs-sourcelink{background-color:#dfe8f1;border-color:transparent;color:#4d7eb2}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:#1abc9c;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-link.is-light{background-color:#edfdf9;color:#15987e}html.theme--documenter-dark .button.is-link.is-light:hover,html.theme--documenter-dark .button.is-link.is-light.is-hovered{background-color:#e2fbf6;border-color:transparent;color:#15987e}html.theme--documenter-dark .button.is-link.is-light:active,html.theme--documenter-dark .button.is-link.is-light.is-active{background-color:#d7f9f3;border-color:transparent;color:#15987e}html.theme--documenter-dark .button.is-info{background-color:#3c5dcd;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-info:hover,html.theme--documenter-dark .button.is-info.is-hovered{background-color:#3355c9;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(60,93,205,0.25)}html.theme--documenter-dark .button.is-info:active,html.theme--documenter-dark .button.is-info.is-active{background-color:#3151bf;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-info[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-info{background-color:#3c5dcd;border-color:#3c5dcd;box-shadow:none}html.theme--documenter-dark .button.is-info.is-inverted{background-color:#fff;color:#3c5dcd}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:#3c5dcd}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:#3c5dcd;color:#3c5dcd}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:#3c5dcd;border-color:#3c5dcd;color:#fff}html.theme--documenter-dark .button.is-info.is-outlined.is-loading::after{border-color:transparent transparent #3c5dcd #3c5dcd !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:#3c5dcd;box-shadow:none;color:#3c5dcd}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:#3c5dcd}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 #3c5dcd #3c5dcd !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-info.is-light{background-color:#eff2fb;color:#3253c3}html.theme--documenter-dark .button.is-info.is-light:hover,html.theme--documenter-dark .button.is-info.is-light.is-hovered{background-color:#e5e9f8;border-color:transparent;color:#3253c3}html.theme--documenter-dark .button.is-info.is-light:active,html.theme--documenter-dark .button.is-info.is-light.is-active{background-color:#dae1f6;border-color:transparent;color:#3253c3}html.theme--documenter-dark .button.is-success{background-color:#259a12;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-success:hover,html.theme--documenter-dark .button.is-success.is-hovered{background-color:#228f11;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(37,154,18,0.25)}html.theme--documenter-dark .button.is-success:active,html.theme--documenter-dark .button.is-success.is-active{background-color:#20830f;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-success[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-success{background-color:#259a12;border-color:#259a12;box-shadow:none}html.theme--documenter-dark .button.is-success.is-inverted{background-color:#fff;color:#259a12}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:#259a12}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:#259a12;color:#259a12}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:#259a12;border-color:#259a12;color:#fff}html.theme--documenter-dark .button.is-success.is-outlined.is-loading::after{border-color:transparent transparent #259a12 #259a12 !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:#259a12;box-shadow:none;color:#259a12}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:#259a12}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 #259a12 #259a12 !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-success.is-light{background-color:#effded;color:#2ec016}html.theme--documenter-dark .button.is-success.is-light:hover,html.theme--documenter-dark .button.is-success.is-light.is-hovered{background-color:#e5fce1;border-color:transparent;color:#2ec016}html.theme--documenter-dark .button.is-success.is-light:active,html.theme--documenter-dark .button.is-success.is-light.is-active{background-color:#dbfad6;border-color:transparent;color:#2ec016}html.theme--documenter-dark .button.is-warning{background-color:#f4c72f;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--documenter-dark .button.is-warning:hover,html.theme--documenter-dark .button.is-warning.is-hovered{background-color:#f3c423;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--documenter-dark .button.is-warning:focus,html.theme--documenter-dark .button.is-warning.is-focused{border-color:transparent;color:rgba(0,0,0,0.7)}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(244,199,47,0.25)}html.theme--documenter-dark .button.is-warning:active,html.theme--documenter-dark .button.is-warning.is-active{background-color:#f3c017;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--documenter-dark .button.is-warning[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-warning{background-color:#f4c72f;border-color:#f4c72f;box-shadow:none}html.theme--documenter-dark .button.is-warning.is-inverted{background-color:rgba(0,0,0,0.7);color:#f4c72f}html.theme--documenter-dark .button.is-warning.is-inverted:hover,html.theme--documenter-dark .button.is-warning.is-inverted.is-hovered{background-color:rgba(0,0,0,0.7)}html.theme--documenter-dark .button.is-warning.is-inverted[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-warning.is-inverted{background-color:rgba(0,0,0,0.7);border-color:transparent;box-shadow:none;color:#f4c72f}html.theme--documenter-dark .button.is-warning.is-loading::after{border-color:transparent transparent rgba(0,0,0,0.7) rgba(0,0,0,0.7) !important}html.theme--documenter-dark .button.is-warning.is-outlined{background-color:transparent;border-color:#f4c72f;color:#f4c72f}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:#f4c72f;border-color:#f4c72f;color:rgba(0,0,0,0.7)}html.theme--documenter-dark .button.is-warning.is-outlined.is-loading::after{border-color:transparent transparent #f4c72f #f4c72f !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 rgba(0,0,0,0.7) rgba(0,0,0,0.7) !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:#f4c72f;box-shadow:none;color:#f4c72f}html.theme--documenter-dark .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)}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:rgba(0,0,0,0.7);color:#f4c72f}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 #f4c72f #f4c72f !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:rgba(0,0,0,0.7);box-shadow:none;color:rgba(0,0,0,0.7)}html.theme--documenter-dark .button.is-warning.is-light{background-color:#fefaec;color:#8c6e07}html.theme--documenter-dark .button.is-warning.is-light:hover,html.theme--documenter-dark .button.is-warning.is-light.is-hovered{background-color:#fdf7e0;border-color:transparent;color:#8c6e07}html.theme--documenter-dark .button.is-warning.is-light:active,html.theme--documenter-dark .button.is-warning.is-light.is-active{background-color:#fdf3d3;border-color:transparent;color:#8c6e07}html.theme--documenter-dark .button.is-danger{background-color:#cb3c33;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-danger:hover,html.theme--documenter-dark .button.is-danger.is-hovered{background-color:#c13930;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(203,60,51,0.25)}html.theme--documenter-dark .button.is-danger:active,html.theme--documenter-dark .button.is-danger.is-active{background-color:#b7362e;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-danger[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-danger{background-color:#cb3c33;border-color:#cb3c33;box-shadow:none}html.theme--documenter-dark .button.is-danger.is-inverted{background-color:#fff;color:#cb3c33}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:#cb3c33}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:#cb3c33;color:#cb3c33}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:#cb3c33;border-color:#cb3c33;color:#fff}html.theme--documenter-dark .button.is-danger.is-outlined.is-loading::after{border-color:transparent transparent #cb3c33 #cb3c33 !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:#cb3c33;box-shadow:none;color:#cb3c33}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:#cb3c33}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 #cb3c33 #cb3c33 !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-danger.is-light{background-color:#fbefef;color:#c03930}html.theme--documenter-dark .button.is-danger.is-light:hover,html.theme--documenter-dark .button.is-danger.is-light.is-hovered{background-color:#f8e6e5;border-color:transparent;color:#c03930}html.theme--documenter-dark .button.is-danger.is-light:active,html.theme--documenter-dark .button.is-danger.is-light.is-active{background-color:#f6dcda;border-color:transparent;color:#c03930}html.theme--documenter-dark .button.is-small,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.button{font-size:.75rem}html.theme--documenter-dark .button.is-small:not(.is-rounded),html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.button:not(.is-rounded){border-radius:3px}html.theme--documenter-dark .button.is-normal{font-size:1rem}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:#5e6d6f;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 * 0.5));top:calc(50% - (1em * 0.5));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:9999px;padding-left:calc(1em + 0.25em);padding-right:calc(1em + 0.25em)}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:.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){font-size:.75rem}html.theme--documenter-dark .buttons.are-small .button:not(.is-normal):not(.is-medium):not(.is-large):not(.is-rounded){border-radius:3px}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}@media screen and (max-width: 768px){html.theme--documenter-dark .button.is-responsive.is-small,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-responsive{font-size:.5625rem}html.theme--documenter-dark .button.is-responsive,html.theme--documenter-dark .button.is-responsive.is-normal{font-size:.65625rem}html.theme--documenter-dark .button.is-responsive.is-medium{font-size:.75rem}html.theme--documenter-dark .button.is-responsive.is-large{font-size:1rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--documenter-dark .button.is-responsive.is-small,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-responsive{font-size:.65625rem}html.theme--documenter-dark .button.is-responsive,html.theme--documenter-dark .button.is-responsive.is-normal{font-size:.75rem}html.theme--documenter-dark .button.is-responsive.is-medium{font-size:1rem}html.theme--documenter-dark .button.is-responsive.is-large{font-size:1.25rem}}html.theme--documenter-dark .container{flex-grow:1;margin:0 auto;position:relative;width:auto}html.theme--documenter-dark .container.is-fluid{max-width:none !important;padding-left:32px;padding-right:32px;width:100%}@media screen and (min-width: 1056px){html.theme--documenter-dark .container{max-width:992px}}@media screen and (max-width: 1215px){html.theme--documenter-dark .container.is-widescreen:not(.is-max-desktop){max-width:1152px}}@media screen and (max-width: 1407px){html.theme--documenter-dark .container.is-fullhd:not(.is-max-desktop):not(.is-max-widescreen){max-width:1344px}}@media screen and (min-width: 1216px){html.theme--documenter-dark .container:not(.is-max-desktop){max-width:1152px}}@media screen and (min-width: 1408px){html.theme--documenter-dark .container:not(.is-max-desktop):not(.is-max-widescreen){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:inherit}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:.75rem}html.theme--documenter-dark .content.is-normal{font-size:1rem}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 .icon-text{align-items:flex-start;color:inherit;display:inline-flex;flex-wrap:wrap;line-height:1.5rem;vertical-align:top}html.theme--documenter-dark .icon-text .icon{flex-grow:0;flex-shrink:0}html.theme--documenter-dark .icon-text .icon:not(:last-child){margin-right:.25em}html.theme--documenter-dark .icon-text .icon:not(:first-child){margin-left:.25em}html.theme--documenter-dark div.icon-text{display:flex}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:9999px}html.theme--documenter-dark .image.is-fullwidth,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-fullwidth{width:100%}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;position:relative;padding:1.25rem 2.5rem 1.25rem 1.5rem}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{right:.5rem;position:absolute;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:rgba(0,0,0,0.7)}html.theme--documenter-dark .notification.is-dark,html.theme--documenter-dark .content kbd.notification{background-color:#282f2f;color:#fff}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-primary.is-light,html.theme--documenter-dark .docstring>section>a.notification.is-light.docs-sourcelink{background-color:#f1f5f9;color:#4d7eb2}html.theme--documenter-dark .notification.is-link{background-color:#1abc9c;color:#fff}html.theme--documenter-dark .notification.is-link.is-light{background-color:#edfdf9;color:#15987e}html.theme--documenter-dark .notification.is-info{background-color:#3c5dcd;color:#fff}html.theme--documenter-dark .notification.is-info.is-light{background-color:#eff2fb;color:#3253c3}html.theme--documenter-dark .notification.is-success{background-color:#259a12;color:#fff}html.theme--documenter-dark .notification.is-success.is-light{background-color:#effded;color:#2ec016}html.theme--documenter-dark .notification.is-warning{background-color:#f4c72f;color:rgba(0,0,0,0.7)}html.theme--documenter-dark .notification.is-warning.is-light{background-color:#fefaec;color:#8c6e07}html.theme--documenter-dark .notification.is-danger{background-color:#cb3c33;color:#fff}html.theme--documenter-dark .notification.is-danger.is-light{background-color:#fbefef;color:#c03930}html.theme--documenter-dark .progress{-moz-appearance:none;-webkit-appearance:none;border:none;border-radius:9999px;display:block;height:1rem;overflow:hidden;padding:0;width:100%}html.theme--documenter-dark .progress::-webkit-progress-bar{background-color:#343c3d}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%, #343c3d 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%, #343c3d 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%, #343c3d 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%, #343c3d 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%, #343c3d 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%, #343c3d 30%)}html.theme--documenter-dark .progress.is-info::-webkit-progress-value{background-color:#3c5dcd}html.theme--documenter-dark .progress.is-info::-moz-progress-bar{background-color:#3c5dcd}html.theme--documenter-dark .progress.is-info::-ms-fill{background-color:#3c5dcd}html.theme--documenter-dark .progress.is-info:indeterminate{background-image:linear-gradient(to right, #3c5dcd 30%, #343c3d 30%)}html.theme--documenter-dark .progress.is-success::-webkit-progress-value{background-color:#259a12}html.theme--documenter-dark .progress.is-success::-moz-progress-bar{background-color:#259a12}html.theme--documenter-dark .progress.is-success::-ms-fill{background-color:#259a12}html.theme--documenter-dark .progress.is-success:indeterminate{background-image:linear-gradient(to right, #259a12 30%, #343c3d 30%)}html.theme--documenter-dark .progress.is-warning::-webkit-progress-value{background-color:#f4c72f}html.theme--documenter-dark .progress.is-warning::-moz-progress-bar{background-color:#f4c72f}html.theme--documenter-dark .progress.is-warning::-ms-fill{background-color:#f4c72f}html.theme--documenter-dark .progress.is-warning:indeterminate{background-image:linear-gradient(to right, #f4c72f 30%, #343c3d 30%)}html.theme--documenter-dark .progress.is-danger::-webkit-progress-value{background-color:#cb3c33}html.theme--documenter-dark .progress.is-danger::-moz-progress-bar{background-color:#cb3c33}html.theme--documenter-dark .progress.is-danger::-ms-fill{background-color:#cb3c33}html.theme--documenter-dark .progress.is-danger:indeterminate{background-image:linear-gradient(to right, #cb3c33 30%, #343c3d 30%)}html.theme--documenter-dark .progress:indeterminate{animation-duration:1.5s;animation-iteration-count:infinite;animation-name:moveIndeterminate;animation-timing-function:linear;background-color:#343c3d;background-image:linear-gradient(to right, #fff 30%, #343c3d 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:indeterminate::-ms-fill{animation-name:none}html.theme--documenter-dark .progress.is-small,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.progress{height:.75rem}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:rgba(0,0,0,0.7)}html.theme--documenter-dark .table td.is-dark,html.theme--documenter-dark .table th.is-dark{background-color:#282f2f;border-color:#282f2f;color:#fff}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:#3c5dcd;border-color:#3c5dcd;color:#fff}html.theme--documenter-dark .table td.is-success,html.theme--documenter-dark .table th.is-success{background-color:#259a12;border-color:#259a12;color:#fff}html.theme--documenter-dark .table td.is-warning,html.theme--documenter-dark .table th.is-warning{background-color:#f4c72f;border-color:#f4c72f;color:rgba(0,0,0,0.7)}html.theme--documenter-dark .table td.is-danger,html.theme--documenter-dark .table th.is-danger{background-color:#cb3c33;border-color:#cb3c33;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 td.is-vcentered,html.theme--documenter-dark .table th.is-vcentered{vertical-align:middle}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:.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:1rem}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-top-left-radius:0;border-bottom-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-top-right-radius:0;border-bottom-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:.75rem;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:.25rem;margin-right:-.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:rgba(0,0,0,0.7)}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:#fff}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-primary.is-light:not(body),html.theme--documenter-dark .content kbd.is-primary.is-light:not(body),html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-light:not(body){background-color:#f1f5f9;color:#4d7eb2}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-link.is-light:not(body),html.theme--documenter-dark .content kbd.is-link.is-light:not(body),html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-link.is-light:not(body){background-color:#edfdf9;color:#15987e}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:#3c5dcd;color:#fff}html.theme--documenter-dark .tag.is-info.is-light:not(body),html.theme--documenter-dark .content kbd.is-info.is-light:not(body),html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-info.is-light:not(body){background-color:#eff2fb;color:#3253c3}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:#259a12;color:#fff}html.theme--documenter-dark .tag.is-success.is-light:not(body),html.theme--documenter-dark .content kbd.is-success.is-light:not(body),html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-success.is-light:not(body){background-color:#effded;color:#2ec016}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:#f4c72f;color:rgba(0,0,0,0.7)}html.theme--documenter-dark .tag.is-warning.is-light:not(body),html.theme--documenter-dark .content kbd.is-warning.is-light:not(body),html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-warning.is-light:not(body){background-color:#fefaec;color:#8c6e07}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:#cb3c33;color:#fff}html.theme--documenter-dark .tag.is-danger.is-light:not(body),html.theme--documenter-dark .content kbd.is-danger.is-light:not(body),html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-danger.is-light:not(body){background-color:#fbefef;color:#c03930}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:.75rem}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:1rem}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:-.375em;margin-right:.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:.1875em;margin-right:-.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:-.375em;margin-right:-.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:9999px}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: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:1rem}html.theme--documenter-dark .title.is-7{font-size:.75rem}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:1rem}html.theme--documenter-dark .subtitle.is-7{font-size:.75rem}html.theme--documenter-dark .heading{display:block;font-size:11px;letter-spacing:1px;margin-bottom:5px;text-transform:uppercase}html.theme--documenter-dark .number{align-items:center;background-color:#282f2f;border-radius:9999px;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:#868c98}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:#868c98}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:#868c98}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:#868c98}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 0.0625em 0.125em rgba(10,10,10,0.05);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:#3c5dcd}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(60,93,205,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:#259a12}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(37,154,18,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:#f4c72f}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(244,199,47,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:#cb3c33}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(203,60,51,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:.75rem}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:9999px;padding-left:calc(calc(0.75em - 1px) + 0.375em);padding-right:calc(calc(0.75em - 1px) + 0.375em)}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:calc(0.75em - 1px);resize:vertical}html.theme--documenter-dark .textarea:not([rows]){max-height:40em;min-height:8em}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,html.theme--documenter-dark .radio input[disabled],html.theme--documenter-dark .checkbox input[disabled]{color:#fff;cursor:not-allowed}html.theme--documenter-dark .radio+.radio{margin-left:.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.5em}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:9999px;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:#3c5dcd}html.theme--documenter-dark .select.is-info select{border-color:#3c5dcd}html.theme--documenter-dark .select.is-info select:hover,html.theme--documenter-dark .select.is-info select.is-hovered{border-color:#3151bf}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(60,93,205,0.25)}html.theme--documenter-dark .select.is-success:not(:hover)::after{border-color:#259a12}html.theme--documenter-dark .select.is-success select{border-color:#259a12}html.theme--documenter-dark .select.is-success select:hover,html.theme--documenter-dark .select.is-success select.is-hovered{border-color:#20830f}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(37,154,18,0.25)}html.theme--documenter-dark .select.is-warning:not(:hover)::after{border-color:#f4c72f}html.theme--documenter-dark .select.is-warning select{border-color:#f4c72f}html.theme--documenter-dark .select.is-warning select:hover,html.theme--documenter-dark .select.is-warning select.is-hovered{border-color:#f3c017}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(244,199,47,0.25)}html.theme--documenter-dark .select.is-danger:not(:hover)::after{border-color:#cb3c33}html.theme--documenter-dark .select.is-danger select{border-color:#cb3c33}html.theme--documenter-dark .select.is-danger select:hover,html.theme--documenter-dark .select.is-danger select.is-hovered{border-color:#b7362e}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(203,60,51,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:.75rem}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 !important;opacity:0.5}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:.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:.75rem}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:rgba(0,0,0,0.7)}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:rgba(0,0,0,0.7)}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:rgba(0,0,0,0.7)}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:rgba(0,0,0,0.7)}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:#fff}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:#fff}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:#fff}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:#fff}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:#3c5dcd;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:#3355c9;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(60,93,205,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:#3151bf;border-color:transparent;color:#fff}html.theme--documenter-dark .file.is-success .file-cta{background-color:#259a12;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:#228f11;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(37,154,18,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:#20830f;border-color:transparent;color:#fff}html.theme--documenter-dark .file.is-warning .file-cta{background-color:#f4c72f;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--documenter-dark .file.is-warning:hover .file-cta,html.theme--documenter-dark .file.is-warning.is-hovered .file-cta{background-color:#f3c423;border-color:transparent;color:rgba(0,0,0,0.7)}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(244,199,47,0.25);color:rgba(0,0,0,0.7)}html.theme--documenter-dark .file.is-warning:active .file-cta,html.theme--documenter-dark .file.is-warning.is-active .file-cta{background-color:#f3c017;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--documenter-dark .file.is-danger .file-cta{background-color:#cb3c33;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:#c13930;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(203,60,51,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:#b7362e;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:.75rem}html.theme--documenter-dark .file.is-normal{font-size:1rem}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:#232829;color:#f2f2f2}html.theme--documenter-dark .file-label:hover .file-name{border-color:#596668}html.theme--documenter-dark .file-label:active .file-cta{background-color:#1d2122;color:#f2f2f2}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:#282f2f;color:#fff}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:inherit;text-overflow:ellipsis}html.theme--documenter-dark .file-icon{align-items:center;display:flex;height:1em;justify-content:center;margin-right:.5em;width:1em}html.theme--documenter-dark .file-icon .fa{font-size:14px}html.theme--documenter-dark .label{color:#f2f2f2;display:block;font-size:1rem;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:.75rem}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:.75rem;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:#3c5dcd}html.theme--documenter-dark .help.is-success{color:#259a12}html.theme--documenter-dark .help.is-warning{color:#f4c72f}html.theme--documenter-dark .help.is-danger{color:#cb3c33}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:.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:.75rem;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:.75rem}}html.theme--documenter-dark .control{box-sizing:border-box;clear:both;font-size:1rem;position:relative;text-align:inherit}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:#282f2f}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:.75rem}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:#5e6d6f;height:2.5em;pointer-events:none;position:absolute;top:0;width:2.5em;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.5em}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.5em}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:.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:.75rem}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:1rem;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:.5em}html.theme--documenter-dark .breadcrumb .icon:last-child{margin-left:.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:.75rem}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;border-radius:.25rem;box-shadow:#171717;color:#fff;max-width:100%;position:relative}html.theme--documenter-dark .card-footer:first-child,html.theme--documenter-dark .card-content:first-child,html.theme--documenter-dark .card-header:first-child{border-top-left-radius:.25rem;border-top-right-radius:.25rem}html.theme--documenter-dark .card-footer:last-child,html.theme--documenter-dark .card-content:last-child,html.theme--documenter-dark .card-header:last-child{border-bottom-left-radius:.25rem;border-bottom-right-radius:.25rem}html.theme--documenter-dark .card-header{background-color:rgba(0,0,0,0);align-items:stretch;box-shadow:0 0.125em 0.25em 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:0.75rem 1rem}html.theme--documenter-dark .card-header-title.is-centered{justify-content:center}html.theme--documenter-dark .card-header-icon{-moz-appearance:none;-webkit-appearance:none;appearance:none;background:none;border:none;color:currentColor;font-family:inherit;font-size:1em;margin:0;padding:0;align-items:center;cursor:pointer;display:flex;justify-content:center;padding:0.75rem 1rem}html.theme--documenter-dark .card-image{display:block;position:relative}html.theme--documenter-dark .card-image:first-child img{border-top-left-radius:.25rem;border-top-right-radius:.25rem}html.theme--documenter-dark .card-image:last-child img{border-bottom-left-radius:.25rem;border-bottom-right-radius:.25rem}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 #ededed;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 #ededed}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:#171717;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:inherit;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:#ededed;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 .media{align-items:flex-start;display:flex;text-align:inherit}html.theme--documenter-dark .media .content:not(:last-child){margin-bottom:.75rem}html.theme--documenter-dark .media .media{border-top:1px solid rgba(94,109,111,0.5);display:flex;padding-top:.75rem}html.theme--documenter-dark .media .media .content:not(:last-child),html.theme--documenter-dark .media .media .control:not(:last-child){margin-bottom:.5rem}html.theme--documenter-dark .media .media .media{padding-top:.5rem}html.theme--documenter-dark .media .media .media+.media{margin-top:.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:inherit}@media screen and (max-width: 768px){html.theme--documenter-dark .media-content{overflow-x:auto}}html.theme--documenter-dark .menu{font-size:1rem}html.theme--documenter-dark .menu.is-small,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.menu{font-size:.75rem}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:1rem}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:.75rem}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}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}html.theme--documenter-dark .message.is-light{background-color:#f9fafb}html.theme--documenter-dark .message.is-light .message-header{background-color:#ecf0f1;color:rgba(0,0,0,0.7)}html.theme--documenter-dark .message.is-light .message-body{border-color:#ecf0f1}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:#fff}html.theme--documenter-dark .message.is-dark .message-body,html.theme--documenter-dark .content kbd.message .message-body{border-color:#282f2f}html.theme--documenter-dark .message.is-primary,html.theme--documenter-dark .docstring>section>a.message.docs-sourcelink{background-color:#f1f5f9}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:#4d7eb2}html.theme--documenter-dark .message.is-link{background-color:#edfdf9}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:#15987e}html.theme--documenter-dark .message.is-info{background-color:#eff2fb}html.theme--documenter-dark .message.is-info .message-header{background-color:#3c5dcd;color:#fff}html.theme--documenter-dark .message.is-info .message-body{border-color:#3c5dcd;color:#3253c3}html.theme--documenter-dark .message.is-success{background-color:#effded}html.theme--documenter-dark .message.is-success .message-header{background-color:#259a12;color:#fff}html.theme--documenter-dark .message.is-success .message-body{border-color:#259a12;color:#2ec016}html.theme--documenter-dark .message.is-warning{background-color:#fefaec}html.theme--documenter-dark .message.is-warning .message-header{background-color:#f4c72f;color:rgba(0,0,0,0.7)}html.theme--documenter-dark .message.is-warning .message-body{border-color:#f4c72f;color:#8c6e07}html.theme--documenter-dark .message.is-danger{background-color:#fbefef}html.theme--documenter-dark .message.is-danger .message-header{background-color:#cb3c33;color:#fff}html.theme--documenter-dark .message.is-danger .message-body{border-color:#cb3c33;color:#c03930}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:.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){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:.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:rgba(0,0,0,0.7)}html.theme--documenter-dark .navbar.is-light .navbar-brand>.navbar-item,html.theme--documenter-dark .navbar.is-light .navbar-brand .navbar-link{color:rgba(0,0,0,0.7)}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:rgba(0,0,0,0.7)}html.theme--documenter-dark .navbar.is-light .navbar-brand .navbar-link::after{border-color:rgba(0,0,0,0.7)}html.theme--documenter-dark .navbar.is-light .navbar-burger{color:rgba(0,0,0,0.7)}@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:rgba(0,0,0,0.7)}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:rgba(0,0,0,0.7)}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:rgba(0,0,0,0.7)}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:rgba(0,0,0,0.7)}html.theme--documenter-dark .navbar.is-light .navbar-dropdown a.navbar-item.is-active{background-color:#ecf0f1;color:rgba(0,0,0,0.7)}}html.theme--documenter-dark .navbar.is-dark,html.theme--documenter-dark .content kbd.navbar{background-color:#282f2f;color:#fff}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:#fff}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:#fff}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:#fff}html.theme--documenter-dark .navbar.is-dark .navbar-burger,html.theme--documenter-dark .content kbd.navbar .navbar-burger{color:#fff}@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:#fff}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:#fff}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:#fff}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:#fff}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:#fff}}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:#3c5dcd;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:#3151bf;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:#3151bf;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:#3151bf;color:#fff}html.theme--documenter-dark .navbar.is-info .navbar-dropdown a.navbar-item.is-active{background-color:#3c5dcd;color:#fff}}html.theme--documenter-dark .navbar.is-success{background-color:#259a12;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:#20830f;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:#20830f;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:#20830f;color:#fff}html.theme--documenter-dark .navbar.is-success .navbar-dropdown a.navbar-item.is-active{background-color:#259a12;color:#fff}}html.theme--documenter-dark .navbar.is-warning{background-color:#f4c72f;color:rgba(0,0,0,0.7)}html.theme--documenter-dark .navbar.is-warning .navbar-brand>.navbar-item,html.theme--documenter-dark .navbar.is-warning .navbar-brand .navbar-link{color:rgba(0,0,0,0.7)}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:#f3c017;color:rgba(0,0,0,0.7)}html.theme--documenter-dark .navbar.is-warning .navbar-brand .navbar-link::after{border-color:rgba(0,0,0,0.7)}html.theme--documenter-dark .navbar.is-warning .navbar-burger{color:rgba(0,0,0,0.7)}@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:rgba(0,0,0,0.7)}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:#f3c017;color:rgba(0,0,0,0.7)}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:rgba(0,0,0,0.7)}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:#f3c017;color:rgba(0,0,0,0.7)}html.theme--documenter-dark .navbar.is-warning .navbar-dropdown a.navbar-item.is-active{background-color:#f4c72f;color:rgba(0,0,0,0.7)}}html.theme--documenter-dark .navbar.is-danger{background-color:#cb3c33;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:#b7362e;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:#b7362e;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:#b7362e;color:#fff}html.theme--documenter-dark .navbar.is-danger .navbar-dropdown a.navbar-item.is-active{background-color:#cb3c33;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;-moz-appearance:none;-webkit-appearance:none;appearance:none;background:none;border:none;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{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.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:1rem;margin:-.25rem}html.theme--documenter-dark .pagination.is-small,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.pagination{font-size:.75rem}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:9999px}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:9999px}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.5em}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-previous.is-disabled,html.theme--documenter-dark .pagination-next[disabled],html.theme--documenter-dark .pagination-next.is-disabled,html.theme--documenter-dark .pagination-link[disabled],html.theme--documenter-dark .pagination-link.is-disabled{background-color:#5e6d6f;border-color:#5e6d6f;box-shadow:none;color:#fff;opacity:0.5}html.theme--documenter-dark .pagination-previous,html.theme--documenter-dark .pagination-next{padding-left:.75em;padding-right:.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}html.theme--documenter-dark .pagination-list li{list-style:none}@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,html.theme--documenter-dark .pagination-next,html.theme--documenter-dark .pagination-link,html.theme--documenter-dark .pagination-ellipsis{margin-bottom:0;margin-top:0}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;margin-bottom:0;margin-top:0}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{border-radius:8px;box-shadow:#171717;font-size:1rem}html.theme--documenter-dark .panel:not(:last-child){margin-bottom:1.5rem}html.theme--documenter-dark .panel.is-white .panel-heading{background-color:#fff;color:#0a0a0a}html.theme--documenter-dark .panel.is-white .panel-tabs a.is-active{border-bottom-color:#fff}html.theme--documenter-dark .panel.is-white .panel-block.is-active .panel-icon{color:#fff}html.theme--documenter-dark .panel.is-black .panel-heading{background-color:#0a0a0a;color:#fff}html.theme--documenter-dark .panel.is-black .panel-tabs a.is-active{border-bottom-color:#0a0a0a}html.theme--documenter-dark .panel.is-black .panel-block.is-active .panel-icon{color:#0a0a0a}html.theme--documenter-dark .panel.is-light .panel-heading{background-color:#ecf0f1;color:rgba(0,0,0,0.7)}html.theme--documenter-dark .panel.is-light .panel-tabs a.is-active{border-bottom-color:#ecf0f1}html.theme--documenter-dark .panel.is-light .panel-block.is-active .panel-icon{color:#ecf0f1}html.theme--documenter-dark .panel.is-dark .panel-heading,html.theme--documenter-dark .content kbd.panel .panel-heading{background-color:#282f2f;color:#fff}html.theme--documenter-dark .panel.is-dark .panel-tabs a.is-active,html.theme--documenter-dark .content kbd.panel .panel-tabs a.is-active{border-bottom-color:#282f2f}html.theme--documenter-dark .panel.is-dark .panel-block.is-active .panel-icon,html.theme--documenter-dark .content kbd.panel .panel-block.is-active .panel-icon{color:#282f2f}html.theme--documenter-dark .panel.is-primary .panel-heading,html.theme--documenter-dark .docstring>section>a.panel.docs-sourcelink .panel-heading{background-color:#375a7f;color:#fff}html.theme--documenter-dark .panel.is-primary .panel-tabs a.is-active,html.theme--documenter-dark .docstring>section>a.panel.docs-sourcelink .panel-tabs a.is-active{border-bottom-color:#375a7f}html.theme--documenter-dark .panel.is-primary .panel-block.is-active .panel-icon,html.theme--documenter-dark .docstring>section>a.panel.docs-sourcelink .panel-block.is-active .panel-icon{color:#375a7f}html.theme--documenter-dark .panel.is-link .panel-heading{background-color:#1abc9c;color:#fff}html.theme--documenter-dark .panel.is-link .panel-tabs a.is-active{border-bottom-color:#1abc9c}html.theme--documenter-dark .panel.is-link .panel-block.is-active .panel-icon{color:#1abc9c}html.theme--documenter-dark .panel.is-info .panel-heading{background-color:#3c5dcd;color:#fff}html.theme--documenter-dark .panel.is-info .panel-tabs a.is-active{border-bottom-color:#3c5dcd}html.theme--documenter-dark .panel.is-info .panel-block.is-active .panel-icon{color:#3c5dcd}html.theme--documenter-dark .panel.is-success .panel-heading{background-color:#259a12;color:#fff}html.theme--documenter-dark .panel.is-success .panel-tabs a.is-active{border-bottom-color:#259a12}html.theme--documenter-dark .panel.is-success .panel-block.is-active .panel-icon{color:#259a12}html.theme--documenter-dark .panel.is-warning .panel-heading{background-color:#f4c72f;color:rgba(0,0,0,0.7)}html.theme--documenter-dark .panel.is-warning .panel-tabs a.is-active{border-bottom-color:#f4c72f}html.theme--documenter-dark .panel.is-warning .panel-block.is-active .panel-icon{color:#f4c72f}html.theme--documenter-dark .panel.is-danger .panel-heading{background-color:#cb3c33;color:#fff}html.theme--documenter-dark .panel.is-danger .panel-tabs a.is-active{border-bottom-color:#cb3c33}html.theme--documenter-dark .panel.is-danger .panel-block.is-active .panel-icon{color:#cb3c33}html.theme--documenter-dark .panel-tabs:not(:last-child),html.theme--documenter-dark .panel-block:not(:last-child){border-bottom:1px solid #ededed}html.theme--documenter-dark .panel-heading{background-color:#343c3d;border-radius:8px 8px 0 0;color:#f2f2f2;font-size:1.25em;font-weight:700;line-height:1.25;padding:0.75em 1em}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:.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 .panel-block:last-child{border-bottom-left-radius:8px;border-bottom-right-radius:8px}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:.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:1rem;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:.5em}html.theme--documenter-dark .tabs .icon:last-child{margin-left:.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-top-left-radius:.4em;border-bottom-left-radius:.4em}html.theme--documenter-dark .tabs.is-toggle li:last-child a{border-top-right-radius:.4em;border-bottom-right-radius:.4em}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:9999px;border-top-left-radius:9999px;padding-left:1.25em}html.theme--documenter-dark .tabs.is-toggle.is-toggle-rounded li:last-child a{border-bottom-right-radius:9999px;border-top-right-radius:9999px;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:.75rem}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;width:unset}.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.33333337%}.columns.is-mobile>html.theme--documenter-dark .column.is-offset-1{margin-left:8.33333337%}.columns.is-mobile>html.theme--documenter-dark .column.is-2{flex:none;width:16.66666674%}.columns.is-mobile>html.theme--documenter-dark .column.is-offset-2{margin-left:16.66666674%}.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.33333337%}.columns.is-mobile>html.theme--documenter-dark .column.is-offset-4{margin-left:33.33333337%}.columns.is-mobile>html.theme--documenter-dark .column.is-5{flex:none;width:41.66666674%}.columns.is-mobile>html.theme--documenter-dark .column.is-offset-5{margin-left:41.66666674%}.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.33333337%}.columns.is-mobile>html.theme--documenter-dark .column.is-offset-7{margin-left:58.33333337%}.columns.is-mobile>html.theme--documenter-dark .column.is-8{flex:none;width:66.66666674%}.columns.is-mobile>html.theme--documenter-dark .column.is-offset-8{margin-left:66.66666674%}.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.33333337%}.columns.is-mobile>html.theme--documenter-dark .column.is-offset-10{margin-left:83.33333337%}.columns.is-mobile>html.theme--documenter-dark .column.is-11{flex:none;width:91.66666674%}.columns.is-mobile>html.theme--documenter-dark .column.is-offset-11{margin-left:91.66666674%}.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;width:unset}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.33333337%}html.theme--documenter-dark .column.is-offset-1-mobile{margin-left:8.33333337%}html.theme--documenter-dark .column.is-2-mobile{flex:none;width:16.66666674%}html.theme--documenter-dark .column.is-offset-2-mobile{margin-left:16.66666674%}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.33333337%}html.theme--documenter-dark .column.is-offset-4-mobile{margin-left:33.33333337%}html.theme--documenter-dark .column.is-5-mobile{flex:none;width:41.66666674%}html.theme--documenter-dark .column.is-offset-5-mobile{margin-left:41.66666674%}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.33333337%}html.theme--documenter-dark .column.is-offset-7-mobile{margin-left:58.33333337%}html.theme--documenter-dark .column.is-8-mobile{flex:none;width:66.66666674%}html.theme--documenter-dark .column.is-offset-8-mobile{margin-left:66.66666674%}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.33333337%}html.theme--documenter-dark .column.is-offset-10-mobile{margin-left:83.33333337%}html.theme--documenter-dark .column.is-11-mobile{flex:none;width:91.66666674%}html.theme--documenter-dark .column.is-offset-11-mobile{margin-left:91.66666674%}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;width:unset}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.33333337%}html.theme--documenter-dark .column.is-offset-1,html.theme--documenter-dark .column.is-offset-1-tablet{margin-left:8.33333337%}html.theme--documenter-dark .column.is-2,html.theme--documenter-dark .column.is-2-tablet{flex:none;width:16.66666674%}html.theme--documenter-dark .column.is-offset-2,html.theme--documenter-dark .column.is-offset-2-tablet{margin-left:16.66666674%}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.33333337%}html.theme--documenter-dark .column.is-offset-4,html.theme--documenter-dark .column.is-offset-4-tablet{margin-left:33.33333337%}html.theme--documenter-dark .column.is-5,html.theme--documenter-dark .column.is-5-tablet{flex:none;width:41.66666674%}html.theme--documenter-dark .column.is-offset-5,html.theme--documenter-dark .column.is-offset-5-tablet{margin-left:41.66666674%}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.33333337%}html.theme--documenter-dark .column.is-offset-7,html.theme--documenter-dark .column.is-offset-7-tablet{margin-left:58.33333337%}html.theme--documenter-dark .column.is-8,html.theme--documenter-dark .column.is-8-tablet{flex:none;width:66.66666674%}html.theme--documenter-dark .column.is-offset-8,html.theme--documenter-dark .column.is-offset-8-tablet{margin-left:66.66666674%}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.33333337%}html.theme--documenter-dark .column.is-offset-10,html.theme--documenter-dark .column.is-offset-10-tablet{margin-left:83.33333337%}html.theme--documenter-dark .column.is-11,html.theme--documenter-dark .column.is-11-tablet{flex:none;width:91.66666674%}html.theme--documenter-dark .column.is-offset-11,html.theme--documenter-dark .column.is-offset-11-tablet{margin-left:91.66666674%}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;width:unset}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.33333337%}html.theme--documenter-dark .column.is-offset-1-touch{margin-left:8.33333337%}html.theme--documenter-dark .column.is-2-touch{flex:none;width:16.66666674%}html.theme--documenter-dark .column.is-offset-2-touch{margin-left:16.66666674%}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.33333337%}html.theme--documenter-dark .column.is-offset-4-touch{margin-left:33.33333337%}html.theme--documenter-dark .column.is-5-touch{flex:none;width:41.66666674%}html.theme--documenter-dark .column.is-offset-5-touch{margin-left:41.66666674%}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.33333337%}html.theme--documenter-dark .column.is-offset-7-touch{margin-left:58.33333337%}html.theme--documenter-dark .column.is-8-touch{flex:none;width:66.66666674%}html.theme--documenter-dark .column.is-offset-8-touch{margin-left:66.66666674%}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.33333337%}html.theme--documenter-dark .column.is-offset-10-touch{margin-left:83.33333337%}html.theme--documenter-dark .column.is-11-touch{flex:none;width:91.66666674%}html.theme--documenter-dark .column.is-offset-11-touch{margin-left:91.66666674%}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;width:unset}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.33333337%}html.theme--documenter-dark .column.is-offset-1-desktop{margin-left:8.33333337%}html.theme--documenter-dark .column.is-2-desktop{flex:none;width:16.66666674%}html.theme--documenter-dark .column.is-offset-2-desktop{margin-left:16.66666674%}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.33333337%}html.theme--documenter-dark .column.is-offset-4-desktop{margin-left:33.33333337%}html.theme--documenter-dark .column.is-5-desktop{flex:none;width:41.66666674%}html.theme--documenter-dark .column.is-offset-5-desktop{margin-left:41.66666674%}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.33333337%}html.theme--documenter-dark .column.is-offset-7-desktop{margin-left:58.33333337%}html.theme--documenter-dark .column.is-8-desktop{flex:none;width:66.66666674%}html.theme--documenter-dark .column.is-offset-8-desktop{margin-left:66.66666674%}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.33333337%}html.theme--documenter-dark .column.is-offset-10-desktop{margin-left:83.33333337%}html.theme--documenter-dark .column.is-11-desktop{flex:none;width:91.66666674%}html.theme--documenter-dark .column.is-offset-11-desktop{margin-left:91.66666674%}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;width:unset}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.33333337%}html.theme--documenter-dark .column.is-offset-1-widescreen{margin-left:8.33333337%}html.theme--documenter-dark .column.is-2-widescreen{flex:none;width:16.66666674%}html.theme--documenter-dark .column.is-offset-2-widescreen{margin-left:16.66666674%}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.33333337%}html.theme--documenter-dark .column.is-offset-4-widescreen{margin-left:33.33333337%}html.theme--documenter-dark .column.is-5-widescreen{flex:none;width:41.66666674%}html.theme--documenter-dark .column.is-offset-5-widescreen{margin-left:41.66666674%}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.33333337%}html.theme--documenter-dark .column.is-offset-7-widescreen{margin-left:58.33333337%}html.theme--documenter-dark .column.is-8-widescreen{flex:none;width:66.66666674%}html.theme--documenter-dark .column.is-offset-8-widescreen{margin-left:66.66666674%}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.33333337%}html.theme--documenter-dark .column.is-offset-10-widescreen{margin-left:83.33333337%}html.theme--documenter-dark .column.is-11-widescreen{flex:none;width:91.66666674%}html.theme--documenter-dark .column.is-offset-11-widescreen{margin-left:91.66666674%}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;width:unset}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.33333337%}html.theme--documenter-dark .column.is-offset-1-fullhd{margin-left:8.33333337%}html.theme--documenter-dark .column.is-2-fullhd{flex:none;width:16.66666674%}html.theme--documenter-dark .column.is-offset-2-fullhd{margin-left:16.66666674%}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.33333337%}html.theme--documenter-dark .column.is-offset-4-fullhd{margin-left:33.33333337%}html.theme--documenter-dark .column.is-5-fullhd{flex:none;width:41.66666674%}html.theme--documenter-dark .column.is-offset-5-fullhd{margin-left:41.66666674%}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.33333337%}html.theme--documenter-dark .column.is-offset-7-fullhd{margin-left:58.33333337%}html.theme--documenter-dark .column.is-8-fullhd{flex:none;width:66.66666674%}html.theme--documenter-dark .column.is-offset-8-fullhd{margin-left:66.66666674%}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.33333337%}html.theme--documenter-dark .column.is-offset-10-fullhd{margin-left:83.33333337%}html.theme--documenter-dark .column.is-11-fullhd{flex:none;width:91.66666674%}html.theme--documenter-dark .column.is-offset-11-fullhd{margin-left:91.66666674%}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.33333337%}html.theme--documenter-dark .tile.is-2{flex:none;width:16.66666674%}html.theme--documenter-dark .tile.is-3{flex:none;width:25%}html.theme--documenter-dark .tile.is-4{flex:none;width:33.33333337%}html.theme--documenter-dark .tile.is-5{flex:none;width:41.66666674%}html.theme--documenter-dark .tile.is-6{flex:none;width:50%}html.theme--documenter-dark .tile.is-7{flex:none;width:58.33333337%}html.theme--documenter-dark .tile.is-8{flex:none;width:66.66666674%}html.theme--documenter-dark .tile.is-9{flex:none;width:75%}html.theme--documenter-dark .tile.is-10{flex:none;width:83.33333337%}html.theme--documenter-dark .tile.is-11{flex:none;width:91.66666674%}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{color:#fff !important;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{color:#0a0a0a !important;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:rgba(0,0,0,0.7)}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:rgba(0,0,0,0.7)}html.theme--documenter-dark .hero.is-light .subtitle{color:rgba(0,0,0,0.9)}html.theme--documenter-dark .hero.is-light .subtitle a:not(.button),html.theme--documenter-dark .hero.is-light .subtitle strong{color:rgba(0,0,0,0.7)}@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(0,0,0,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:rgba(0,0,0,0.7)}html.theme--documenter-dark .hero.is-light .tabs a{color:rgba(0,0,0,0.7);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{color:#ecf0f1 !important;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:rgba(0,0,0,0.7)}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:rgba(0,0,0,0.7);border-color:rgba(0,0,0,0.7);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:#fff}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:#fff}html.theme--documenter-dark .hero.is-dark .subtitle,html.theme--documenter-dark .content kbd.hero .subtitle{color:rgba(255,255,255,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:#fff}@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(255,255,255,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:#fff}html.theme--documenter-dark .hero.is-dark .tabs a,html.theme--documenter-dark .content kbd.hero .tabs a{color:#fff;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{color:#282f2f !important;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:#fff}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:#fff;border-color:#fff;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{color:#375a7f !important;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{color:#1abc9c !important;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:#3c5dcd;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:#3c5dcd}}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:#3151bf;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{color:#3c5dcd !important;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:#3c5dcd}html.theme--documenter-dark .hero.is-info.is-bold{background-image:linear-gradient(141deg, #215bb5 0%, #3c5dcd 71%, #4b53d8 100%)}@media screen and (max-width: 768px){html.theme--documenter-dark .hero.is-info.is-bold .navbar-menu{background-image:linear-gradient(141deg, #215bb5 0%, #3c5dcd 71%, #4b53d8 100%)}}html.theme--documenter-dark .hero.is-success{background-color:#259a12;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:#259a12}}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:#20830f;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{color:#259a12 !important;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:#259a12}html.theme--documenter-dark .hero.is-success.is-bold{background-image:linear-gradient(141deg, #287207 0%, #259a12 71%, #10b614 100%)}@media screen and (max-width: 768px){html.theme--documenter-dark .hero.is-success.is-bold .navbar-menu{background-image:linear-gradient(141deg, #287207 0%, #259a12 71%, #10b614 100%)}}html.theme--documenter-dark .hero.is-warning{background-color:#f4c72f;color:rgba(0,0,0,0.7)}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:rgba(0,0,0,0.7)}html.theme--documenter-dark .hero.is-warning .subtitle{color:rgba(0,0,0,0.9)}html.theme--documenter-dark .hero.is-warning .subtitle a:not(.button),html.theme--documenter-dark .hero.is-warning .subtitle strong{color:rgba(0,0,0,0.7)}@media screen and (max-width: 1055px){html.theme--documenter-dark .hero.is-warning .navbar-menu{background-color:#f4c72f}}html.theme--documenter-dark .hero.is-warning .navbar-item,html.theme--documenter-dark .hero.is-warning .navbar-link{color:rgba(0,0,0,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:#f3c017;color:rgba(0,0,0,0.7)}html.theme--documenter-dark .hero.is-warning .tabs a{color:rgba(0,0,0,0.7);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{color:#f4c72f !important;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:rgba(0,0,0,0.7)}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:rgba(0,0,0,0.7);border-color:rgba(0,0,0,0.7);color:#f4c72f}html.theme--documenter-dark .hero.is-warning.is-bold{background-image:linear-gradient(141deg, #f09100 0%, #f4c72f 71%, #faef42 100%)}@media screen and (max-width: 768px){html.theme--documenter-dark .hero.is-warning.is-bold .navbar-menu{background-image:linear-gradient(141deg, #f09100 0%, #f4c72f 71%, #faef42 100%)}}html.theme--documenter-dark .hero.is-danger{background-color:#cb3c33;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:#cb3c33}}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:#b7362e;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{color:#cb3c33 !important;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:#cb3c33}html.theme--documenter-dark .hero.is-danger.is-bold{background-image:linear-gradient(141deg, #ac1f2e 0%, #cb3c33 71%, #d66341 100%)}@media screen and (max-width: 768px){html.theme--documenter-dark .hero.is-danger.is-bold .navbar-menu{background-image:linear-gradient(141deg, #ac1f2e 0%, #cb3c33 71%, #d66341 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:1.5rem}@media screen and (min-width: 769px),print{html.theme--documenter-dark .hero.is-medium .hero-body{padding:9rem 4.5rem}}@media screen and (min-width: 769px),print{html.theme--documenter-dark .hero.is-large .hero-body{padding:18rem 6rem}}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}@media screen and (min-width: 769px),print{html.theme--documenter-dark .hero-body{padding:3rem 3rem}}html.theme--documenter-dark .section{padding:3rem 1.5rem}@media screen and (min-width: 1056px){html.theme--documenter-dark .section{padding:3rem 3rem}html.theme--documenter-dark .section.is-medium{padding:9rem 4.5rem}html.theme--documenter-dark .section.is-large{padding:18rem 6rem}}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:#5a76d5}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:#3c5dcd;box-shadow:0 0 0 2px rgba(60,93,205,0.5)}html.theme--documenter-dark .button.is-success.is-hovered,html.theme--documenter-dark .button.is-success:hover{background-color:#2dbc16}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:#259a12;box-shadow:0 0 0 2px rgba(37,154,18,0.5)}html.theme--documenter-dark .button.is-warning.is-hovered,html.theme--documenter-dark .button.is-warning:hover{background-color:#f6d153}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:#f4c72f;box-shadow:0 0 0 2px rgba(244,199,47,0.5)}html.theme--documenter-dark .button.is-danger.is-hovered,html.theme--documenter-dark .button.is-danger:hover{background-color:#d35951}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:#cb3c33;box-shadow:0 0 0 2px rgba(203,60,51,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:rgba(0,0,0,0.7);text-decoration:underline}html.theme--documenter-dark .notification.is-dark a:not(.button),html.theme--documenter-dark .content kbd.notification a:not(.button){color:#fff;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:rgba(0,0,0,0.7);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 6 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 6 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:2px;border-color:#dbdee0;border-radius:4px;font-size:1rem}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:.75rem}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:#dbdee0}html.theme--documenter-dark .admonition.is-default>.admonition-header{background-color:rgba(0,0,0,0);color:#dbdee0}html.theme--documenter-dark .admonition.is-default>.admonition-body{color:#fff}html.theme--documenter-dark .admonition.is-info{background-color:#282f2f;border-color:#3c5dcd}html.theme--documenter-dark .admonition.is-info>.admonition-header{background-color:rgba(0,0,0,0);color:#3c5dcd}html.theme--documenter-dark .admonition.is-info>.admonition-body{color:#fff}html.theme--documenter-dark .admonition.is-success{background-color:#282f2f;border-color:#259a12}html.theme--documenter-dark .admonition.is-success>.admonition-header{background-color:rgba(0,0,0,0);color:#259a12}html.theme--documenter-dark .admonition.is-success>.admonition-body{color:#fff}html.theme--documenter-dark .admonition.is-warning{background-color:#282f2f;border-color:#f4c72f}html.theme--documenter-dark .admonition.is-warning>.admonition-header{background-color:rgba(0,0,0,0);color:#f4c72f}html.theme--documenter-dark .admonition.is-warning>.admonition-body{color:#fff}html.theme--documenter-dark .admonition.is-danger{background-color:#282f2f;border-color:#cb3c33}html.theme--documenter-dark .admonition.is-danger>.admonition-header{background-color:rgba(0,0,0,0);color:#cb3c33}html.theme--documenter-dark .admonition.is-danger>.admonition-body{color:#fff}html.theme--documenter-dark .admonition.is-compat{background-color:#282f2f;border-color:#3489da}html.theme--documenter-dark .admonition.is-compat>.admonition-header{background-color:rgba(0,0,0,0);color:#3489da}html.theme--documenter-dark .admonition.is-compat>.admonition-body{color:#fff}html.theme--documenter-dark .admonition.is-todo{background-color:#282f2f;border-color:#9558b2}html.theme--documenter-dark .admonition.is-todo>.admonition-header{background-color:rgba(0,0,0,0);color:#9558b2}html.theme--documenter-dark .admonition.is-todo>.admonition-body{color:#fff}html.theme--documenter-dark .admonition-header{color:#dbdee0;background-color:rgba(0,0,0,0);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 6 Free";font-weight:900;margin-right:.75rem;content:"\f06a"}html.theme--documenter-dark details.admonition.is-details>.admonition-header{list-style:none}html.theme--documenter-dark details.admonition.is-details>.admonition-header:before{font-family:"Font Awesome 6 Free";font-weight:900;content:"\f055"}html.theme--documenter-dark details.admonition.is-details[open]>.admonition-header:before{font-family:"Font Awesome 6 Free";font-weight:900;content:"\f056"}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:2px solid #5e6d6f;border-radius:4px;box-shadow:none;max-width:100%}html.theme--documenter-dark .docstring>header{cursor:pointer;display:flex;flex-grow:1;align-items:stretch;padding:0.5rem .75rem;background-color:#282f2f;box-shadow:0 0.125em 0.25em rgba(10,10,10,0.1);box-shadow:none;border-bottom:1px solid #5e6d6f;overflow:auto}html.theme--documenter-dark .docstring>header code{background-color:transparent}html.theme--documenter-dark .docstring>header .docstring-article-toggle-button{min-width:1.1rem;padding:0.2rem 0.2rem 0.2rem 0}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 rgba(0,0,0,0);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:2px solid #5e6d6f;border-radius:4px}html.theme--documenter-dark .content code{font-weight:inherit}html.theme--documenter-dark .content a code{color:#1abc9c}html.theme--documenter-dark .content a:hover code{color:#1dd2af}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;overflow-x:hidden}html.theme--documenter-dark #documenter .docs-main header.docs-navbar .docs-sidebar-button{display:block;font-size:1.5rem;padding-bottom:0.1rem;margin-right:1rem}html.theme--documenter-dark #documenter .docs-main header.docs-navbar .docs-right{display:flex;white-space:nowrap;gap:1rem;align-items:center}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{display:inline-block}html.theme--documenter-dark #documenter .docs-main header.docs-navbar .docs-right .docs-label{padding:0;margin-left:0.3em}@media screen and (max-width: 1055px){html.theme--documenter-dark #documenter .docs-main header.docs-navbar .docs-right .docs-navbar-link{margin-left:0.4rem;margin-right:0.4rem}}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:1rem;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:.95rem;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:.75rem;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 6 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:.85rem;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}html.theme--documenter-dark #documenter .docs-sidebar #documenter-search-query{color:#868c98;width:14.4rem;box-shadow:inset 0 1px 2px rgba(10,10,10,0.1)}@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 kbd.search-modal-key-hints{border-radius:0.25rem;border:1px solid rgba(245,245,245,0.6);box-shadow:0 2px 0 1px rgba(245,245,245,0.6);cursor:default;font-size:0.9rem;line-height:1.5;min-width:0.75rem;text-align:center;padding:0.1rem 0.3rem;position:relative;top:-1px}html.theme--documenter-dark .search-min-width-50{min-width:50%}html.theme--documenter-dark .search-min-height-100{min-height:100%}html.theme--documenter-dark .search-modal-card-body{max-height:calc(100vh - 15rem)}html.theme--documenter-dark .search-result-link{border-radius:0.7em;transition:all 300ms}html.theme--documenter-dark .search-result-link:hover,html.theme--documenter-dark .search-result-link:focus{background-color:rgba(0,128,128,0.1)}html.theme--documenter-dark .search-result-link .property-search-result-badge,html.theme--documenter-dark .search-result-link .search-filter{transition:all 300ms}html.theme--documenter-dark .property-search-result-badge,html.theme--documenter-dark .search-filter{padding:0.15em 0.5em;font-size:0.8em;font-style:italic;text-transform:none !important;line-height:1.5;color:#f5f5f5;background-color:rgba(51,65,85,0.501961);border-radius:0.6rem}html.theme--documenter-dark .search-result-link:hover .property-search-result-badge,html.theme--documenter-dark .search-result-link:hover .search-filter,html.theme--documenter-dark .search-result-link:focus .property-search-result-badge,html.theme--documenter-dark .search-result-link:focus .search-filter{color:#333;background-color:#f1f5f9}html.theme--documenter-dark .search-filter{color:#333;background-color:#f5f5f5;transition:all 300ms}html.theme--documenter-dark .search-filter:hover,html.theme--documenter-dark .search-filter:focus{color:#333}html.theme--documenter-dark .search-filter-selected{color:#f5f5f5;background-color:rgba(139,0,139,0.5)}html.theme--documenter-dark .search-filter-selected:hover,html.theme--documenter-dark .search-filter-selected:focus{color:#f5f5f5}html.theme--documenter-dark .search-result-highlight{background-color:#ffdd57;color:black}html.theme--documenter-dark .search-divider{border-bottom:1px solid #5e6d6f}html.theme--documenter-dark .search-result-title{width:85%;color:#f5f5f5}html.theme--documenter-dark .search-result-code-title{font-size:0.875rem;font-family:"JuliaMono","SFMono-Regular","Menlo","Consolas","Liberation Mono","DejaVu Sans Mono",monospace}html.theme--documenter-dark #search-modal .modal-card-body::-webkit-scrollbar,html.theme--documenter-dark #search-modal .filter-tabs::-webkit-scrollbar{height:10px;width:10px;background-color:transparent}html.theme--documenter-dark #search-modal .modal-card-body::-webkit-scrollbar-thumb,html.theme--documenter-dark #search-modal .filter-tabs::-webkit-scrollbar-thumb{background-color:gray;border-radius:1rem}html.theme--documenter-dark #search-modal .modal-card-body::-webkit-scrollbar-track,html.theme--documenter-dark #search-modal .filter-tabs::-webkit-scrollbar-track{-webkit-box-shadow:inset 0 0 6px rgba(0,0,0,0.6);background-color:transparent}html.theme--documenter-dark .w-100{width:100%}html.theme--documenter-dark .gap-2{gap:0.5rem}html.theme--documenter-dark .gap-4{gap:1rem}html.theme--documenter-dark .gap-8{gap:2rem}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}html.theme--documenter-dark .search-result-link{border-radius:0.7em;transition:all 300ms}html.theme--documenter-dark .search-result-link:hover,html.theme--documenter-dark .search-result-link:focus{background-color:rgba(0,128,128,0.1)}html.theme--documenter-dark .search-result-link .property-search-result-badge,html.theme--documenter-dark .search-result-link .search-filter{transition:all 300ms}html.theme--documenter-dark .search-result-link:hover .property-search-result-badge,html.theme--documenter-dark .search-result-link:hover .search-filter,html.theme--documenter-dark .search-result-link:focus .property-search-result-badge,html.theme--documenter-dark .search-result-link:focus .search-filter{color:#333 !important;background-color:#f1f5f9 !important}html.theme--documenter-dark .search-result-title{color:whitesmoke}html.theme--documenter-dark .search-result-highlight{background-color:greenyellow;color:black}html.theme--documenter-dark .search-divider{border-bottom:1px solid #5e6d6f50}html.theme--documenter-dark .w-100{width:100%}html.theme--documenter-dark .gap-2{gap:0.5rem}html.theme--documenter-dark .gap-4{gap:1rem} diff --git a/previews/PR4245/assets/themes/documenter-light.css b/previews/PR4245/assets/themes/documenter-light.css deleted file mode 100644 index e000447e6010..000000000000 --- a/previews/PR4245/assets/themes/documenter-light.css +++ /dev/null @@ -1,9 +0,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.5em;justify-content:flex-start;line-height:1.5;padding-bottom:calc(0.5em - 1px);padding-left:calc(0.75em - 1px);padding-right:calc(0.75em - 1px);padding-top:calc(0.5em - 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}.tabs,.pagination-previous,.pagination-next,.pagination-link,.pagination-ellipsis,.breadcrumb,.file,.button,.is-unselectable{-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),.pagination:not(:last-child),.message:not(:last-child),.level:not(:last-child),.breadcrumb: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{-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-moz-appearance:none;-webkit-appearance:none;background-color:rgba(10,10,10,0.2);border:none;border-radius:9999px;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:9999px;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}.navbar-burger{-moz-appearance:none;-webkit-appearance:none;appearance:none;background:none;border:none;color:currentColor;font-family:inherit;font-size:1em;margin:0;padding:0}.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-primary-light{color:#eef8fc !important}a.has-text-primary-light:hover,a.has-text-primary-light:focus{color:#c3e6f4 !important}.has-background-primary-light{background-color:#eef8fc !important}.has-text-primary-dark{color:#1a6d8e !important}a.has-text-primary-dark:hover,a.has-text-primary-dark:focus{color:#228eb9 !important}.has-background-primary-dark{background-color:#1a6d8e !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-link-light{color:#eff3fb !important}a.has-text-link-light:hover,a.has-text-link-light:focus{color:#c6d6f1 !important}.has-background-link-light{background-color:#eff3fb !important}.has-text-link-dark{color:#3169c4 !important}a.has-text-link-dark:hover,a.has-text-link-dark:focus{color:#5485d4 !important}.has-background-link-dark{background-color:#3169c4 !important}.has-text-info{color:#3c5dcd !important}a.has-text-info:hover,a.has-text-info:focus{color:#2c48aa !important}.has-background-info{background-color:#3c5dcd !important}.has-text-info-light{color:#eff2fb !important}a.has-text-info-light:hover,a.has-text-info-light:focus{color:#c6d0f0 !important}.has-background-info-light{background-color:#eff2fb !important}.has-text-info-dark{color:#3253c3 !important}a.has-text-info-dark:hover,a.has-text-info-dark:focus{color:#5571d3 !important}.has-background-info-dark{background-color:#3253c3 !important}.has-text-success{color:#259a12 !important}a.has-text-success:hover,a.has-text-success:focus{color:#1a6c0d !important}.has-background-success{background-color:#259a12 !important}.has-text-success-light{color:#effded !important}a.has-text-success-light:hover,a.has-text-success-light:focus{color:#c7f8bf !important}.has-background-success-light{background-color:#effded !important}.has-text-success-dark{color:#2ec016 !important}a.has-text-success-dark:hover,a.has-text-success-dark:focus{color:#3fe524 !important}.has-background-success-dark{background-color:#2ec016 !important}.has-text-warning{color:#a98800 !important}a.has-text-warning:hover,a.has-text-warning:focus{color:#765f00 !important}.has-background-warning{background-color:#a98800 !important}.has-text-warning-light{color:#fffbeb !important}a.has-text-warning-light:hover,a.has-text-warning-light:focus{color:#fff1b8 !important}.has-background-warning-light{background-color:#fffbeb !important}.has-text-warning-dark{color:#cca400 !important}a.has-text-warning-dark:hover,a.has-text-warning-dark:focus{color:#ffcd00 !important}.has-background-warning-dark{background-color:#cca400 !important}.has-text-danger{color:#cb3c33 !important}a.has-text-danger:hover,a.has-text-danger:focus{color:#a23029 !important}.has-background-danger{background-color:#cb3c33 !important}.has-text-danger-light{color:#fbefef !important}a.has-text-danger-light:hover,a.has-text-danger-light:focus{color:#f1c8c6 !important}.has-background-danger-light{background-color:#fbefef !important}.has-text-danger-dark{color:#c03930 !important}a.has-text-danger-dark:hover,a.has-text-danger-dark:focus{color:#d35850 !important}.has-background-danger-dark{background-color:#c03930 !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}.is-flex-direction-row{flex-direction:row !important}.is-flex-direction-row-reverse{flex-direction:row-reverse !important}.is-flex-direction-column{flex-direction:column !important}.is-flex-direction-column-reverse{flex-direction:column-reverse !important}.is-flex-wrap-nowrap{flex-wrap:nowrap !important}.is-flex-wrap-wrap{flex-wrap:wrap !important}.is-flex-wrap-wrap-reverse{flex-wrap:wrap-reverse !important}.is-justify-content-flex-start{justify-content:flex-start !important}.is-justify-content-flex-end{justify-content:flex-end !important}.is-justify-content-center{justify-content:center !important}.is-justify-content-space-between{justify-content:space-between !important}.is-justify-content-space-around{justify-content:space-around !important}.is-justify-content-space-evenly{justify-content:space-evenly !important}.is-justify-content-start{justify-content:start !important}.is-justify-content-end{justify-content:end !important}.is-justify-content-left{justify-content:left !important}.is-justify-content-right{justify-content:right !important}.is-align-content-flex-start{align-content:flex-start !important}.is-align-content-flex-end{align-content:flex-end !important}.is-align-content-center{align-content:center !important}.is-align-content-space-between{align-content:space-between !important}.is-align-content-space-around{align-content:space-around !important}.is-align-content-space-evenly{align-content:space-evenly !important}.is-align-content-stretch{align-content:stretch !important}.is-align-content-start{align-content:start !important}.is-align-content-end{align-content:end !important}.is-align-content-baseline{align-content:baseline !important}.is-align-items-stretch{align-items:stretch !important}.is-align-items-flex-start{align-items:flex-start !important}.is-align-items-flex-end{align-items:flex-end !important}.is-align-items-center{align-items:center !important}.is-align-items-baseline{align-items:baseline !important}.is-align-items-start{align-items:start !important}.is-align-items-end{align-items:end !important}.is-align-items-self-start{align-items:self-start !important}.is-align-items-self-end{align-items:self-end !important}.is-align-self-auto{align-self:auto !important}.is-align-self-flex-start{align-self:flex-start !important}.is-align-self-flex-end{align-self:flex-end !important}.is-align-self-center{align-self:center !important}.is-align-self-baseline{align-self:baseline !important}.is-align-self-stretch{align-self:stretch !important}.is-flex-grow-0{flex-grow:0 !important}.is-flex-grow-1{flex-grow:1 !important}.is-flex-grow-2{flex-grow:2 !important}.is-flex-grow-3{flex-grow:3 !important}.is-flex-grow-4{flex-grow:4 !important}.is-flex-grow-5{flex-grow:5 !important}.is-flex-shrink-0{flex-shrink:0 !important}.is-flex-shrink-1{flex-shrink:1 !important}.is-flex-shrink-2{flex-shrink:2 !important}.is-flex-shrink-3{flex-shrink:3 !important}.is-flex-shrink-4{flex-shrink:4 !important}.is-flex-shrink-5{flex-shrink:5 !important}.is-clearfix::after{clear:both;content:" ";display:table}.is-pulled-left{float:left !important}.is-pulled-right{float:right !important}.is-radiusless{border-radius:0 !important}.is-shadowless{box-shadow:none !important}.is-clickable{cursor:pointer !important;pointer-events:all !important}.is-clipped{overflow:hidden !important}.is-relative{position:relative !important}.is-marginless{margin:0 !important}.is-paddingless{padding:0 !important}.m-0{margin:0 !important}.mt-0{margin-top:0 !important}.mr-0{margin-right:0 !important}.mb-0{margin-bottom:0 !important}.ml-0{margin-left:0 !important}.mx-0{margin-left:0 !important;margin-right:0 !important}.my-0{margin-top:0 !important;margin-bottom:0 !important}.m-1{margin:.25rem !important}.mt-1{margin-top:.25rem !important}.mr-1{margin-right:.25rem !important}.mb-1{margin-bottom:.25rem !important}.ml-1{margin-left:.25rem !important}.mx-1{margin-left:.25rem !important;margin-right:.25rem !important}.my-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.m-2{margin:.5rem !important}.mt-2{margin-top:.5rem !important}.mr-2{margin-right:.5rem !important}.mb-2{margin-bottom:.5rem !important}.ml-2{margin-left:.5rem !important}.mx-2{margin-left:.5rem !important;margin-right:.5rem !important}.my-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.m-3{margin:.75rem !important}.mt-3{margin-top:.75rem !important}.mr-3{margin-right:.75rem !important}.mb-3{margin-bottom:.75rem !important}.ml-3{margin-left:.75rem !important}.mx-3{margin-left:.75rem !important;margin-right:.75rem !important}.my-3{margin-top:.75rem !important;margin-bottom:.75rem !important}.m-4{margin:1rem !important}.mt-4{margin-top:1rem !important}.mr-4{margin-right:1rem !important}.mb-4{margin-bottom:1rem !important}.ml-4{margin-left:1rem !important}.mx-4{margin-left:1rem !important;margin-right:1rem !important}.my-4{margin-top:1rem !important;margin-bottom:1rem !important}.m-5{margin:1.5rem !important}.mt-5{margin-top:1.5rem !important}.mr-5{margin-right:1.5rem !important}.mb-5{margin-bottom:1.5rem !important}.ml-5{margin-left:1.5rem !important}.mx-5{margin-left:1.5rem !important;margin-right:1.5rem !important}.my-5{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.m-6{margin:3rem !important}.mt-6{margin-top:3rem !important}.mr-6{margin-right:3rem !important}.mb-6{margin-bottom:3rem !important}.ml-6{margin-left:3rem !important}.mx-6{margin-left:3rem !important;margin-right:3rem !important}.my-6{margin-top:3rem !important;margin-bottom:3rem !important}.m-auto{margin:auto !important}.mt-auto{margin-top:auto !important}.mr-auto{margin-right:auto !important}.mb-auto{margin-bottom:auto !important}.ml-auto{margin-left:auto !important}.mx-auto{margin-left:auto !important;margin-right:auto !important}.my-auto{margin-top:auto !important;margin-bottom:auto !important}.p-0{padding:0 !important}.pt-0{padding-top:0 !important}.pr-0{padding-right:0 !important}.pb-0{padding-bottom:0 !important}.pl-0{padding-left:0 !important}.px-0{padding-left:0 !important;padding-right:0 !important}.py-0{padding-top:0 !important;padding-bottom:0 !important}.p-1{padding:.25rem !important}.pt-1{padding-top:.25rem !important}.pr-1{padding-right:.25rem !important}.pb-1{padding-bottom:.25rem !important}.pl-1{padding-left:.25rem !important}.px-1{padding-left:.25rem !important;padding-right:.25rem !important}.py-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.p-2{padding:.5rem !important}.pt-2{padding-top:.5rem !important}.pr-2{padding-right:.5rem !important}.pb-2{padding-bottom:.5rem !important}.pl-2{padding-left:.5rem !important}.px-2{padding-left:.5rem !important;padding-right:.5rem !important}.py-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.p-3{padding:.75rem !important}.pt-3{padding-top:.75rem !important}.pr-3{padding-right:.75rem !important}.pb-3{padding-bottom:.75rem !important}.pl-3{padding-left:.75rem !important}.px-3{padding-left:.75rem !important;padding-right:.75rem !important}.py-3{padding-top:.75rem !important;padding-bottom:.75rem !important}.p-4{padding:1rem !important}.pt-4{padding-top:1rem !important}.pr-4{padding-right:1rem !important}.pb-4{padding-bottom:1rem !important}.pl-4{padding-left:1rem !important}.px-4{padding-left:1rem !important;padding-right:1rem !important}.py-4{padding-top:1rem !important;padding-bottom:1rem !important}.p-5{padding:1.5rem !important}.pt-5{padding-top:1.5rem !important}.pr-5{padding-right:1.5rem !important}.pb-5{padding-bottom:1.5rem !important}.pl-5{padding-left:1.5rem !important}.px-5{padding-left:1.5rem !important;padding-right:1.5rem !important}.py-5{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.p-6{padding:3rem !important}.pt-6{padding-top:3rem !important}.pr-6{padding-right:3rem !important}.pb-6{padding-bottom:3rem !important}.pl-6{padding-left:3rem !important}.px-6{padding-left:3rem !important;padding-right:3rem !important}.py-6{padding-top:3rem !important;padding-bottom:3rem !important}.p-auto{padding:auto !important}.pt-auto{padding-top:auto !important}.pr-auto{padding-right:auto !important}.pb-auto{padding-bottom:auto !important}.pl-auto{padding-left:auto !important}.px-auto{padding-left:auto !important;padding-right:auto !important}.py-auto{padding-top:auto !important;padding-bottom:auto !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}.is-underlined{text-decoration:underline !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}}/*! minireset.css v0.0.6 | 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,video{height:auto;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:inherit}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,optgroup,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:inherit}table th{color:#222}@keyframes spinAround{from{transform:rotate(0deg)}to{transform:rotate(359deg)}}.box{background-color:#fff;border-radius:6px;box-shadow:#bbb;color:#222;display:block;padding:1.25rem}a.box:hover,a.box:focus{box-shadow:0 0.5em 1em -0.125em 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:#222;cursor:pointer;justify-content:center;padding-bottom:calc(0.5em - 1px);padding-left:1em;padding-right:1em;padding-top:calc(0.5em - 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.5em - 1px);margin-right:.25em}.button .icon:last-child:not(:first-child){margin-left:.25em;margin-right:calc(-0.5em - 1px)}.button .icon:first-child:last-child{margin-left:calc(-0.5em - 1px);margin-right:calc(-0.5em - 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-ghost{background:none;border-color:rgba(0,0,0,0);color:#2e63b8;text-decoration:none}.button.is-ghost:hover,.button.is-ghost.is-hovered{color:#2e63b8;text-decoration:underline}.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:#fff;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:#0a0a0a;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:rgba(0,0,0,0.7)}.button.is-light:hover,.button.is-light.is-hovered{background-color:#eee;border-color:transparent;color:rgba(0,0,0,0.7)}.button.is-light:focus,.button.is-light.is-focused{border-color:transparent;color:rgba(0,0,0,0.7)}.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:rgba(0,0,0,0.7)}.button.is-light[disabled],fieldset[disabled] .button.is-light{background-color:#f5f5f5;border-color:#f5f5f5;box-shadow:none}.button.is-light.is-inverted{background-color:rgba(0,0,0,0.7);color:#f5f5f5}.button.is-light.is-inverted:hover,.button.is-light.is-inverted.is-hovered{background-color:rgba(0,0,0,0.7)}.button.is-light.is-inverted[disabled],fieldset[disabled] .button.is-light.is-inverted{background-color:rgba(0,0,0,0.7);border-color:transparent;box-shadow:none;color:#f5f5f5}.button.is-light.is-loading::after{border-color:transparent transparent rgba(0,0,0,0.7) rgba(0,0,0,0.7) !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:rgba(0,0,0,0.7)}.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 rgba(0,0,0,0.7) rgba(0,0,0,0.7) !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:rgba(0,0,0,0.7);color:rgba(0,0,0,0.7)}.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:rgba(0,0,0,0.7);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:rgba(0,0,0,0.7);box-shadow:none;color:rgba(0,0,0,0.7)}.button.is-dark,.content kbd.button{background-color:#363636;border-color:transparent;color:#fff}.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:#fff}.button.is-dark:focus,.content kbd.button:focus,.button.is-dark.is-focused,.content kbd.button.is-focused{border-color:transparent;color:#fff}.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:#fff}.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:#363636;box-shadow:none}.button.is-dark.is-inverted,.content kbd.button.is-inverted{background-color:#fff;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:#f2f2f2}.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:#fff;border-color:transparent;box-shadow:none;color:#363636}.button.is-dark.is-loading::after,.content kbd.button.is-loading::after{border-color:transparent transparent #fff #fff !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:#fff}.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 #fff #fff !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:#fff;color:#fff}.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:#fff;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:#fff;box-shadow:none;color:#fff}.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:#4eb5de;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-primary.is-light,.docstring>section>a.button.is-light.docs-sourcelink{background-color:#eef8fc;color:#1a6d8e}.button.is-primary.is-light:hover,.docstring>section>a.button.is-light.docs-sourcelink:hover,.button.is-primary.is-light.is-hovered,.docstring>section>a.button.is-light.is-hovered.docs-sourcelink{background-color:#e3f3fa;border-color:transparent;color:#1a6d8e}.button.is-primary.is-light:active,.docstring>section>a.button.is-light.docs-sourcelink:active,.button.is-primary.is-light.is-active,.docstring>section>a.button.is-light.is-active.docs-sourcelink{background-color:#d8eff8;border-color:transparent;color:#1a6d8e}.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:#2e63b8;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-link.is-light{background-color:#eff3fb;color:#3169c4}.button.is-link.is-light:hover,.button.is-link.is-light.is-hovered{background-color:#e4ecf8;border-color:transparent;color:#3169c4}.button.is-link.is-light:active,.button.is-link.is-light.is-active{background-color:#dae5f6;border-color:transparent;color:#3169c4}.button.is-info{background-color:#3c5dcd;border-color:transparent;color:#fff}.button.is-info:hover,.button.is-info.is-hovered{background-color:#3355c9;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(60,93,205,0.25)}.button.is-info:active,.button.is-info.is-active{background-color:#3151bf;border-color:transparent;color:#fff}.button.is-info[disabled],fieldset[disabled] .button.is-info{background-color:#3c5dcd;border-color:#3c5dcd;box-shadow:none}.button.is-info.is-inverted{background-color:#fff;color:#3c5dcd}.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:#3c5dcd}.button.is-info.is-loading::after{border-color:transparent transparent #fff #fff !important}.button.is-info.is-outlined{background-color:transparent;border-color:#3c5dcd;color:#3c5dcd}.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:#3c5dcd;border-color:#3c5dcd;color:#fff}.button.is-info.is-outlined.is-loading::after{border-color:transparent transparent #3c5dcd #3c5dcd !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:#3c5dcd;box-shadow:none;color:#3c5dcd}.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:#3c5dcd}.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 #3c5dcd #3c5dcd !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-info.is-light{background-color:#eff2fb;color:#3253c3}.button.is-info.is-light:hover,.button.is-info.is-light.is-hovered{background-color:#e5e9f8;border-color:transparent;color:#3253c3}.button.is-info.is-light:active,.button.is-info.is-light.is-active{background-color:#dae1f6;border-color:transparent;color:#3253c3}.button.is-success{background-color:#259a12;border-color:transparent;color:#fff}.button.is-success:hover,.button.is-success.is-hovered{background-color:#228f11;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(37,154,18,0.25)}.button.is-success:active,.button.is-success.is-active{background-color:#20830f;border-color:transparent;color:#fff}.button.is-success[disabled],fieldset[disabled] .button.is-success{background-color:#259a12;border-color:#259a12;box-shadow:none}.button.is-success.is-inverted{background-color:#fff;color:#259a12}.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:#259a12}.button.is-success.is-loading::after{border-color:transparent transparent #fff #fff !important}.button.is-success.is-outlined{background-color:transparent;border-color:#259a12;color:#259a12}.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:#259a12;border-color:#259a12;color:#fff}.button.is-success.is-outlined.is-loading::after{border-color:transparent transparent #259a12 #259a12 !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:#259a12;box-shadow:none;color:#259a12}.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:#259a12}.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 #259a12 #259a12 !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-success.is-light{background-color:#effded;color:#2ec016}.button.is-success.is-light:hover,.button.is-success.is-light.is-hovered{background-color:#e5fce1;border-color:transparent;color:#2ec016}.button.is-success.is-light:active,.button.is-success.is-light.is-active{background-color:#dbfad6;border-color:transparent;color:#2ec016}.button.is-warning{background-color:#a98800;border-color:transparent;color:#fff}.button.is-warning:hover,.button.is-warning.is-hovered{background-color:#9c7d00;border-color:transparent;color:#fff}.button.is-warning:focus,.button.is-warning.is-focused{border-color:transparent;color:#fff}.button.is-warning:focus:not(:active),.button.is-warning.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(169,136,0,0.25)}.button.is-warning:active,.button.is-warning.is-active{background-color:#8f7300;border-color:transparent;color:#fff}.button.is-warning[disabled],fieldset[disabled] .button.is-warning{background-color:#a98800;border-color:#a98800;box-shadow:none}.button.is-warning.is-inverted{background-color:#fff;color:#a98800}.button.is-warning.is-inverted:hover,.button.is-warning.is-inverted.is-hovered{background-color:#f2f2f2}.button.is-warning.is-inverted[disabled],fieldset[disabled] .button.is-warning.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#a98800}.button.is-warning.is-loading::after{border-color:transparent transparent #fff #fff !important}.button.is-warning.is-outlined{background-color:transparent;border-color:#a98800;color:#a98800}.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:#a98800;border-color:#a98800;color:#fff}.button.is-warning.is-outlined.is-loading::after{border-color:transparent transparent #a98800 #a98800 !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 #fff #fff !important}.button.is-warning.is-outlined[disabled],fieldset[disabled] .button.is-warning.is-outlined{background-color:transparent;border-color:#a98800;box-shadow:none;color:#a98800}.button.is-warning.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}.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:#fff;color:#a98800}.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 #a98800 #a98800 !important}.button.is-warning.is-inverted.is-outlined[disabled],fieldset[disabled] .button.is-warning.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}.button.is-warning.is-light{background-color:#fffbeb;color:#cca400}.button.is-warning.is-light:hover,.button.is-warning.is-light.is-hovered{background-color:#fff9de;border-color:transparent;color:#cca400}.button.is-warning.is-light:active,.button.is-warning.is-light.is-active{background-color:#fff6d1;border-color:transparent;color:#cca400}.button.is-danger{background-color:#cb3c33;border-color:transparent;color:#fff}.button.is-danger:hover,.button.is-danger.is-hovered{background-color:#c13930;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(203,60,51,0.25)}.button.is-danger:active,.button.is-danger.is-active{background-color:#b7362e;border-color:transparent;color:#fff}.button.is-danger[disabled],fieldset[disabled] .button.is-danger{background-color:#cb3c33;border-color:#cb3c33;box-shadow:none}.button.is-danger.is-inverted{background-color:#fff;color:#cb3c33}.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:#cb3c33}.button.is-danger.is-loading::after{border-color:transparent transparent #fff #fff !important}.button.is-danger.is-outlined{background-color:transparent;border-color:#cb3c33;color:#cb3c33}.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:#cb3c33;border-color:#cb3c33;color:#fff}.button.is-danger.is-outlined.is-loading::after{border-color:transparent transparent #cb3c33 #cb3c33 !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:#cb3c33;box-shadow:none;color:#cb3c33}.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:#cb3c33}.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 #cb3c33 #cb3c33 !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-danger.is-light{background-color:#fbefef;color:#c03930}.button.is-danger.is-light:hover,.button.is-danger.is-light.is-hovered{background-color:#f8e6e5;border-color:transparent;color:#c03930}.button.is-danger.is-light:active,.button.is-danger.is-light.is-active{background-color:#f6dcda;border-color:transparent;color:#c03930}.button.is-small,#documenter .docs-sidebar form.docs-search>input.button{font-size:.75rem}.button.is-small:not(.is-rounded),#documenter .docs-sidebar form.docs-search>input.button:not(.is-rounded){border-radius:2px}.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 * 0.5));top:calc(50% - (1em * 0.5));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:9999px;padding-left:calc(1em + 0.25em);padding-right:calc(1em + 0.25em)}.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:.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){font-size:.75rem}.buttons.are-small .button:not(.is-normal):not(.is-medium):not(.is-large):not(.is-rounded){border-radius:2px}.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}@media screen and (max-width: 768px){.button.is-responsive.is-small,#documenter .docs-sidebar form.docs-search>input.is-responsive{font-size:.5625rem}.button.is-responsive,.button.is-responsive.is-normal{font-size:.65625rem}.button.is-responsive.is-medium{font-size:.75rem}.button.is-responsive.is-large{font-size:1rem}}@media screen and (min-width: 769px) and (max-width: 1055px){.button.is-responsive.is-small,#documenter .docs-sidebar form.docs-search>input.is-responsive{font-size:.65625rem}.button.is-responsive,.button.is-responsive.is-normal{font-size:.75rem}.button.is-responsive.is-medium{font-size:1rem}.button.is-responsive.is-large{font-size:1.25rem}}.container{flex-grow:1;margin:0 auto;position:relative;width:auto}.container.is-fluid{max-width:none !important;padding-left:32px;padding-right:32px;width:100%}@media screen and (min-width: 1056px){.container{max-width:992px}}@media screen and (max-width: 1215px){.container.is-widescreen:not(.is-max-desktop){max-width:1152px}}@media screen and (max-width: 1407px){.container.is-fullhd:not(.is-max-desktop):not(.is-max-widescreen){max-width:1344px}}@media screen and (min-width: 1216px){.container:not(.is-max-desktop){max-width:1152px}}@media screen and (min-width: 1408px){.container:not(.is-max-desktop):not(.is-max-widescreen){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:inherit}.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-normal{font-size:1rem}.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}.icon-text{align-items:flex-start;color:inherit;display:inline-flex;flex-wrap:wrap;line-height:1.5rem;vertical-align:top}.icon-text .icon{flex-grow:0;flex-shrink:0}.icon-text .icon:not(:last-child){margin-right:.25em}.icon-text .icon:not(:first-child){margin-left:.25em}div.icon-text{display:flex}.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:9999px}.image.is-fullwidth,#documenter .docs-sidebar .docs-logo>img.is-fullwidth{width:100%}.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;position:relative;padding:1.25rem 2.5rem 1.25rem 1.5rem}.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{right:.5rem;position:absolute;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:rgba(0,0,0,0.7)}.notification.is-dark,.content kbd.notification{background-color:#363636;color:#fff}.notification.is-primary,.docstring>section>a.notification.docs-sourcelink{background-color:#4eb5de;color:#fff}.notification.is-primary.is-light,.docstring>section>a.notification.is-light.docs-sourcelink{background-color:#eef8fc;color:#1a6d8e}.notification.is-link{background-color:#2e63b8;color:#fff}.notification.is-link.is-light{background-color:#eff3fb;color:#3169c4}.notification.is-info{background-color:#3c5dcd;color:#fff}.notification.is-info.is-light{background-color:#eff2fb;color:#3253c3}.notification.is-success{background-color:#259a12;color:#fff}.notification.is-success.is-light{background-color:#effded;color:#2ec016}.notification.is-warning{background-color:#a98800;color:#fff}.notification.is-warning.is-light{background-color:#fffbeb;color:#cca400}.notification.is-danger{background-color:#cb3c33;color:#fff}.notification.is-danger.is-light{background-color:#fbefef;color:#c03930}.progress{-moz-appearance:none;-webkit-appearance:none;border:none;border-radius:9999px;display:block;height:1rem;overflow:hidden;padding:0;width:100%}.progress::-webkit-progress-bar{background-color:#ededed}.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%, #ededed 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%, #ededed 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%, #ededed 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%, #ededed 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%, #ededed 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%, #ededed 30%)}.progress.is-info::-webkit-progress-value{background-color:#3c5dcd}.progress.is-info::-moz-progress-bar{background-color:#3c5dcd}.progress.is-info::-ms-fill{background-color:#3c5dcd}.progress.is-info:indeterminate{background-image:linear-gradient(to right, #3c5dcd 30%, #ededed 30%)}.progress.is-success::-webkit-progress-value{background-color:#259a12}.progress.is-success::-moz-progress-bar{background-color:#259a12}.progress.is-success::-ms-fill{background-color:#259a12}.progress.is-success:indeterminate{background-image:linear-gradient(to right, #259a12 30%, #ededed 30%)}.progress.is-warning::-webkit-progress-value{background-color:#a98800}.progress.is-warning::-moz-progress-bar{background-color:#a98800}.progress.is-warning::-ms-fill{background-color:#a98800}.progress.is-warning:indeterminate{background-image:linear-gradient(to right, #a98800 30%, #ededed 30%)}.progress.is-danger::-webkit-progress-value{background-color:#cb3c33}.progress.is-danger::-moz-progress-bar{background-color:#cb3c33}.progress.is-danger::-ms-fill{background-color:#cb3c33}.progress.is-danger:indeterminate{background-image:linear-gradient(to right, #cb3c33 30%, #ededed 30%)}.progress:indeterminate{animation-duration:1.5s;animation-iteration-count:infinite;animation-name:moveIndeterminate;animation-timing-function:linear;background-color:#ededed;background-image:linear-gradient(to right, #222 30%, #ededed 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:indeterminate::-ms-fill{animation-name:none}.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:#222}.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:rgba(0,0,0,0.7)}.table td.is-dark,.table th.is-dark{background-color:#363636;border-color:#363636;color:#fff}.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:#3c5dcd;border-color:#3c5dcd;color:#fff}.table td.is-success,.table th.is-success{background-color:#259a12;border-color:#259a12;color:#fff}.table td.is-warning,.table th.is-warning{background-color:#a98800;border-color:#a98800;color:#fff}.table td.is-danger,.table th.is-danger{background-color:#cb3c33;border-color:#cb3c33;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 td.is-vcentered,.table th.is-vcentered{vertical-align:middle}.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:.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-top-left-radius:0;border-bottom-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-top-right-radius:0;border-bottom-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:.25rem;margin-right:-.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:rgba(0,0,0,0.7)}.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:#fff}.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-primary.is-light:not(body),.content kbd.is-primary.is-light:not(body),.docstring>section>a.docs-sourcelink.is-light:not(body){background-color:#eef8fc;color:#1a6d8e}.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-link.is-light:not(body),.content kbd.is-link.is-light:not(body),.docstring>section>a.docs-sourcelink.is-link.is-light:not(body){background-color:#eff3fb;color:#3169c4}.tag.is-info:not(body),.content kbd.is-info:not(body),.docstring>section>a.docs-sourcelink.is-info:not(body){background-color:#3c5dcd;color:#fff}.tag.is-info.is-light:not(body),.content kbd.is-info.is-light:not(body),.docstring>section>a.docs-sourcelink.is-info.is-light:not(body){background-color:#eff2fb;color:#3253c3}.tag.is-success:not(body),.content kbd.is-success:not(body),.docstring>section>a.docs-sourcelink.is-success:not(body){background-color:#259a12;color:#fff}.tag.is-success.is-light:not(body),.content kbd.is-success.is-light:not(body),.docstring>section>a.docs-sourcelink.is-success.is-light:not(body){background-color:#effded;color:#2ec016}.tag.is-warning:not(body),.content kbd.is-warning:not(body),.docstring>section>a.docs-sourcelink.is-warning:not(body){background-color:#a98800;color:#fff}.tag.is-warning.is-light:not(body),.content kbd.is-warning.is-light:not(body),.docstring>section>a.docs-sourcelink.is-warning.is-light:not(body){background-color:#fffbeb;color:#cca400}.tag.is-danger:not(body),.content kbd.is-danger:not(body),.docstring>section>a.docs-sourcelink.is-danger:not(body){background-color:#cb3c33;color:#fff}.tag.is-danger.is-light:not(body),.content kbd.is-danger.is-light:not(body),.docstring>section>a.docs-sourcelink.is-danger.is-light:not(body){background-color:#fbefef;color:#c03930}.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:-.375em;margin-right:.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:.1875em;margin-right:-.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:-.375em;margin-right:-.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:9999px}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:#222;font-size:2rem;font-weight:600;line-height:1.125}.title strong{color:inherit;font-weight:inherit}.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:#222;font-size:1.25rem;font-weight:400;line-height:1.25}.subtitle strong{color:#222;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}.number{align-items:center;background-color:#f5f5f5;border-radius:9999px;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:#222}.select select::-moz-placeholder,.textarea::-moz-placeholder,.input::-moz-placeholder,#documenter .docs-sidebar form.docs-search>input::-moz-placeholder{color:#707070}.select select::-webkit-input-placeholder,.textarea::-webkit-input-placeholder,.input::-webkit-input-placeholder,#documenter .docs-sidebar form.docs-search>input::-webkit-input-placeholder{color:#707070}.select select:-moz-placeholder,.textarea:-moz-placeholder,.input:-moz-placeholder,#documenter .docs-sidebar form.docs-search>input:-moz-placeholder{color:#707070}.select select:-ms-input-placeholder,.textarea:-ms-input-placeholder,.input:-ms-input-placeholder,#documenter .docs-sidebar form.docs-search>input:-ms-input-placeholder{color:#707070}.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 0.0625em 0.125em rgba(10,10,10,0.05);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:#3c5dcd}.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(60,93,205,0.25)}.is-success.textarea,.is-success.input,#documenter .docs-sidebar form.docs-search>input.is-success{border-color:#259a12}.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(37,154,18,0.25)}.is-warning.textarea,.is-warning.input,#documenter .docs-sidebar form.docs-search>input.is-warning{border-color:#a98800}.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(169,136,0,0.25)}.is-danger.textarea,.is-danger.input,#documenter .docs-sidebar form.docs-search>input.is-danger{border-color:#cb3c33}.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(203,60,51,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:9999px;padding-left:calc(calc(0.75em - 1px) + 0.375em);padding-right:calc(calc(0.75em - 1px) + 0.375em)}.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:calc(0.75em - 1px);resize:vertical}.textarea:not([rows]){max-height:40em;min-height:8em}.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:#222}.radio[disabled],.checkbox[disabled],fieldset[disabled] .radio,fieldset[disabled] .checkbox,.radio input[disabled],.checkbox input[disabled]{color:#6b6b6b;cursor:not-allowed}.radio+.radio{margin-left:.5em}.select{display:inline-block;max-width:100%;position:relative;vertical-align:top}.select:not(.is-multiple){height:2.5em}.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:9999px;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:#222}.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:#3c5dcd}.select.is-info select{border-color:#3c5dcd}.select.is-info select:hover,.select.is-info select.is-hovered{border-color:#3151bf}.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(60,93,205,0.25)}.select.is-success:not(:hover)::after{border-color:#259a12}.select.is-success select{border-color:#259a12}.select.is-success select:hover,.select.is-success select.is-hovered{border-color:#20830f}.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(37,154,18,0.25)}.select.is-warning:not(:hover)::after{border-color:#a98800}.select.is-warning select{border-color:#a98800}.select.is-warning select:hover,.select.is-warning select.is-hovered{border-color:#8f7300}.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(169,136,0,0.25)}.select.is-danger:not(:hover)::after{border-color:#cb3c33}.select.is-danger select{border-color:#cb3c33}.select.is-danger select:hover,.select.is-danger select.is-hovered{border-color:#b7362e}.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(203,60,51,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 !important;opacity:0.5}.select.is-fullwidth{width:100%}.select.is-fullwidth select{width:100%}.select.is-loading::after{margin-top:0;position:absolute;right:.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:rgba(0,0,0,0.7)}.file.is-light:hover .file-cta,.file.is-light.is-hovered .file-cta{background-color:#eee;border-color:transparent;color:rgba(0,0,0,0.7)}.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:rgba(0,0,0,0.7)}.file.is-light:active .file-cta,.file.is-light.is-active .file-cta{background-color:#e8e8e8;border-color:transparent;color:rgba(0,0,0,0.7)}.file.is-dark .file-cta,.content kbd.file .file-cta{background-color:#363636;border-color:transparent;color:#fff}.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:#fff}.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:#fff}.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:#fff}.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:#3c5dcd;border-color:transparent;color:#fff}.file.is-info:hover .file-cta,.file.is-info.is-hovered .file-cta{background-color:#3355c9;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(60,93,205,0.25);color:#fff}.file.is-info:active .file-cta,.file.is-info.is-active .file-cta{background-color:#3151bf;border-color:transparent;color:#fff}.file.is-success .file-cta{background-color:#259a12;border-color:transparent;color:#fff}.file.is-success:hover .file-cta,.file.is-success.is-hovered .file-cta{background-color:#228f11;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(37,154,18,0.25);color:#fff}.file.is-success:active .file-cta,.file.is-success.is-active .file-cta{background-color:#20830f;border-color:transparent;color:#fff}.file.is-warning .file-cta{background-color:#a98800;border-color:transparent;color:#fff}.file.is-warning:hover .file-cta,.file.is-warning.is-hovered .file-cta{background-color:#9c7d00;border-color:transparent;color:#fff}.file.is-warning:focus .file-cta,.file.is-warning.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(169,136,0,0.25);color:#fff}.file.is-warning:active .file-cta,.file.is-warning.is-active .file-cta{background-color:#8f7300;border-color:transparent;color:#fff}.file.is-danger .file-cta{background-color:#cb3c33;border-color:transparent;color:#fff}.file.is-danger:hover .file-cta,.file.is-danger.is-hovered .file-cta{background-color:#c13930;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(203,60,51,0.25);color:#fff}.file.is-danger:active .file-cta,.file.is-danger.is-active .file-cta{background-color:#b7362e;border-color:transparent;color:#fff}.file.is-small,#documenter .docs-sidebar form.docs-search>input.file{font-size:.75rem}.file.is-normal{font-size:1rem}.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:#222}.file-label:hover .file-name{border-color:#d5d5d5}.file-label:active .file-cta{background-color:#e8e8e8;color:#222}.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:#222}.file-name{border-color:#dbdbdb;border-style:solid;border-width:1px 1px 1px 0;display:block;max-width:16em;overflow:hidden;text-align:inherit;text-overflow:ellipsis}.file-icon{align-items:center;display:flex;height:1em;justify-content:center;margin-right:.5em;width:1em}.file-icon .fa{font-size:14px}.label{color:#222;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:#3c5dcd}.help.is-success{color:#259a12}.help.is-warning{color:#a98800}.help.is-danger{color:#cb3c33}.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:.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:.75rem}}.control{box-sizing:border-box;clear:both;font-size:1rem;position:relative;text-align:inherit}.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:#222}.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.5em;pointer-events:none;position:absolute;top:0;width:2.5em;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.5em}.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.5em}.control.has-icons-right .icon.is-right{right:0}.control.is-loading::after{position:absolute !important;right:.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:.5em}.breadcrumb .icon:last-child{margin-left:.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;border-radius:.25rem;box-shadow:#bbb;color:#222;max-width:100%;position:relative}.card-footer:first-child,.card-content:first-child,.card-header:first-child{border-top-left-radius:.25rem;border-top-right-radius:.25rem}.card-footer:last-child,.card-content:last-child,.card-header:last-child{border-bottom-left-radius:.25rem;border-bottom-right-radius:.25rem}.card-header{background-color:rgba(0,0,0,0);align-items:stretch;box-shadow:0 0.125em 0.25em 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:0.75rem 1rem}.card-header-title.is-centered{justify-content:center}.card-header-icon{-moz-appearance:none;-webkit-appearance:none;appearance:none;background:none;border:none;color:currentColor;font-family:inherit;font-size:1em;margin:0;padding:0;align-items:center;cursor:pointer;display:flex;justify-content:center;padding:0.75rem 1rem}.card-image{display:block;position:relative}.card-image:first-child img{border-top-left-radius:.25rem;border-top-right-radius:.25rem}.card-image:last-child img{border-bottom-left-radius:.25rem;border-bottom-right-radius:.25rem}.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 #ededed;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 #ededed}.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:#bbb;padding-bottom:.5rem;padding-top:.5rem}.dropdown-item{color:#222;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:inherit;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:#ededed;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}}.media{align-items:flex-start;display:flex;text-align:inherit}.media .content:not(:last-child){margin-bottom:.75rem}.media .media{border-top:1px solid rgba(219,219,219,0.5);display:flex;padding-top:.75rem}.media .media .content:not(:last-child),.media .media .control:not(:last-child){margin-bottom:.5rem}.media .media .media{padding-top:.5rem}.media .media .media+.media{margin-top:.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:inherit}@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}.message.is-black{background-color:#fafafa}.message.is-black .message-header{background-color:#0a0a0a;color:#fff}.message.is-black .message-body{border-color:#0a0a0a}.message.is-light{background-color:#fafafa}.message.is-light .message-header{background-color:#f5f5f5;color:rgba(0,0,0,0.7)}.message.is-light .message-body{border-color:#f5f5f5}.message.is-dark,.content kbd.message{background-color:#fafafa}.message.is-dark .message-header,.content kbd.message .message-header{background-color:#363636;color:#fff}.message.is-dark .message-body,.content kbd.message .message-body{border-color:#363636}.message.is-primary,.docstring>section>a.message.docs-sourcelink{background-color:#eef8fc}.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:#1a6d8e}.message.is-link{background-color:#eff3fb}.message.is-link .message-header{background-color:#2e63b8;color:#fff}.message.is-link .message-body{border-color:#2e63b8;color:#3169c4}.message.is-info{background-color:#eff2fb}.message.is-info .message-header{background-color:#3c5dcd;color:#fff}.message.is-info .message-body{border-color:#3c5dcd;color:#3253c3}.message.is-success{background-color:#effded}.message.is-success .message-header{background-color:#259a12;color:#fff}.message.is-success .message-body{border-color:#259a12;color:#2ec016}.message.is-warning{background-color:#fffbeb}.message.is-warning .message-header{background-color:#a98800;color:#fff}.message.is-warning .message-body{border-color:#a98800;color:#cca400}.message.is-danger{background-color:#fbefef}.message.is-danger .message-header{background-color:#cb3c33;color:#fff}.message.is-danger .message-body{border-color:#cb3c33;color:#c03930}.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:.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){.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:.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:rgba(0,0,0,0.7)}.navbar.is-light .navbar-brand>.navbar-item,.navbar.is-light .navbar-brand .navbar-link{color:rgba(0,0,0,0.7)}.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:rgba(0,0,0,0.7)}.navbar.is-light .navbar-brand .navbar-link::after{border-color:rgba(0,0,0,0.7)}.navbar.is-light .navbar-burger{color:rgba(0,0,0,0.7)}@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:rgba(0,0,0,0.7)}.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:rgba(0,0,0,0.7)}.navbar.is-light .navbar-start .navbar-link::after,.navbar.is-light .navbar-end .navbar-link::after{border-color:rgba(0,0,0,0.7)}.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:rgba(0,0,0,0.7)}.navbar.is-light .navbar-dropdown a.navbar-item.is-active{background-color:#f5f5f5;color:rgba(0,0,0,0.7)}}.navbar.is-dark,.content kbd.navbar{background-color:#363636;color:#fff}.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:#fff}.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:#fff}.navbar.is-dark .navbar-brand .navbar-link::after,.content kbd.navbar .navbar-brand .navbar-link::after{border-color:#fff}.navbar.is-dark .navbar-burger,.content kbd.navbar .navbar-burger{color:#fff}@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:#fff}.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:#fff}.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:#fff}.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:#fff}.navbar.is-dark .navbar-dropdown a.navbar-item.is-active,.content kbd.navbar .navbar-dropdown a.navbar-item.is-active{background-color:#363636;color:#fff}}.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:#3c5dcd;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:#3151bf;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:#3151bf;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:#3151bf;color:#fff}.navbar.is-info .navbar-dropdown a.navbar-item.is-active{background-color:#3c5dcd;color:#fff}}.navbar.is-success{background-color:#259a12;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:#20830f;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:#20830f;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:#20830f;color:#fff}.navbar.is-success .navbar-dropdown a.navbar-item.is-active{background-color:#259a12;color:#fff}}.navbar.is-warning{background-color:#a98800;color:#fff}.navbar.is-warning .navbar-brand>.navbar-item,.navbar.is-warning .navbar-brand .navbar-link{color:#fff}.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:#8f7300;color:#fff}.navbar.is-warning .navbar-brand .navbar-link::after{border-color:#fff}.navbar.is-warning .navbar-burger{color:#fff}@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:#fff}.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:#8f7300;color:#fff}.navbar.is-warning .navbar-start .navbar-link::after,.navbar.is-warning .navbar-end .navbar-link::after{border-color:#fff}.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:#8f7300;color:#fff}.navbar.is-warning .navbar-dropdown a.navbar-item.is-active{background-color:#a98800;color:#fff}}.navbar.is-danger{background-color:#cb3c33;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:#b7362e;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:#b7362e;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:#b7362e;color:#fff}.navbar.is-danger .navbar-dropdown a.navbar-item.is-active{background-color:#cb3c33;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:#222;-moz-appearance:none;-webkit-appearance:none;appearance:none;background:none;border:none;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:#222;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{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.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:9999px}.pagination.is-rounded .pagination-link,#documenter .docs-sidebar form.docs-search>input.pagination .pagination-link{border-radius:9999px}.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:#222;min-width:2.5em}.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-previous.is-disabled,.pagination-next[disabled],.pagination-next.is-disabled,.pagination-link[disabled],.pagination-link.is-disabled{background-color:#dbdbdb;border-color:#dbdbdb;box-shadow:none;color:#6b6b6b;opacity:0.5}.pagination-previous,.pagination-next{padding-left:.75em;padding-right:.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}.pagination-list li{list-style:none}@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,.pagination-next,.pagination-link,.pagination-ellipsis{margin-bottom:0;margin-top:0}.pagination-previous{order:2}.pagination-next{order:3}.pagination{justify-content:space-between;margin-bottom:0;margin-top:0}.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{border-radius:6px;box-shadow:#bbb;font-size:1rem}.panel:not(:last-child){margin-bottom:1.5rem}.panel.is-white .panel-heading{background-color:#fff;color:#0a0a0a}.panel.is-white .panel-tabs a.is-active{border-bottom-color:#fff}.panel.is-white .panel-block.is-active .panel-icon{color:#fff}.panel.is-black .panel-heading{background-color:#0a0a0a;color:#fff}.panel.is-black .panel-tabs a.is-active{border-bottom-color:#0a0a0a}.panel.is-black .panel-block.is-active .panel-icon{color:#0a0a0a}.panel.is-light .panel-heading{background-color:#f5f5f5;color:rgba(0,0,0,0.7)}.panel.is-light .panel-tabs a.is-active{border-bottom-color:#f5f5f5}.panel.is-light .panel-block.is-active .panel-icon{color:#f5f5f5}.panel.is-dark .panel-heading,.content kbd.panel .panel-heading{background-color:#363636;color:#fff}.panel.is-dark .panel-tabs a.is-active,.content kbd.panel .panel-tabs a.is-active{border-bottom-color:#363636}.panel.is-dark .panel-block.is-active .panel-icon,.content kbd.panel .panel-block.is-active .panel-icon{color:#363636}.panel.is-primary .panel-heading,.docstring>section>a.panel.docs-sourcelink .panel-heading{background-color:#4eb5de;color:#fff}.panel.is-primary .panel-tabs a.is-active,.docstring>section>a.panel.docs-sourcelink .panel-tabs a.is-active{border-bottom-color:#4eb5de}.panel.is-primary .panel-block.is-active .panel-icon,.docstring>section>a.panel.docs-sourcelink .panel-block.is-active .panel-icon{color:#4eb5de}.panel.is-link .panel-heading{background-color:#2e63b8;color:#fff}.panel.is-link .panel-tabs a.is-active{border-bottom-color:#2e63b8}.panel.is-link .panel-block.is-active .panel-icon{color:#2e63b8}.panel.is-info .panel-heading{background-color:#3c5dcd;color:#fff}.panel.is-info .panel-tabs a.is-active{border-bottom-color:#3c5dcd}.panel.is-info .panel-block.is-active .panel-icon{color:#3c5dcd}.panel.is-success .panel-heading{background-color:#259a12;color:#fff}.panel.is-success .panel-tabs a.is-active{border-bottom-color:#259a12}.panel.is-success .panel-block.is-active .panel-icon{color:#259a12}.panel.is-warning .panel-heading{background-color:#a98800;color:#fff}.panel.is-warning .panel-tabs a.is-active{border-bottom-color:#a98800}.panel.is-warning .panel-block.is-active .panel-icon{color:#a98800}.panel.is-danger .panel-heading{background-color:#cb3c33;color:#fff}.panel.is-danger .panel-tabs a.is-active{border-bottom-color:#cb3c33}.panel.is-danger .panel-block.is-active .panel-icon{color:#cb3c33}.panel-tabs:not(:last-child),.panel-block:not(:last-child){border-bottom:1px solid #ededed}.panel-heading{background-color:#ededed;border-radius:6px 6px 0 0;color:#222;font-size:1.25em;font-weight:700;line-height:1.25;padding:0.75em 1em}.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:.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}.panel-block:last-child{border-bottom-left-radius:6px;border-bottom-right-radius:6px}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:.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:.5em}.tabs .icon:last-child{margin-left:.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-top-left-radius:4px;border-bottom-left-radius:4px}.tabs.is-toggle li:last-child a{border-top-right-radius:4px;border-bottom-right-radius:4px}.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:9999px;border-top-left-radius:9999px;padding-left:1.25em}.tabs.is-toggle.is-toggle-rounded li:last-child a{border-bottom-right-radius:9999px;border-top-right-radius:9999px;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;width:unset}.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.33333337%}.columns.is-mobile>.column.is-offset-1{margin-left:8.33333337%}.columns.is-mobile>.column.is-2{flex:none;width:16.66666674%}.columns.is-mobile>.column.is-offset-2{margin-left:16.66666674%}.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.33333337%}.columns.is-mobile>.column.is-offset-4{margin-left:33.33333337%}.columns.is-mobile>.column.is-5{flex:none;width:41.66666674%}.columns.is-mobile>.column.is-offset-5{margin-left:41.66666674%}.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.33333337%}.columns.is-mobile>.column.is-offset-7{margin-left:58.33333337%}.columns.is-mobile>.column.is-8{flex:none;width:66.66666674%}.columns.is-mobile>.column.is-offset-8{margin-left:66.66666674%}.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.33333337%}.columns.is-mobile>.column.is-offset-10{margin-left:83.33333337%}.columns.is-mobile>.column.is-11{flex:none;width:91.66666674%}.columns.is-mobile>.column.is-offset-11{margin-left:91.66666674%}.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;width:unset}.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.33333337%}.column.is-offset-1-mobile{margin-left:8.33333337%}.column.is-2-mobile{flex:none;width:16.66666674%}.column.is-offset-2-mobile{margin-left:16.66666674%}.column.is-3-mobile{flex:none;width:25%}.column.is-offset-3-mobile{margin-left:25%}.column.is-4-mobile{flex:none;width:33.33333337%}.column.is-offset-4-mobile{margin-left:33.33333337%}.column.is-5-mobile{flex:none;width:41.66666674%}.column.is-offset-5-mobile{margin-left:41.66666674%}.column.is-6-mobile{flex:none;width:50%}.column.is-offset-6-mobile{margin-left:50%}.column.is-7-mobile{flex:none;width:58.33333337%}.column.is-offset-7-mobile{margin-left:58.33333337%}.column.is-8-mobile{flex:none;width:66.66666674%}.column.is-offset-8-mobile{margin-left:66.66666674%}.column.is-9-mobile{flex:none;width:75%}.column.is-offset-9-mobile{margin-left:75%}.column.is-10-mobile{flex:none;width:83.33333337%}.column.is-offset-10-mobile{margin-left:83.33333337%}.column.is-11-mobile{flex:none;width:91.66666674%}.column.is-offset-11-mobile{margin-left:91.66666674%}.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;width:unset}.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.33333337%}.column.is-offset-1,.column.is-offset-1-tablet{margin-left:8.33333337%}.column.is-2,.column.is-2-tablet{flex:none;width:16.66666674%}.column.is-offset-2,.column.is-offset-2-tablet{margin-left:16.66666674%}.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.33333337%}.column.is-offset-4,.column.is-offset-4-tablet{margin-left:33.33333337%}.column.is-5,.column.is-5-tablet{flex:none;width:41.66666674%}.column.is-offset-5,.column.is-offset-5-tablet{margin-left:41.66666674%}.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.33333337%}.column.is-offset-7,.column.is-offset-7-tablet{margin-left:58.33333337%}.column.is-8,.column.is-8-tablet{flex:none;width:66.66666674%}.column.is-offset-8,.column.is-offset-8-tablet{margin-left:66.66666674%}.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.33333337%}.column.is-offset-10,.column.is-offset-10-tablet{margin-left:83.33333337%}.column.is-11,.column.is-11-tablet{flex:none;width:91.66666674%}.column.is-offset-11,.column.is-offset-11-tablet{margin-left:91.66666674%}.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;width:unset}.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.33333337%}.column.is-offset-1-touch{margin-left:8.33333337%}.column.is-2-touch{flex:none;width:16.66666674%}.column.is-offset-2-touch{margin-left:16.66666674%}.column.is-3-touch{flex:none;width:25%}.column.is-offset-3-touch{margin-left:25%}.column.is-4-touch{flex:none;width:33.33333337%}.column.is-offset-4-touch{margin-left:33.33333337%}.column.is-5-touch{flex:none;width:41.66666674%}.column.is-offset-5-touch{margin-left:41.66666674%}.column.is-6-touch{flex:none;width:50%}.column.is-offset-6-touch{margin-left:50%}.column.is-7-touch{flex:none;width:58.33333337%}.column.is-offset-7-touch{margin-left:58.33333337%}.column.is-8-touch{flex:none;width:66.66666674%}.column.is-offset-8-touch{margin-left:66.66666674%}.column.is-9-touch{flex:none;width:75%}.column.is-offset-9-touch{margin-left:75%}.column.is-10-touch{flex:none;width:83.33333337%}.column.is-offset-10-touch{margin-left:83.33333337%}.column.is-11-touch{flex:none;width:91.66666674%}.column.is-offset-11-touch{margin-left:91.66666674%}.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;width:unset}.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.33333337%}.column.is-offset-1-desktop{margin-left:8.33333337%}.column.is-2-desktop{flex:none;width:16.66666674%}.column.is-offset-2-desktop{margin-left:16.66666674%}.column.is-3-desktop{flex:none;width:25%}.column.is-offset-3-desktop{margin-left:25%}.column.is-4-desktop{flex:none;width:33.33333337%}.column.is-offset-4-desktop{margin-left:33.33333337%}.column.is-5-desktop{flex:none;width:41.66666674%}.column.is-offset-5-desktop{margin-left:41.66666674%}.column.is-6-desktop{flex:none;width:50%}.column.is-offset-6-desktop{margin-left:50%}.column.is-7-desktop{flex:none;width:58.33333337%}.column.is-offset-7-desktop{margin-left:58.33333337%}.column.is-8-desktop{flex:none;width:66.66666674%}.column.is-offset-8-desktop{margin-left:66.66666674%}.column.is-9-desktop{flex:none;width:75%}.column.is-offset-9-desktop{margin-left:75%}.column.is-10-desktop{flex:none;width:83.33333337%}.column.is-offset-10-desktop{margin-left:83.33333337%}.column.is-11-desktop{flex:none;width:91.66666674%}.column.is-offset-11-desktop{margin-left:91.66666674%}.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;width:unset}.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.33333337%}.column.is-offset-1-widescreen{margin-left:8.33333337%}.column.is-2-widescreen{flex:none;width:16.66666674%}.column.is-offset-2-widescreen{margin-left:16.66666674%}.column.is-3-widescreen{flex:none;width:25%}.column.is-offset-3-widescreen{margin-left:25%}.column.is-4-widescreen{flex:none;width:33.33333337%}.column.is-offset-4-widescreen{margin-left:33.33333337%}.column.is-5-widescreen{flex:none;width:41.66666674%}.column.is-offset-5-widescreen{margin-left:41.66666674%}.column.is-6-widescreen{flex:none;width:50%}.column.is-offset-6-widescreen{margin-left:50%}.column.is-7-widescreen{flex:none;width:58.33333337%}.column.is-offset-7-widescreen{margin-left:58.33333337%}.column.is-8-widescreen{flex:none;width:66.66666674%}.column.is-offset-8-widescreen{margin-left:66.66666674%}.column.is-9-widescreen{flex:none;width:75%}.column.is-offset-9-widescreen{margin-left:75%}.column.is-10-widescreen{flex:none;width:83.33333337%}.column.is-offset-10-widescreen{margin-left:83.33333337%}.column.is-11-widescreen{flex:none;width:91.66666674%}.column.is-offset-11-widescreen{margin-left:91.66666674%}.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;width:unset}.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.33333337%}.column.is-offset-1-fullhd{margin-left:8.33333337%}.column.is-2-fullhd{flex:none;width:16.66666674%}.column.is-offset-2-fullhd{margin-left:16.66666674%}.column.is-3-fullhd{flex:none;width:25%}.column.is-offset-3-fullhd{margin-left:25%}.column.is-4-fullhd{flex:none;width:33.33333337%}.column.is-offset-4-fullhd{margin-left:33.33333337%}.column.is-5-fullhd{flex:none;width:41.66666674%}.column.is-offset-5-fullhd{margin-left:41.66666674%}.column.is-6-fullhd{flex:none;width:50%}.column.is-offset-6-fullhd{margin-left:50%}.column.is-7-fullhd{flex:none;width:58.33333337%}.column.is-offset-7-fullhd{margin-left:58.33333337%}.column.is-8-fullhd{flex:none;width:66.66666674%}.column.is-offset-8-fullhd{margin-left:66.66666674%}.column.is-9-fullhd{flex:none;width:75%}.column.is-offset-9-fullhd{margin-left:75%}.column.is-10-fullhd{flex:none;width:83.33333337%}.column.is-offset-10-fullhd{margin-left:83.33333337%}.column.is-11-fullhd{flex:none;width:91.66666674%}.column.is-offset-11-fullhd{margin-left:91.66666674%}.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.33333337%}.tile.is-2{flex:none;width:16.66666674%}.tile.is-3{flex:none;width:25%}.tile.is-4{flex:none;width:33.33333337%}.tile.is-5{flex:none;width:41.66666674%}.tile.is-6{flex:none;width:50%}.tile.is-7{flex:none;width:58.33333337%}.tile.is-8{flex:none;width:66.66666674%}.tile.is-9{flex:none;width:75%}.tile.is-10{flex:none;width:83.33333337%}.tile.is-11{flex:none;width:91.66666674%}.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{color:#fff !important;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{color:#0a0a0a !important;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:rgba(0,0,0,0.7)}.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:rgba(0,0,0,0.7)}.hero.is-light .subtitle{color:rgba(0,0,0,0.9)}.hero.is-light .subtitle a:not(.button),.hero.is-light .subtitle strong{color:rgba(0,0,0,0.7)}@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(0,0,0,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:rgba(0,0,0,0.7)}.hero.is-light .tabs a{color:rgba(0,0,0,0.7);opacity:0.9}.hero.is-light .tabs a:hover{opacity:1}.hero.is-light .tabs li.is-active a{color:#f5f5f5 !important;opacity:1}.hero.is-light .tabs.is-boxed a,.hero.is-light .tabs.is-toggle a{color:rgba(0,0,0,0.7)}.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:rgba(0,0,0,0.7);border-color:rgba(0,0,0,0.7);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:#fff}.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:#fff}.hero.is-dark .subtitle,.content kbd.hero .subtitle{color:rgba(255,255,255,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:#fff}@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(255,255,255,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:#fff}.hero.is-dark .tabs a,.content kbd.hero .tabs a{color:#fff;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{color:#363636 !important;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:#fff}.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:#fff;border-color:#fff;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{color:#4eb5de !important;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{color:#2e63b8 !important;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:#3c5dcd;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:#3c5dcd}}.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:#3151bf;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{color:#3c5dcd !important;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:#3c5dcd}.hero.is-info.is-bold{background-image:linear-gradient(141deg, #215bb5 0%, #3c5dcd 71%, #4b53d8 100%)}@media screen and (max-width: 768px){.hero.is-info.is-bold .navbar-menu{background-image:linear-gradient(141deg, #215bb5 0%, #3c5dcd 71%, #4b53d8 100%)}}.hero.is-success{background-color:#259a12;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:#259a12}}.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:#20830f;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{color:#259a12 !important;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:#259a12}.hero.is-success.is-bold{background-image:linear-gradient(141deg, #287207 0%, #259a12 71%, #10b614 100%)}@media screen and (max-width: 768px){.hero.is-success.is-bold .navbar-menu{background-image:linear-gradient(141deg, #287207 0%, #259a12 71%, #10b614 100%)}}.hero.is-warning{background-color:#a98800;color:#fff}.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:#fff}.hero.is-warning .subtitle{color:rgba(255,255,255,0.9)}.hero.is-warning .subtitle a:not(.button),.hero.is-warning .subtitle strong{color:#fff}@media screen and (max-width: 1055px){.hero.is-warning .navbar-menu{background-color:#a98800}}.hero.is-warning .navbar-item,.hero.is-warning .navbar-link{color:rgba(255,255,255,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:#8f7300;color:#fff}.hero.is-warning .tabs a{color:#fff;opacity:0.9}.hero.is-warning .tabs a:hover{opacity:1}.hero.is-warning .tabs li.is-active a{color:#a98800 !important;opacity:1}.hero.is-warning .tabs.is-boxed a,.hero.is-warning .tabs.is-toggle a{color:#fff}.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:#fff;border-color:#fff;color:#a98800}.hero.is-warning.is-bold{background-image:linear-gradient(141deg, #764b00 0%, #a98800 71%, #c2bd00 100%)}@media screen and (max-width: 768px){.hero.is-warning.is-bold .navbar-menu{background-image:linear-gradient(141deg, #764b00 0%, #a98800 71%, #c2bd00 100%)}}.hero.is-danger{background-color:#cb3c33;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:#cb3c33}}.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:#b7362e;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{color:#cb3c33 !important;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:#cb3c33}.hero.is-danger.is-bold{background-image:linear-gradient(141deg, #ac1f2e 0%, #cb3c33 71%, #d66341 100%)}@media screen and (max-width: 768px){.hero.is-danger.is-bold .navbar-menu{background-image:linear-gradient(141deg, #ac1f2e 0%, #cb3c33 71%, #d66341 100%)}}.hero.is-small .hero-body,#documenter .docs-sidebar form.docs-search>input.hero .hero-body{padding:1.5rem}@media screen and (min-width: 769px),print{.hero.is-medium .hero-body{padding:9rem 4.5rem}}@media screen and (min-width: 769px),print{.hero.is-large .hero-body{padding:18rem 6rem}}.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}@media screen and (min-width: 769px),print{.hero-body{padding:3rem 3rem}}.section{padding:3rem 1.5rem}@media screen and (min-width: 1056px){.section{padding:3rem 3rem}.section.is-medium{padding:9rem 4.5rem}.section.is-large{padding:18rem 6rem}}.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 6 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 6 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:#f5f5f5;border-style:solid;border-width:2px;border-color:#4a4a4a;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:#f5f5f5;border-color:#4a4a4a}.admonition.is-default>.admonition-header{background-color:rgba(0,0,0,0);color:#4a4a4a}.admonition.is-default>.admonition-body{color:rgba(0,0,0,0.7)}.admonition.is-info{background-color:#f5f5f5;border-color:#3c5dcd}.admonition.is-info>.admonition-header{background-color:rgba(0,0,0,0);color:#3c5dcd}.admonition.is-info>.admonition-body{color:rgba(0,0,0,0.7)}.admonition.is-success{background-color:#f5f5f5;border-color:#259a12}.admonition.is-success>.admonition-header{background-color:rgba(0,0,0,0);color:#259a12}.admonition.is-success>.admonition-body{color:rgba(0,0,0,0.7)}.admonition.is-warning{background-color:#f5f5f5;border-color:#a98800}.admonition.is-warning>.admonition-header{background-color:rgba(0,0,0,0);color:#a98800}.admonition.is-warning>.admonition-body{color:rgba(0,0,0,0.7)}.admonition.is-danger{background-color:#f5f5f5;border-color:#cb3c33}.admonition.is-danger>.admonition-header{background-color:rgba(0,0,0,0);color:#cb3c33}.admonition.is-danger>.admonition-body{color:rgba(0,0,0,0.7)}.admonition.is-compat{background-color:#f5f5f5;border-color:#3489da}.admonition.is-compat>.admonition-header{background-color:rgba(0,0,0,0);color:#3489da}.admonition.is-compat>.admonition-body{color:rgba(0,0,0,0.7)}.admonition.is-todo{background-color:#f5f5f5;border-color:#9558b2}.admonition.is-todo>.admonition-header{background-color:rgba(0,0,0,0);color:#9558b2}.admonition.is-todo>.admonition-body{color:rgba(0,0,0,0.7)}.admonition-header{color:#4a4a4a;background-color:rgba(0,0,0,0);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 6 Free";font-weight:900;margin-right:.75rem;content:"\f06a"}details.admonition.is-details>.admonition-header{list-style:none}details.admonition.is-details>.admonition-header:before{font-family:"Font Awesome 6 Free";font-weight:900;content:"\f055"}details.admonition.is-details[open]>.admonition-header:before{font-family:"Font Awesome 6 Free";font-weight:900;content:"\f056"}.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:2px solid #dbdbdb;border-radius:4px;box-shadow:2px 2px 3px rgba(10,10,10,0.1);max-width:100%}.docstring>header{cursor:pointer;display:flex;flex-grow:1;align-items:stretch;padding:0.5rem .75rem;background-color:#f5f5f5;box-shadow:0 0.125em 0.25em rgba(10,10,10,0.1);box-shadow:none;border-bottom:1px solid #dbdbdb;overflow:auto}.docstring>header code{background-color:transparent}.docstring>header .docstring-article-toggle-button{min-width:1.1rem;padding:0.2rem 0.2rem 0.2rem 0}.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:#f5f5f5;color:rgba(0,0,0,0.7);border-bottom:3px solid rgba(0,0,0,0);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:2px solid #dbdbdb;border-radius:4px}.content code{font-weight:inherit}.content a code{color:#2e63b8}.content a:hover code{color:#363636}.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;overflow-x:hidden}#documenter .docs-main header.docs-navbar .docs-sidebar-button{display:block;font-size:1.5rem;padding-bottom:0.1rem;margin-right:1rem}#documenter .docs-main header.docs-navbar .docs-right{display:flex;white-space:nowrap;gap:1rem;align-items:center}#documenter .docs-main header.docs-navbar .docs-right .docs-icon,#documenter .docs-main header.docs-navbar .docs-right .docs-label{display:inline-block}#documenter .docs-main header.docs-navbar .docs-right .docs-label{padding:0;margin-left:0.3em}@media screen and (max-width: 1055px){#documenter .docs-main header.docs-navbar .docs-right .docs-navbar-link{margin-left:0.4rem;margin-right:0.4rem}}#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 6 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}#documenter .docs-sidebar #documenter-search-query{color:#707070;width:14.4rem;box-shadow:inset 0 1px 2px rgba(10,10,10,0.1)}@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}}kbd.search-modal-key-hints{border-radius:0.25rem;border:1px solid rgba(0,0,0,0.6);box-shadow:0 2px 0 1px rgba(0,0,0,0.6);cursor:default;font-size:0.9rem;line-height:1.5;min-width:0.75rem;text-align:center;padding:0.1rem 0.3rem;position:relative;top:-1px}.search-min-width-50{min-width:50%}.search-min-height-100{min-height:100%}.search-modal-card-body{max-height:calc(100vh - 15rem)}.search-result-link{border-radius:0.7em;transition:all 300ms}.search-result-link:hover,.search-result-link:focus{background-color:rgba(0,128,128,0.1)}.search-result-link .property-search-result-badge,.search-result-link .search-filter{transition:all 300ms}.property-search-result-badge,.search-filter{padding:0.15em 0.5em;font-size:0.8em;font-style:italic;text-transform:none !important;line-height:1.5;color:#f5f5f5;background-color:rgba(51,65,85,0.501961);border-radius:0.6rem}.search-result-link:hover .property-search-result-badge,.search-result-link:hover .search-filter,.search-result-link:focus .property-search-result-badge,.search-result-link:focus .search-filter{color:#f1f5f9;background-color:#333}.search-filter{color:#333;background-color:#f5f5f5;transition:all 300ms}.search-filter:hover,.search-filter:focus{color:#333}.search-filter-selected{color:#f5f5f5;background-color:rgba(139,0,139,0.5)}.search-filter-selected:hover,.search-filter-selected:focus{color:#f5f5f5}.search-result-highlight{background-color:#ffdd57;color:black}.search-divider{border-bottom:1px solid #dbdbdb}.search-result-title{width:85%;color:#333}.search-result-code-title{font-size:0.875rem;font-family:"JuliaMono","SFMono-Regular","Menlo","Consolas","Liberation Mono","DejaVu Sans Mono",monospace}#search-modal .modal-card-body::-webkit-scrollbar,#search-modal .filter-tabs::-webkit-scrollbar{height:10px;width:10px;background-color:transparent}#search-modal .modal-card-body::-webkit-scrollbar-thumb,#search-modal .filter-tabs::-webkit-scrollbar-thumb{background-color:gray;border-radius:1rem}#search-modal .modal-card-body::-webkit-scrollbar-track,#search-modal .filter-tabs::-webkit-scrollbar-track{-webkit-box-shadow:inset 0 0 6px rgba(0,0,0,0.6);background-color:transparent}.w-100{width:100%}.gap-2{gap:0.5rem}.gap-4{gap:1rem}.gap-8{gap:2rem}.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;padding:1em}code.hljs{padding:3px 5px}.hljs{background:#F3F3F3;color:#444}.hljs-comment{color:#697070}.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:#ab5656}.hljs-literal{color:#695}.hljs-built_in,.hljs-bullet,.hljs-code,.hljs-addition{color:#397300}.hljs-meta{color:#1f7199}.hljs-meta .hljs-string{color:#38a}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:bold}.gap-4{gap:1rem} diff --git a/previews/PR4245/assets/themeswap.js b/previews/PR4245/assets/themeswap.js deleted file mode 100644 index 9f5eebe6aa2b..000000000000 --- a/previews/PR4245/assets/themeswap.js +++ /dev/null @@ -1,84 +0,0 @@ -// Small function to quickly swap out themes. Gets put into the tag.. -function set_theme_from_local_storage() { - // Initialize 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 users preference is for dark color scheme - var darkPreference = - window.matchMedia("(prefers-color-scheme: dark)").matches === 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 primaryLightTheme = null; - var primaryDarkTheme = 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. - if (ss.ownerNode.getAttribute("data-theme-primary") !== null) { - primaryLightTheme = themename; - } - // Check if the theme is primary dark theme so that we could store its name in darkTheme - if (ss.ownerNode.getAttribute("data-theme-primary-dark") !== null) { - primaryDarkTheme = 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); - } - var activeTheme = null; - 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; - activeTheme = theme; - } else { - // If we did _not_ find an active theme, then we need to fall back to the primary theme - // which can either be dark or light, depending on the user's OS preference. - var activeTheme = darkPreference ? primaryDarkTheme : primaryLightTheme; - // In case it somehow happens that the relevant primary theme was not found in the - // preceding loop, we abort without doing anything. - if (activeTheme === null) { - console.error("Unable to determine primary theme."); - return; - } - // When switching to the primary light theme, then we must not have a class name - // for the tag. That's only for non-primary or the primary dark theme. - if (darkPreference) { - document.getElementsByTagName("html")[0].className = - "theme--" + activeTheme; - } else { - document.getElementsByTagName("html")[0].className = ""; - } - } - 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; - // we'll disable all the stylesheets, except for the active one - ss.disabled = !(themename == activeTheme); - } -} -set_theme_from_local_storage(); diff --git a/previews/PR4245/assets/warner.js b/previews/PR4245/assets/warner.js deleted file mode 100644 index 3f6f5d0083aa..000000000000 --- a/previews/PR4245/assets/warner.js +++ /dev/null @@ -1,52 +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/PR4245/index.html b/previews/PR4245/index.html deleted file mode 100644 index c1b46665f5a0..000000000000 --- a/previews/PR4245/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.

If you have used OSCAR in the preparation of a paper, please cite it as described here.

diff --git a/previews/PR4245/manualindex/index.html b/previews/PR4245/manualindex/index.html deleted file mode 100644 index b6bf52e32e6d..000000000000 --- a/previews/PR4245/manualindex/index.html +++ /dev/null @@ -1,2 +0,0 @@ - -Index · Oscar.jl
diff --git a/previews/PR4245/objects.inv b/previews/PR4245/objects.inv deleted file mode 100644 index 7b7c19de2a9f6744dc4070779b31aa7748a2a8f1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 136446 zcmV)BK*PTyAX9K?X>NERX>N99Zgg*Qc_4OWa&u{KZXhxWBOp+6Z)#;@bUGkUb7Nt0 zE^2HFBOq2~a&u{KZaN?_E;24KEks3D3L_v?Xk{RBWo=<;Ze(S0Aa78b#rNMXCQiPX<{x4c$~bw>vG&kvL^T+PZ4I-oUXDFI!lzQ zN>yfKy%Z%%IxR{pQPs6pXZoapnIMT0GLe-)l46gw*}lWR#6H3Kwg1kW?2~NxB_ce4 z01!x0V{@iUM236d5*H8m&p$8L%lxydo8?c-YN67{O8uIbi)xjtrc&?EkB>eiukv-i z&B|G}U0fGUzG!yaTuOv~pQ$79msL?U*ZDRii$BcNyQ;}+by;oIuFki$sxB3Y=sVi% z8vT!~yvi@OnX2#VCSTQ7^JVr&NUy#;QzzT}k6pfQ$~$#bf6ABY=UrYmMYVR~y0;=L zi+^TtIi$#IFjME*O|iaG*?OtUDqF(8FN-pF3gL!J|IN03nyF)Mb5vec+oHK%)v8#V zm%gobn|fBPn{DMO5!Ywx4g6=hTfj{jk&CP@7Ii>|eweA}_+Qh!-d$YbzXB5WH~qlo zpGNMFUDXu&rH16}Z!`U>`JYB^LpK}}Ge6DLnQ5d4fZy#V->&dVNZ$OW73hEN8v2^P zg3C>xIRB!@OR?4?SC5v>Hm~))>k-qsiAC=%EX)m5<=x_LQ5K7q>?&*egw0Pgb(%HX z;&V$fTXY7e{9#6aD*DSxp^ocn6_7JO8A<(5{r|R`>!Mz{UU$9sYkp#R{95{2R|mE# zi;KQ{&_9`b(Er?K+d|Kz*ZJa8uHVUe2W!hkUKZJ!#yt;sscp1zYpw*_=ViWXkLbaM zGxd`H6;`;)Hsi{mk^bWLodp}!&2|S%X;zNvb4~TEbz;Z3f@a;ZF<)F~TRmuCz3urv zqKWxV?ut>i%@@^GKm%SkV)%!iU1Ggzf@8CRVfit;&}%9TtJ7@zsZKuVbvCdjip#Cf zd~~7ThQ7@s+BIfdSg3_$==T}wQd=dRbLV=_ulxpz>X&tKqh~_ajyRr#%-hC?A74v$i zD{2Aj;Vry4{HyzNc14}9&qb^n`z@@-FP|z z_ad*)+8v)1dASS>N_l-`R9-^Up@+u?Gg28GnA?o5bVsK7MUQI!S8Ih?74>3vk}Y5* z>s?!9BYhwG)~c-@C*jp^y<1)6+xaEEfJK?rHUH78zh6XKN$?jx`^W3N+IENi<+i&w z_O)>%$VyR9{Q0#px9EO+xT-%r{D&L<5p4JeHT+pLyhLlF^NriT8MDK?8@6@>9ob)I z>c}>t*J#J2Z8Kk#Rjr5m{Bjc*qM>F|D_@0WnC@5GMa9bA=-XnQXIt}{JM$p$^Uz+5 zBdw+-X>c@B8@qg!*o`?JbQeZ4sD{==Y++5Wk#!au&AGS11+dlB4L`mm^Fy}}{esGT zP&Kv)+N<*MjNj0iBSuk!V-zSbwc7`?VJ z&%_Mf4RAqQrP*4QW4*DhH=pt_Z5eAQjz8RQS9F&Vy>L_eV0yuh?naw`3%#lr>rBs~ z&Vesp3TBDB#@2lD4mT#+y=OPYTL0nM;i2DW>hJWAKi9BGl840C)Y)vhzYYy`-|FZn z8*3Y{dXn{H>>hd++GSO>$+vuV8xS2mz=oUKV{BwMFq*gPfum@+ISu-4*95J$OE_6Z zt!RO^L*Id$(|^X4@_*EO{BKav=o@ae>+=wp$5`h2ZHzuFw$hJ@{|zbvTXr6&O*DnQ zJ!3OR(ItO^u}{GmhP_j*)lOTFbV1sV&2_G}_6*{QUu9)g)VhwVCF zZnN@LUaj&bv>x=eX$_e`GkYmYX{+@V^$R`O&`SfeF1i~}3Ovc;&*A>yIKRq1<u8nhB~B!(0sG4uD01~tglw<86Vfc0go3# zJ*TCeJ-RAo8`bwQj{~Y>xf;ZXO4tg7zy#?Y=amusH zOZ|0%C*bkcdN$()<7A*?rC!&It=Z%PO3G?sBXDCKdTsTnra$%A!Uu}#j!(SrZ}P2t zB|Sdqy%da(jzJybls@)8qV@R4{mHkar&cg9cpp7DG3{T|KNWuAxmJMFXr9#%@y`0S z+PMUS%z7bs+|_%(S@sw>3;jNK-%+NGUZ+^^@B7~6b+vk+Tl6)B?@yg(o9Xu$+=us8 zqL=0CtRRc%xLV-9-3A>{3qGH+x+?UFWERAc8wp6v&`ZP@%`zJ5O&`GXi*>$zp4B;@ za3VIG9w~59adhduxi;SE75_EAfIlbo?2AGW@xT5P{+^vT`h92HrNVX!z7e~#r{0e- zM(%TCR>#O4uCnI(;zIov9I{2d$jdTY=hd#BT@>`5182IavNQFZFKA1uSb+uoB8TBy z)kWX7qmPBF{MTyxsYcslK4t42l+`=G!Ungx0eaqeYX-BX*Vqs$dF9&khCc&EkAQG);z`t4JO0aJFyimagt-Ze8h9WETE)-|5;mrMvH_jm>_PVu28@*Qz zsfOR%8b9i59Yxz5ALAzGe%o!^9gvY<-l-3!p}BntpzvmqcX=uHT&6GRyN3(pW>2twJ2j_!O zK0YVTuk-9C_T_M6eJW!q-CO*aIKEqy(bEpw>S0eZU}2+wrrL&juvgCW#w?uj+Hjv^ z(ruSTu~5)*^gi5o*!Nz-8oW6Xe@}l0Y-Ll}orV6si@cv6Y5Q*M?{T-_o?zeG=xFd> z%h2r{@3uGgInKazrYpm@&?jZzzy_|V1zzm$)!pNSPTNA>qaH{1IQ3bBl3w3y~c^Jqer^`GkISr=Kjn-&Ynizk`sUw zll2u_>>uwox$O{K-+Vql`;VtX-7j~4*XDm4NgUChv5duKk#E6)xNh*Ds@~)a{V#n8 z)yE+CNXwmGyYz`d%j`_gsF!Nq04%hwLGJ zTh_OHJ~B>Py7A8!Y)DPID^GI9Z|6n7Nj4ykGhyOO3COo@Lhex|I;sHT3=KD{V zAz=)SMIATCq)q>L&2Cj+zx=$(0iC{Xvhthpn|fYWx4X@LpP?mdZip^N+=}nDU&+6Q z?_)qv&j85XJqL?IzZQ;ecU1_VxJ=ZYr7!$7YJ(gC~bZ@LHMzBWRsTM9dk zueI&FFkCU% zL#r+3G~xwC7rNRTz7R+(A8YF#K^&7rdY^%7R_jFsK53v?YaWGLo<0AS{~56CBSj{6 zv_QO*|JvfE1YS!2oSNTb9*IIRC&@^nBlnAidqIr%qF84Ta9ltzJ=lVY;RUb5DxUt@J?L{B^A>=mKciJM(*Lpo(%p3h?2Kwl>ovAZ% zO)m|3r-PU4-3lQxH+f52wrz?~pnRGzq(7Q}$99cj^UTktohZs#;QC*&ood5kx1EdK zdXL^aI%Z(#?zWy05UERGE%vz;DNdXr=C9mm9|Gp zKg2)OPS4V#vp?7B{OwuK{bigA7g%6o+Rxg#bh$>$ZzrzfN3wP#SV>o+-%nQ?R;r|@_LLC@V^8)0d)iA8uayB zH+N-zwbR>AM4ztl%r(((U0+qN;BsFtOZitsM_zl~7yk)+G1A+pMb+QgM%%&ARKK1k zE6SLc*%pEL1YL2AI(@gAU+k`~TIYnZw($Cl7(LMOzymEZeE^E;fLrQm&LVpG#k{Nw z@V?fg57SFy6w_WWaq`dp7giTnYyGAdjFgXgZ@vh;KDYuvG`iB)nO;>0T(^yVq?QD( zN0d>p9ek{9t~Z%FW)^WvSU*TauM*i6W_k4~H%r!WRhD@t!7W+W|aeOe%=j(*zX-WJ8An^+W> zazM-z37h$$0~bi0fswLI(+Q42}0HZSrYv z-;?_a28)?{&az*3WM zf#twOSTtbt;!LBfV5(GBPDzT3$d3XMnaQ_=q(;gM?TAcgPsPu>YB>)(V+);S--xy_! z>X$LEcNdeo3yXS5rf?79x2R_Y>Z!@ki$dNrw>V>al>{M=g=^2^0ZfTsukB-**owhvUzwHAI|TwUjN^J@;?(YSdrE;=+r!qRwru$$7v zu6^N|IA^6C~9gol8QN#skx`5d`+#0ZP9hhB4KGyg_TDBta4 zRh5yw_e#tp2fJ)F&?947J4nMg3HLS7*rqR1mg*$sePR{x33%G{H_Er*n;I|(`vl;5 zo%Co|;3|mg16t11tFpQPEGLMKD(}NZ#7WH5Ybih4TUnr2twpUA(;n6=E9QVRt0vcDU;b;9z|iUwkTH(WAjo&JuydpeaBr-Z0Ah5asOa9H zMW;Q&-D!(id=K%?JGdh{g)votZ~J9h?<_Ji*tpR?ApClfZ<{Hd7#WJxqV#cAE_UTE z;+d+Z0h4)G4p?O)a{B4?U&{PB+GqYb18>)){)~*CJf(iFW=r^%mqyjeRv&>xBv~1B zQNo-`>08NKSpshx^c&4v`PHAgl#;J1rUJC;BDXoMEKUAi)H^?9W!3bux1pf7W2O3j zQ@vxQX2(i}n>^yayvg6+NtLV^Sc-z zkk`6nDCEz!yR{xe>8Y^Lt@=nZ65SQ6vBWXVa-3SC-?V{jo57oRq`+FCp-Fah!k{2I z&eqi$QE_!(#Dw_#g})oe&4>JtU9ruV{%genWEjCyLD<==+cfs|8}0sE#u3!!8)r6- zR3G6|=8Mc|;C4U61Oit47{v1dheM~?8qj*+r}n1t!R0(Nhqn@2R9 zJg#pCknt{N0k2{;lu$0v0x3qjQ$P#&w-JRq&|UW+4}Mw0n{E*mO&CQeFWFK}fH_Yg z1t0|`lk}zJ3JtG8QMQU%b3r|27+`@4ODt;A#L`kf>`-rh8WH;0=6WTkk7Tqc)RH*5 zrBu%cb5p5re%s=xNq=!W_KZ#%s?#0~K_mI8XgkqxsQ^&}tlsTsf9 zt8KQ_Gx>uJjSQ{q6b^y;3gYlhNSt|jh#23jRH;34m?W~^x5Azdt(dv>S%s1+l9zhj zWL}umx+K&5bCa*@?i7u5c&-KqdW?W+#UUZZI(rNdb0-U@z>&9G^NVYWpU{t%3{YLoV_Nt^0900r7-7mC>0Hnk2QM`{9qJt&$txC}K2< z3;mOSAVp&Mw7y$iRBgL)oJ$^F4!IfdnqoCRL^S+%eGC?wDDOA4Mx@y?y{;B|7QotT zxJgsr12y~^kn;ijYd6K}mAay_K=5@Ji{;aAqn;=j}H=Vi9|^pCHv zn`Tr0G@DiRLT^M=obNBy_G(tc@8A3-YH4dhBEO2bi-Yf;i~BhE?#033GrX6BCr5fl z>i=usk-miYba43NU!WWyFP_|kD-DPvPp{bYGphfKUMuuBOHG|RT)CG;hS9v>31*~T z0`BaPKVpmG5yy$AF%dq;*o8JtTn=U`vpNUtxY4{$+&w#)on-K*?>%P0p;fAnTM+gK zGV~p{AXuuWRaxZg6tIcyhZyEYW6P7|70D-tXdrFJ@2pZP%wwtrfk|(;34};O;TIeM z22?=XY?{^4XQ_P|Mq%7Uag1^TOe(ccwFZV*hhOMfbEoGele`6ArJd2U2J)FuC(9`- zmtav!yRy*%Y>Me+no`jL+*Umh3D;3*mGw#OaA3BE6e7Us^7}{W|J)Q$Mvp!Lf{CyC zl^z@(>jmo=6d!dMFDUlB{2$*xQk&v`JV{>e79|XUwe$o8X4tR?z-o~W0GeC2qGzg2 zN_~jb_ELIrmwIup){fOG8>#hMCCVyM7k91TnXTgic01MaXpNIl`H!zy?BMVRDHtjW za-@x3IKQM@81^_R!z*U*fHWG^)>b((8uTdn+mqI(eEb*($m7F3M@T@S9UNNe5%9&d z#)a+@2FByV1k$Q(X4#mJq9->CTwIWym3hXXo`JITU&{6I
    O%t)stNzGUOP_%Wg z+rHEho7^rR&pEN=z-R)RhgA zZBn{Xu;uj^uO*L8%$O0xLaomGsD;k9Fs@<$hCXpe?>n-O8UR6J6m%|`J`6voWJp1b z2cJ4{u%y}oA2VEVZT3x7sRxIILOqFeE*L{>;)AuB8`!^Mv>Ib9d9%u{#>RT6ju+Zr z`q)W+Mg1M#I8^A+j>|w$I9$&E0H)FuT*gF4cu%W_aN;9E%w0|S(BwE-&-$LO_idp@*u|{ zuSf+p{?R@o$)GJb-yu8WE9ZEe)MZ!8RTlG#av_-QU zcVNi_gVPAh;Gj;?xe^U=1(Xew+MZTJ#|itZcd(UjSf3)u@<>Is^hYTrlcki`;GLkx ztVeiYY4?ux1+QYLw>MstweD1Qe`FHhICaC5PM#OqWWOzz%d#^)&?1mAi$YuFrfKqi zo$m1b{eRTg)$M$pt@20wZ_aXR{W;G~wehhr*~#qw%64|}^jq5A+}{fW*(l z;b)aDj2=c1adTqx4CpGYl<>I&II88kb5?(zt z>NT)Iq_9_~UoWcsQkz6Dioc0*+Ip@sU)RCmGokI^@JH5XS^-=>S6+{%P7R!g43K7> z-@=5C@!xf3y;Ou*{J?QX2jkPMaPdfA?I^(+0s;ybc0}YwnQd@ogiU@?>0O{$qYJ3J z8~NTvA&dLIkhR8%R%`0=rdgBnfiZOl#(SPMT|dg!3C5O>#mZOP-2222pvfnyQ_>g@blGzuhnG|~_-D38D8+jR$>8tq#= zzpl1T`u9BG^qb-uLN$ujBqvaMHHA!E0vX^_Uu0$bF3C5vy&xwolxwvz^t>p;p+~Jp z9|p19*1ho+MkAd1P-6>fVL?yM2zdYijm1JaLnMf!=>{(&R@!dR(gaCbVM|(U&5D|O zy7gCQ64u4405l}b*nj4n znKH6=^;mwa3a2or5}n+w@b#t*B&gk^2iBuNPjX(BH#u&5`R67AFpa)&n8_fgSdMVg zNA)6KBT%YCKi318j3c0fuWnS!!?y4(29YpbQ&K?r!{+?n=%zMtM8j{Qk+|omG1({AgG7mxW#+!6f03 zIQ>mOre90;rEdcB-E8WETC{O0^=Ru$QTp;w`_+^yEy z{QX^@4{z#pTix;>hTwT{y|Z7KAyA-9p}e}Ol~%@o7-hP@B|Ku+z8f@nQWxV3Bgea8 zFf9O0y@;NLg+|Y0Ss-mDWNT~6~GNjOAlqN03I8i^=pQL_j|0S_-VHNRHrwg1%N${4S{H|q2h)D zmm|StL$4DqLTV9(Zg*Qc5jkj%1c}wjYl+QCA!96Uy`0f^F?Z$d&+pw*bMWLy!6o&gQorU3HTT23Y#i?qzUwz@0&|pi>1npUyLU*h zw^tF^gMSY9-47MBu|DFbcPbR95MjTQLZ3R)y4fvTo9amFG@AGq=xEWRn6N}Xs$qXt zs%>#_TpQnQTqw$MlcL!To@=AP0U0Gc{-Ioq7T_qs^3vOQURXD)}s3v)}{jdLoqf-hDln$71UpU*V?ZNSrgXiA|RhvE){NRuaa7_Aa z#`R_TKdJU&`g3}TCmF;V>w7L-BFvC`x1ZkeE3X@Eb;WdKDIsAE2-2tG2i)r~-Tm~!{e`HfNyt{%vo7*1Ymqf|A1dJNLB>sZ020FAE z?c|?)m#xU*q|f{7z!!^J9!ZH3N&6xP@#PCuF4?`l!0AA7hl|KXGO|Wq-_@j zwQR_l(0{XeS%QtZm{YkZlkw%=1}RdcDEUR7LNHnJLw-}#xyw_$(o4|p;xF2aoi)Yk zS})l%YVw!g%Wt%uy7-h`#kmOENsFe-gYTY`#!ynC>t6rCH=zGzZvn!*<|ed4bTrbB ziZ3U}0;-Ms_I|nEQVnj-Ue5QK9>v<^#xQbaG(L-d#kZ~3^Kgy}qV@we4rIK)O z;KfHV`O$_+iMCJ`tB==jfFXtlW6YVAn?}>aaC<(l>Kk2ExL*eXa^tZOE6$<0v+5Q+ zK$ruI=A}vPssm}YIPK^M)CIDN8zSE*CvDNCPPRJu2DG_TKR|-IP^G&;H$~s3KMgcz zl!=mL*Lt5BzF$aq-r7@5h=FRUzpY*<>fP8Wff~+rL+Q|PgMofmpeV7{BTf#Y(&fyu zVKcLn4(&9-_$N)gaO*SJhWwKSBg{uJLeP57t;vnOVFG2kmK-fUt*hHIUs7?D(6)~6 z(QuRb(`~b@Zi*!(rM9~70GivkCzePVoAHiRGKyi4V=j-NM4v|AwCk22&GijI~7&E?~%IV^dojAST#Js5{5ZN!&1Ti z^e`|Q($2-21@Th|PE+mzn`CM@^Yg zNDfE-hkT=rSu=yibN5jkgKjt(TH+MCXZYax6!_q8BfNi7bTJo*} zN;KGcfcPF~2lA+;Tzh6~C_I>(YK(gg_2H(2`e3@?Z_4Pi1q@hUVgdp4>S4H<*j#nE zs+ZOx#PK#b?IY%>Q-?#ay$rm^w|D7sbyzx`10KiunECH4Sg59R3a^_e=i5s!i`@GG+mkBZvCTQgetDPC8%;4WWfpK=(7 zhSTz@1zE;J(O(B1aeAG$ucmYj&|cjheDKg7hPYwOylNq$=~f+UBayJhF*o|BGOL1E z*Nh4@99uSyLGBz9Ug#-yx~?orXFq_@KtB#4)a?sw(3a(75kZH92zrW-w5}`$C~?gV*G!Ismjy8f3o5Ad|Luiw?Ewm>Mba%a1cb>Txtfx-DUj>r0@B`8$9RqT!QUUWLGX$;^0Q&m+kwCxbv^y?gVa z2S?hA{Mx%X0Uqyb!-3M)<`%;*<`%STq4Wv%aHT&~xUh#O-2@Na&W;u}zGqiVaKg^s zj+Kqng!G?!8f~QiNIqMn=LpXbE0i~FCYn+Aw-cl+_tWsb#kr=vY6g(5l&_J2WLklQ z&aw!4l+%-(=c^(uT(oDFZh@5;7Ug0;cXL}K0OUeCTkX_LnO4eOwO%74qXKR};LaF6 zst6p9^c)d86(qQ!3XFhn*KA1Oenoa_3VzLfU7)JNu8P*4OxlC8rMh3YeD3cpGhN%C&e? zr>DTOw!VtX$Lz_qaB3(YGi%hFS{cozO27bmO+S|{RKf)T7`S%U?>>m@($dg9T$+rk@m59Z|i<^YZ8;*!2RaHxEt==h`u3wpMx^V>JS*@*Ohtw6)U! z$VDu?wi_SGuGdQ44d;+^5g9UUD?PHY8!8^|{0e0L6>d|C4WQm|RVFx)pc2o~KxSOA z4uwuTDC~gw(+lD@4(1Lpo2(w0^nV{{TdVXgL)@O1)#8)ob0^^V=e_D&peD=XuDCd8 zD-sKyS=_2dP$cB6fcEsw6IuGpgt$17OXPo~=H*VaKWv3DaF9%_F=iq+1Fvi!LKzd( z@!ns*^W;bL(fshhE}0*#N9Kni2h5M?fB69p8kmZwPh5L*Mp+$-bE zk5Zwbkdi{l+luk`=~dNbkQy7x_QVKk5HYS$4U>O>0U2hZj;>p-b(1b7bR~8G6GWEw zrY(m&=y>4mR1?s)zBd9r96SxE0c}vWFLFZ4?F#+Tw;~)XX>6wMQF1+?6XLD96;WEr zX%pC}e7@c8G@4d&&F9(0Np%E|gqgW*_wIMNL>)d(Z?B65cwr$k8|aGk+(zf&yS#x7 z?&lr2{l+u4`_{6)?(JGO;TDeIC8D~H)A>7G^bQ{@)TPge%IYGArPc-etkGqR#D}RF zLYu3|_J_hGXn_bXVyyenEA9>^k5T3qdVix&Sw#;FzK^6MO`hu&N3WG}9xQzT%dE`yVRre&9WRT5sKrw7CtW~5^#x?n3VU$GC93|`cgOb zTKO)&A`|mVQR|ux`pI?mUPyFudjgxRyumfSA}*=@H-OaTUBQtb1OFlPC~wGFy7mCe zY4^Rg$J=@lMwOx)1%Uw}cqwnnnezKXm^nKZa8etx$;rhEoDNGc$>a6|En#4ZWg!Ug z_{zr`l+$4L4ig=EILt7oZpl@G_ZAaGngk*4F4=H|^&r*}L4h{Ly1QcI=~}|B!6PgS zQcYQK{8CbhKI&cM>tb+XjAmq|kb7^P=(dzwQ~CSI{rvRImFFUDl)>iuwFTaq%HLtY zS+Xp6NiEjPe3R?{S!-*l1`dp|3a%mS$D&|wiP5X1Ugh*MrUfQzqi@}r#a##3U^vy2 za{w2kS9!mKo2|jQ5@P3Q55l`9yD;>rj#6{4swP5S6gKIG&vA-m7>9h|=s8Z43`2?- zJU=J)HOZ5J>$yG%GtuinC}Zv#;b8N1*?e5(n)#b2)6;**ziizAyO%OwJ@+@vTTjPj z7+~pS46c*qsJq=5H!=w+B8kGKAepUhBU6zmDqLqbdfwwnFP)`jrMGGNYad*uR0gpU zPo4Ws&6M~Bs>8sdheHVL@tbOqT|iXgF3zB62i}A}G{l|0B*>}?x5KuG(qCh^6OlwgzceVN{!*l;ydSjNANmx10zb>pFFx+N(0iUwX?K;m-YsDdCxy z68m3u(V_i?0!iPa2Ix z20w+;5eJ_=_q4Nov5s@eJLn{1A2Q7JhVq9Gfs3A-9pc6bu8Xa|x< zZROI;;x;MN6h4nxh1)sw(&fQGUqb+9{Dl-EW~$dNQ)<7@+9!`PdabXJqQuPmicG3M zXUmQY4%PnwKZv6r#Jp^>&>p!(CT{DldY1FU0$EaY#d^u42)p08Q!HFJ5Ht^2oK{`O&{SB|j-%?9J5TR&50X1=`SPSf<4PFjy0wRExj28^ z!k$Jb=doB;moXcq8ScDYB_Ci?>aoRWbJ#U38LPhhdRLBbbQjX5ZNAcKLSx{NQ#2hmj_XB$tVD$f7 zBc2=2m+>c6BR%`7M=e(SwTfLM%f?21E7Qb&@Y5Wr^{-4Prum4xSWoGsrdqMs| zXyyI&l~jrpXU9UZ{ZW}7$#AuGd!`i{4wh(OhpG+k_P`jUh@$jbvxRA0WUbt($^xBI z>DwOK4jne?g_M|aG8%0Y)LARL%5|o^&Jsz%f=hz&s4RjTW5*!761B-@LV>d(? zpZY7lh$JiMCi}4lWi%vcX|Qv*xvd!U6=p-2QkI1D(m77+WssL;LLk=206m&D*+MSh zQG1TaBLn%4B#+Z@v=#&dLFOx16T{51*wigGhZWu4nR%EAJDW zx6iu5dpgt$%h(iu5#|kNPFVUmFm+fcc4#iZSX9Ll zC#FdiD>E)&3qS)>=uuv_a6>s4kc(PxR zcJG7m%AeO=JhNYvHgrNpW>eUvEuCj5(4E zMP=_qndasfZk`-rW_nr@c)lK_a~5m4Zb=AAv`I?B%-48cjbY) zg#Kb$5f;uIg}#Oj9`>N*2aDaz7tSNVhV&wLPKN_41BRL{MEZpG5W1az;39 z%4$nKh&>m^Go;8myfk^@RM&3kG<$!30g0j1U|992f#X4U#D zFB$sGdx%`rMGo0e6H_&4co2<>6Lzq9qN*-(C4NoL^IDIk603y}U&832K#C9(LYM1< z&KdXggmgGR=or#=j0_Nsc-4Z2yYF&u4^WPHRfCd`CaJiwC3+3*4f3j%fl(HKVg%G2 z9G>`!KAJ@1##a0_T_M+MnGB&;2xH@*Ds70$n&_GCQ>RYrAR-u7s?Np!3=Ux52%w1m zDN+Rw;1ZP}cW4 zFE{OK8nLG^QlUsi@+Au=^c736$!Af4j3BRoO*AvX3-FBO`gK7*N4FMOG>8m5AD~9D z8h}4i9p$vB>s>y<6mGu`(xk_bLQT%$w1++K5(GcmfqXhPkU!d?icOO#wrF7O_f5`w z7x~dvO;t6izTRcs3m_k%vEs(b%UucQ8BSq|th$LpiiKSDO^ffsnVrGf-+Gvs;+aMm ztpS7SG8dEAPz$VqG+U0+n*^^V`SuP|3?g*%3HyKm5&&S88wh~O<|5_lP+8>(gZY?$ zgxx9s>*Qba|Fv2Fi(=E8wT*i`N;ig_Wb_NOFVXM7x=ap!cz$y5!;888?`Ez4(di1D z3$8Op3L5?rRBO_I0O6>&Q0UFxCu9EDCn=y1LvH7L<+*hsbT-q|PPTx%dV0Q_4I+`L0IU@g ztcq@?n~fwx{v++8s_m|g2smDi?E`eomoj%_!uAv%HzIC+=Cwkr6RS{_e z;(iqMqg+3(6k@ml%COTTSk@%5;i`FG&ZQUUIlC=D;rNMX zDm^;%Us?HyKGpulA*jU@E1s}Gt+Hxi!3sM%VlAuVvZ^~srhboChjlP@^=4ce=L6NB zu$o>|7}+mnW+Cv(Bp!E!57;qTV(Zkrm9)shm?aQ(y!i0!bnC* zQ4ZS5;mJ|RjRyUqgMAZ&d@{J#SNz+n{XMyELQ9#w{#Ae3Z?EdNEwFGh1eL%&N#Y|+ zYlDk;@1OVg&e47EANM=?xyO}W)!@{@gj?uR2tnKWr<>sKGTID%7y1<#t>)F^i}#cC z6y@`LC1Bhz-#(qEB>)ayb)0*StQRKYr>hd=24XFoAdw9UOe0#(lM5zxQGn!Z7U)Ja zp1pF3r;?6l0cRvV2`BQi9+MdT=~2F(N;(?WZZQJdh+0CzuI`X3)jSBTk<-exYXrd& zN5>wH)t=&KlG0uqtASl`jFCidE!6@RE3USke+Dm!^pi(a9w4#l0>~^a zzeUs-zJHh-q>Ac))d2?my{u}6REG>|CI;~B>K6<*O@9R+z=wR50mgfK?~|0#t3a=^ zdUbzTaMPA`9gp?a%&JHumgH?&*yQ~9Xh?^7Ek;R>D{r=@)G5o?Xs$Ytf$=GbE&EZr zFy$olzj4{@$?0uJ4Fk%+uyN|(ua-jNevmhy#0}8$+RX}vQD+BI#1t3;fjQV??uL$Vs#g-4(E{59hq5=!UPHel#>G6i`lMg#!#<_2~Gf?78@#kfA z+i^CG%`6c5Wy9ykU)E-a&fDz8y~dTD41w|>Y4UP;6&U2g1&>%&ZcM%#zx=?LOOz+C zj$g1q_U6i8cfCpRh?$-;*j;B5$F4u#R%wlnlOn+PG9905^)V0#<2PiY=s9==NjQ{> zH&jf}TN6+L(fmsV!f1QHDw+oAMmIZsPW+W&#JmE0O5bRL*8l|SBhpu=!A?}qauwiQU%s20&wc8yurwd8T?d4-3D<--aE%l zNtt404ueI7)UC3_Eo-{V>#V#a*!NHAYi;9uEH-0+?_TD$o-Pia9CbU9ZI!qk)o$rl zm@cvPlg^OtADP<<^;r(-#Y@yYbM(Ch7XaecQ>&ZLEPfd9xVN2#pdo-|2LckVYAnXr=oLqLOU z{V9HZKJz_dXzk+wft4>%&1Nhi^vrjRp+Rr-acP^6dePH+3N4Meqke4T_2c&kPZ{p6 zT3PaZcXe5OPMJ70&dDNJR!LkL@dTKA(tp3Y{>RtXO|z+gn$52CbL}qvq9^NYQ5Nw3 zze)9Rux%ShB6Cpx!FSKEt`EL@ad7wyd(ms;!QqMiKi8N3L-%C<_ebs#q}3JhID(D+ zmN6HUnQY6b1gsM`3|NL!imgnmqSb>Oy@Dy}zAIMvfc=1YSViHpkH=4O0Go`EIw$ED%_Z-9WD+ynV>?7qw38Lk&!B|dDB{4E$* zh|0NbKi)t*fkRCYUCq;Ait-fV7F5G7S#9pVeM@Py>m^Zp=Bd84zjhGD6QHXelPz>zf#Mt z`Mo;ogf#tvKi~T~LW?Tb*5M-HjTnjedIqc10s*eP@9-U6%>tB&1Nbj>ez_|-L_RG< z(*@g-GLD+NK0ZDa@G_O_3}L+|S5-ascM!CG;hKKowP76^bi&*8H6hjZoVzmivsMZF zxC#Fol_Q&d?v-wGK|RL62v?v)Jy{=ynW6# z$KoU-D)#9eGAfrLNEqwsk(mtxWW3)J$?v!OEkXl&9m(&vgCxJ-63OqkiLBp!KkKz! z3EV3H4)?s?7EopKA(!KRt#Um8dq9N0*6)E^^)1Me&^W3yw_lh^)ToO@#F2zy^1E;S z*dw2;;3)mullJI2q*1wF8PlLbHyoepZSikUI^*z=#^F;;NnrYrz*%7QBtl6Dt&5zi zz}z8Z_}i@i<7%xZaENi>C9+g~QOW_=d6#pbr~6*g0n!y>9Y9UPv;!`B_r|X}F&WM0 z!g^9u@(VG7sn1LGC%qE< z992!%i76CQR?G`aN@T~wF1j*M=`Fyo%1R$nt^3NDFL+KaLd6xy4Z>b?lD5t&W5!5n z%mW(qq@>9?Q)Lg1f$k7UlcWCl%)s*WwS=$~?cm_>8Fv95xppTay%LDj%Tj#}L`rZ&%Ct4__Tx5N*MSu5Aro<= z?88GKn1?Gqw2{nbrf3a>`0GV`B1Gj78yy(-2OXAIGjfR?3hWxHO|jVa9eAIht+1y7 z+pE;t3*Qc$qMxA6@GZs#(+eE%`Vh@N@HdlIoQV}G>Oi>;=r(M_1S$fe z5BPxx7wQF{@6eEHft?qQ;)T}fJ;BcQN6vCiI9>`;o2CuX>(EePjCIa3-Kc9q3Ga~! zsOaSJHw4OZcPXgHmYsM3sQl0A^{y=IpVGfSSgbbO1B7Zjeb}aonku>()ozH?2R=Xx@aDHmRk$?wzie37+Nz3yS&n*O+-sdG&fgo94+` z(OhQu@lKgUPyo^q=Y;t;anRuWVs~|gL(r&&FE*^$-hkqE639-#ENEw#HF(CaIRPyG z0CNI~5WiO2Px_+@M&SVBN%jQm!M1&-Ia>Y>T&*TM2XJo>UG0;*FyV55!AWw_ql;?S z^yLd=@FOaLe^4?&?-pRk>mx4maNqIT+m9Hv1_CR4>)(Iu=zYYMB;4pdt@4XvSEs98 zY%V%WsMXFTqVwjl4wW97e&S~}+J^pIlm*1$Rv~(dDT<9I#hQ}WX7h!&D7MN0JD6C! z0Bp-aG|pi+qVQ^+CUTjB0B)Nlluf8=ggai;oyrC=S*C4;6omokBPtYWXSNJFU~(bV z8!9c0a+V2sQ`(&5m6JC$1@Dl{DLQG*)(^Z>ESDJiF|0~RM?HkdruE(Gq8hAE(TA$F zlxUDaO6R{Ts(VW+@uR~Dpwiv!o3$o%co}Lx+wxm2o&;HqetMYHs%HzBpGKmX28 zFKcxWeMITiF5*#}WrhYBq~u-{7iB>lwQ(quPS%i7hpD(y9p?G1)6;B`?aJ)#UWLTF zs;Hhg?5a_>ZQj&zRhGGZM=6jf>E#R%cd%5+QW@jE7Qw7ywBUjzwTMLIDYbI~ufQpi zb##sp{{W1XeZ^vXndY6Ss1pl?i7@*$?QRbJ<&09Etgh~TdJAN88>H{)&VMgOEO(wJ zn!fIux&>Z2)RG)+HrwiRv7*)b>&vpDQH(tNlw=H^lT5sjb$R#AG_a=M$-&{X$Zie} ze^j2VvNxzulCqh>Rg;O=4mU{IYG#ZWVzwzO$_O8{88wE{&0A-HT^$MN~F@ODs z-?F%%yb&Z)(8C6$6iOvn`x%xPJuty%6!6rHBnV0k;1eQ0%>eX&3Mol6_}?bP9E+nY z)sBlRF)8J!NE{WGWb<@`XN<*^GX_bvj}~O6qB^zU^ThIZ17|uTIxc)qlXF{~9#+F= z8MBk}ReWDI=f$LY)kB&3aDWuN`!N)k;qp}VP~JWqKLr;*rN4cw8r>tZ3<0!>H^?cO z;SFe*%WW2Q62}n0n~csDv7U*8#+Aburf;)#FrM#pFNln^j$}>kE?incD!hfSw*U2?kUBiG)Njwbkm$(?$WlMn zf%_hQJvcmR_2L|bo%>MO0>SpL=*+b*`VVmRsDj*$$UIBq0C&5zs43TKkc_a+VWT^M z5eKr?2Z`*nG(Kqeb()i3;dB#lW<*6iQs-emHKnBTy zN4P<1?;?+k0iYer7IYc4Xhrm&HYOvA^Wt58Ma)}V73E7+LoxlBvM9afP)w=&0YGQR z`)6c)_@=2UiYaf%jN9a&2i*~U*=|M?MqZF=05r8c6o5*h08M$9exL-08&~Ifjnu@& zHf^B_V=F*!jmB0HXw#*#UD|@sYostPwyF(e6s4j~;&sRXH9xwdE6@nPsL8u#L-TF+ zG5FnT}jpoS@fe?%=8I@q*TH1WcGSY9WM&pwuy@>C08qWvlVcd!#9%`BK z5y=8QG+azZ#3{T%pZwGcADq`~yz;N|2F;MV$+n&Bdom*MCpwNa?109$=-jo4oAd-u zjSpbid0G`{?U;4vx7h~g3@~@{_{|sDMyJ8J0cKE8RBVWCiX? zzn6M*4pdW!Jyv*nmDQ`9UcID4!hD*gS4be5tuBzTIA9aSxUor_$`oo-tc@yDC4~6G zj3xq|kGwc*8Iz!Lg2WR&F=^PKE?b)njF0Yy*s^gjV7?ZqJ?D$--L^lt5SbZJgBDR8 znjDdE(Th2}$QvL~hFRr>>O0#@RQN<_Q!Q;i0olgYft-l(6*L*H>Z6F$c}!%k8;b#c zvtAU4(mbVF8)N7QQDe~K1Wab-J#a^tQsvH$cIY>lJ$eo+2!8bY1PrB{sQ0n!V-TCI(odwqJd;Qd+6v zeu0h0^h*VjuwQI)fvkMXl$8zikZBnvPQO$OJ`|I%keNeMpg=x2*L zrWcvo^)nEF>%Kbd;2TA%l&?y#LQqN$$o#Cx*-0s2$=AQ;*{5&Pvuab_V9}PiedFNp z83+PSQHYWQ&8p(0Ag>j}=^rD2R_VW(vaJ1{9-WxgN zl8h$Z!~md%vXOpNs0~&(s|_4~nIdg4<&8F5=#0#Jq+b1!q@Jeo85#J<%{svHiC~lT z9B~qHri0Dn`;$UpMZ($u${;^J5MCJCpGnHlNM^gM|N4Kn`Jc5J|MbE5>Om_wH;g1{5uBY?mRIW5UMmnN2+!ZlPY@fPOvRB}rbv;p1{4SpE^KFb8L~%_h(|K-ehGrO=^nA+*N9EeK7qQJelYt0mFF&#K9+y6tXOjE|9r2 zylL#6W!b0I&$8rJJfV zN0J^Q9@~iWrdKUs4OfyHL)KVjN+{zxBo1#w%8bJ*Hbu1UuX0nguTIO_bD}?3sTNMo@hBZR`PucXq}5HS(cS+fVOcT51-}W@`)Tzy;ALa zKnDZm+fTi+?P1KI#U0sfb=;gF(ot8tZQH!Vtw~~tq!_{DNGv(mgDW-X(;$|$GYJCpoh7U_m>9F*pgXT|5#$>5hKBfWbw-YnZn_Qb2+dtQ^5^5`F^;6pB zzyK7%$83ECbH1t4?^45j5g_O|+?#oWZv;IRd@IPaJN;$^562Ah5&Qfv&s5=h-+QtU;u7mx>cv=V{55pN4HNzf7$mV3X+k=hMaTlWOH8_xmeTI-z z%Ho3iY6Cfrwa0x$m*QMVecV^9*5|%5id(Hb?kl<^%5ee4o}AC*fjXb&fij9n59z=o zt#Q2459oC!AJn<2OJpiGGtI3&4@1B#u%ASpb~aWa4@mxtzMoX@a@Qy=0c`j_UbSI< zUz@Q;Sqfma3#v8AFgP`}OY#l2PN8O_FC81fL$G(4-M(}j1lqLwV+Si#0KVTrmQhni z?4M>E`m6;;MyC{82l_M+owF!eR~!0_e9d2B0>}|4f$&A@Ed=l+qAyFx+L!MTAY-K$ z=HSdw?Za4>Q=wTQmT{@ij-5*nu|y|x0e#vNAZ3Qor3X>!Xm`s`uWK^~lVaBx>AZB6 zT|URy@RXEein)A7_y^YAJ)@Ssr620VEcBFu#}67UTHp4YB@!2HCzm ze0@r-&GmF37W)I5RZsPzu*8#Ed>kot{{3uwwIgB-SkJrykIinoP9Xt4l6l^b+gZ22 z?E%*`uhJv*ps0t$7E`b_7W9&CtnWSWi?-;3t;L|1bk=7`5b&_fI!62GVeS{I%y-vk zDg7o=d=-0UBA^C^8nm`;rKjRcZU2>U2pl7CqxOp1D`;;K8gNvKjFq}bN3M5phgy@@ zC0YZ{OD0Z=(5)WON))#QVZSVvg$hVuy!WE6%AGb2CA&a`>DgWZxg-UIcv+)IETA|1 z;!58nM*H@T9YO-r{m~8Vpz(1FZ&nb8hCt7{>Qn=W9%fdHLM?z51lEy0hTZXCA1RR3 zx*XleLbHqv9J@XRckVX?D6^-I7x^OF6pcOI#b#GnEx6^iwK&UaL+7qZlY>rZorz)A zZBhw)h%EcYYyEfRSlV|332AhmCD=V=l{m9?d`GUOnGkl=Uuts@$xvka!6q#{5QI`ZvNdvd(1gToWknQrXJO38erOq|Yr z>9gPGVzpa6N>_mM*sXB9ALsVI^}sNB00iR2A3*OTK6c7*gah~Mr#(JoMG zE}-3bL7h5k1Cy)Jmsr@rhTE(Nmrkfp4BIU5?k}f0`P(lz4+> z`*wO=E7MxWQ=)gPD!`cDEcHy(mS34wkC)D~FG`gMI>e}hK3{a8d89Q$VU41kG^R9a5y!QrzS!2Kb` zUe{>7+iy+$!^w&>#OpaE^*}}B?KnyLSebH@c3wZyQ%h?lIzcGAV$Q9w5WyY;$A-~h z{z+^QfiiGpfIkwIS&AVu$L!GO@Dvun9JVz& zRoM)okkM(!K8LM9r?E9g>jnGgBQ`a#T(F=joDP+bC%u(F2Qc%PhE?s_6C{?Z9(GQ& zT<*=1iCS7-djlGn=$~OR@e-`3lAro~cVQh`d-%U7eGzvwCXZ_6$q>vP$sTMX<3)a* z-4tyM;1n+t{1KBc!dq=tlo5g54Me}B%O$9wy*ohuo5Epi?IRW;%4{a~|^R5kS zFgDdxm}V0*UW9RG(_TKBM5kCErBCBjFcXM@NTKoWJ0~I6F@33@YbmHHrY+}g-3Dc< zrL47fzksahMdo>k_6Z6IJpv4TCZaj70z;=wQ$i7c!BHX<@HjJ2#l6%qB#|`*3QZmN z&g@Aca&N{5DoojK9Mlhvx)pH$7?^+HfY^RMSZO?rADnHgt-$`%dGOWI*`Mq5{Owsw z-?^S*P@V|9wFZMeyUI3o39m~_AyfU_EQoa}IB3tc8o%Sfskv z0v-ImyJE-i!Z#jT2GC6lq z`NLhV7u~>i*Jo=PoxA9Ks6Pb0y3A}|51s%&(m`bIJ84l?OHA7P2mLjxl?$tno$c03 ziY9=R3z8=?Nhx(_rD!_8T>b!MRHvGYS+d@IoJCmQS9*GVVbtLeJ|;G=-l$RGcaB4qSz% zIx#7KOEFyL!LinH@`OiNbqn?=+SkE#;kvqQDuSs%OG1>iGg3IKuS=RS)u6quR;|=0 zKYfMM0FgE0q#MHlZpf%%B1$PDCa)X10R)&CFdxF6o3TDRUYieLZw;Kr;P9TqmynK( zSbs-5u*vG+1R&cPqEp!BIlNgzm$^_p(4|FJFv%(G>qZT9CDlNlXK{H4yrstfTw zWTm+_7vJl?IzEvwwsfEd_7C^0``n|oRrk54{`C*cNbvD`TiwpqRRjO!3VQmh%n499 zXk{5bUR0sSRId`R53a7~er~Orv`2*b)jNBmzYfyAU}@EP{f*4);uKTQV&a9>Wplm1 zT~oadnC+q_n|=VJ5J~6F0%#T5vfS5Q^i=fO!xY;_9mzXDq~SMub#w-l zY@KbGeR7D#rZ6Y$yYShxghB~48XbW7B5!W!`6u6BHOhsHY^!9Le_r|+eS^P zv#;}VbGg%|ZP+K+$}_sYE3txP}H(MU9oYNk>hB^9~ZJ z;@p-_4rUg}CHAAFgtUGYjkIpNqqz~|tx->ll=yGeGAkh2y@$KRd)>f4QNJzn*ZM4_ zcj{krJX66+G`H?PNA=&-Qghm%vOMDgSAW4Ndd5G?KhAxoo; zQ%{@b=1_6shnXi>yPbo}i633|tls*MZSx3{4e?p^At1_<0x5X2o*Za`JVSgkeI+^C zUKIM)ws%;)zCeChUJkIPRcOEA-zl!l;>wDf)dUM$)k)j3+!s^OwmrdLxX_2x9c4B= z(pCb~>u+~@!_XVwWtj!HOYy4UBj42xzFRB^L)fl>v&QBFlq5P2W486Ni*-vpt4I|vP>Vl&pHT$FBH%YN z7>hrA{}Ev;-s;U8^7U6MJtS9DUNj$BWl=_vj50EkDSzMOPr;7w-hpt2;6S;_G5CiG zdNC!eS}qdvHiTmYM;582ygw$P^pk>-WCaVxJ&2hqZYz)#jMOYxLe7|{;d9LN+_Z?Z zjGvBnls?ysW$@tom{K+l_s!WDP;7UrLrC3l4LiFQC2$-*hCCp$yaGV6*lrW;^_$$YyvIT%X6;J zcLl(!d%VTY7)WjCdO~e4pR@~3wWg{Z-&t*=puhbqHU=70Bcq(Z9sKYD54)z^oN2}3 z%-;~!4=9m5?Tbdo!H;}yKcm!f_a-N8gn!&BC~UAcoS)Y_8BgHHo0w7&8XGdiz`wf` z3+tyDHX-~{rK#8(_Im?v6YyRDmX5fN#}l+F(Za~^r1ffYsXy#`@9gxHQoXg3Ek#mO zQ|gJfqiju?{P(UIC3?}jp)x88d5+42pQXQEau;#2PAQ0SE4iNR*=c;K@kV8o?Ag6(_x0gIl|yw12%R5gKl-_ z{jzFt@^CK(YV3dr&`WY;Dmv(M)?!2fH!%f@G|v`qn-O+|+5ZMInC zn+i)KKmuR83vNv#Tfg3~0Tu~2qfARmK4{fJcU*G=8MiHO3v7NrTlz5u+j@Lt zUdeRFLg#1aTIW&dMCYlqodpV_N3TASHP90*!wF{Hne)+o7%GDn2QDybl~b!)YAyaa zs=SxM8rwXJmNrW9yoxWI?B(;cpBS@2u|@K?s{ZG$G&uczF%hK2!0?k-Me``t|MPlx z!Kijb&tOfl%d*4aJXqvNtAU9=s15p4)PnKvM44b)aQ5K9tAmSO%J1WAU^s=Bf6)O^ zPRV&9J@DQ^4+Ch{?o9A@ii4%iv8K;s_C&yn5+H;tb}M5)Z2}g&UlNN2j0LqZS^Rd^ zJY1EpHsoE*p-J_=_*t3UlPhx%Ep{UuL`EOeK(fB%?Jq+qrv03MZ+~fJl|pE*DwcZv zaZbMT05zR=&nzTlNTlNm;D$=HB+lmHWU&|!VF*Vvlq<#_XKt>iR;wfrA97y8pr+X7$ z-=lZIbp6!8G9<0FRt2~-aEqHnRaT{>Dv#d!>0d4JI5>I&(M3~t zp_|tnu`zHV1!n-q^Zh(JR}f^175^Q*zxNm6-Vg6aJ_4AKKVR-@}<`FZ`X*1xtcHeK~!y9|ip= zyxxixLOAE43r|D*rVDjNi|OU(abAah(nd6?w2FjpnNTy1scRZ;hEg_K7r}U^dnXu; z{UyN@#E{QjrWjn)Mvj+So_67ZnUsp0|@MlDYi@Q}g&dVc)oO>bh_@FEHXX0V-t3YnB9 zJz+Jv1eR!b0_gUN!DtV)A9{VE+hB=?sn?e)1~4TB)0PE*cx_*OIl@n29iV~Ld9Zd+ zUyZriD~Jv8QkXRtyAhmVxA--SDiBT1E@3IiqR;1P{}TD^Ua^oqrCvm&Z-IQqaS`zL zQT~yR)R2JY_QGQ~unK_q;d%XaLsPW*;>!F%$V2KE2y$G_~gQ5MEMrsn1k- zAOppQ*k|Xa#4I}VQoy-d@6T`d3bLDuu&rpjUhG1BI-k#Ps&jJ+8!BjMJUYK6=Xd|S zyXuVFJ?JnogfN~g7fO&nZs)^=nP&nULJXr!vT#Q7EdOIi8$Xl=x$nL&6vO7zqdL?* z))Eo60k|s{RKIx-XC+G}XCj#{{Rqi)LrG`h)H|s|p^n5%y!0mQ2x_Gg2SMMdZxFp4k$x^`J){gxmVv;6j9EkRe% z^4kGRkcwJqqIYc~Pdw)ltEpz=94W*W!vBM^txM zPZ_KliKkPbP1$ErtV>>T!<|YUqb45z4wr{e%zS$R zAn&{M^d2ZZ1YjCXiZq#o`UxCqJ=PQF)xT~zGBHrMAAJ&w2Dp>@oluV{D^mXl-W!2vKB5UJP?(OY*?6M{CpPlXoTwsqWkMc25V}tc>q>{5b-z_WRycvr$`@4LaoD>(j zyTzi=YsDYCZoRusnwAw%M!=iT6WmA}#+i7_f#)%LRp}FF4OM03v?=uYuw6rM-@VB7 zAg2@dKrjyUF=RC-@Z)W0yCLp8%?J+kH2@HVH~^p@t-_v1mNsA)k%;GW4VuHp(#Gv5 z{jOC<{2}Xy`xSJTtD>$8h}Kc5L*mSIbd-XvFWy%V;<(8YI?HsSL>Gdq(sdyn1s);Q~x&wk|7LDi04L>~=5=BXsT2;u!=Iz9_B= zCIh|bk~_33i&ATY2F#I|uoWh|M|3Tf1Tt7Krc=dm+}aRCGFTXE?e96fkUfzE+c%g+akd52KkpAZPXCx zz+_v_N!Snr^X!m$;?#inOD_eZRIos_E1h@0BGFEd7t(NrqFn>a*wDMz|A;ol4-acV z{Alfm9|lZ?AJJ0yAvw|~RPf-^0UER6jaq$aJ@BD=GKp9rpSCe^-rNExM24&Nw$N5V z-D6_yc_bRp>ny5ok>!fp^_frKdg+M!@rS$dDw7a>0`Uk0vEx_l?#mB`Cw2^s6mB$B zXG zi^a^&j`VzTZdZRfQL%{GpA^U>U4F_S))`ncT$VJl&{B%XpiwO8Iw;IT#x7p!t-(Aw zPdKUyvq*rv3GLw{Db*mLZPi!h&TQjpa_j#4&q6xdw)K(Q8+lHs%_4~kOhhoubQwRaIQfbsf?1K{mlI9l*l z#;uSIkXA-A8yDzhMXYC>AuUSgus^9281s5Wra*?OqbccnWRg9JY4d8PPE3cEpf#_8 zD#hZKS_V=ka3KIcO@~dmhX?9U%826pX3>Q5uTm~<5S>~;Da$N12JySk>llIc1>VqU zrcWU&SgR5FuZP{|24>9r^W&orQD;K^Ui9RjFPX{8_%5tg#adzNpjNrnPApI4B*n}Z z8>=Z&)cO{Gt|h3sr#?Y&o$c%fEzMXVB&fS{3lik)iXG^oH}`mJqTYFj>E>Ks2#v4@ z9#w&nbe@-&=@pg>UT58J+C!k{q!daenBICq#dh0B(u2}j4GyT2gu#L2>u1aq{DyLzIsw5c^et&(I70V%v*)`DqbyzKmk5lx zxJz?L(+$TXrrev*u2?$+vOMj!+TNn9YOenVK}T~SZZGe6IAlKzf9^SpqG`t%9=>EK zmaI0zRnlf4?|A3aAnoHYfH_Og^7W!9;TaeQydTkDu={9)OG;KIE#boQ|s@`^MuIf>ycImq)1=|+ZNaV8IH8GTgK}?;MlXauJRqA#$ zTUauYYjU&hr0oz4)EJoN6}&s;(_P#1M@0o%{dJarybvnNJdc6%v`AsfVd|z-7jw4rS4$2*7HHOxfgkdIxLp z5yQ(8UswDK8mz=eEHJ1tF=bq@_A7#7s;P39~IbqiA{^Sr(t31CZH61eLELVsNtVm_v`zS6+7@b7DO0gPy3b z%C4Vaaa`rw#W*~HF###oQP=lv>HIzH;Kb-Z=`yN(6e7GmDw1kR{JjRrhwM%QcqS}* zAS9w&T9L%>Sh{bD&rA){i`YEHWBg((=2P^Wp*O`^|G~6&XS<@#cb^{~Ft#DZxFFI$ z_kxVkn8%zi&Ruys$u%t2Wv*!jDPEk>VpJs`@&!A1)2!Yge;dqr;}$K}*ZN1KiyGi{ z>+^X#<%*T#^f&HOq1-aQc_j$-8V?su3BuJ_RhG6l+^amOS8}|4p)C3Lm*}HZ}L=c2N|w<_lZ3lZOUqE z)uZ_m@gKizjf(xKt7;A`P>~=iu9_i zF7)Q|5!^c9Q)G9; zk7N<*%#KM)+QmVO9{T^RUJZ` zSye}pRQL56k0z;pKboZaJr1tJ^f48j!rcKsM?ABN?+%7Bb*TQkdQ9b}aJk2?L=-AM zAm;1(n~4UaFMn|OtOf?mG|B{fPCi?)I0I8vi(M?sqrbIkFm zGNupQ1U%c9oRAZZ8$wazYvAc_lq7Gfipv!d?>=NXZmTji@xVyq#a|XtDdmbFz?YRO zr!;wy*H|FFaCJlK?55!2>SaaL_N#nxovphewb+=j=*5IFs299B?nSv?5;O>K)NV0} z{3eeEYMS)G*3p+VqHmWqw&0p?)_@G-l56<%1z(9;1OwUAtdVN5;ghmPvj7g&srmL^ zoAiKQZ=W70fAcMG)knL=CCLX;=sbtg6|$?~swc!aHw`0f^P136^MS+5n4xDIxH)Ao zSKfg}FEiToTQ{AUX^TVG(zV(wpW&s$B|tJgt4-}mWWXzWY3Lxx(&Xi`urBSo+HKqW zV|2k+Rz!0S70Fz!=$weNZW07Sk5S3R9dgnlwbAq=u<=J-+#w+?Xkqd;yH0sL{+p^> z|8|<6$Bbgu?$Q2}_M{Cq-!B^erw$l>z$|CJk%u+Q1((QxS2T^lO!wC;i35pKvH23={*7DSL+Mi^F;aC#U>2$ZpknhXP!G zBp9{=DGuf?95ju~L>Uw{X4_EVa=Hujb8t1lY^w(=g;VgvOGmSN7<57-9d}WqA#^0G zhThlom@QK}l4(PaYhtscICK7;IEN6aa$-s7OnWkvFaELXFdL#P)Tb1tPdKg?`0pZ&Wm^ohfyRqD2ULEks~9#?y$=T7hhJfIH-v%j$I48u)R z7`}v2tgK>#lX;h4ksHVwe;;z-(e95?-OC6x-8pNJyBn|y&sSh33$u67=YXxHU7L_e zGYXFq^h+sMr-8K|>bGNRlYTYtUj)jQNBLZ-z7=H}V%;0Pehba&{R=8(4iBTPqQ$P( zdlSZ@0~^f1vI;+;-P6%PniXBg7O z)xgdLsm}Yj=&c4!mNt1@=lEjwa3*s`7t41@1M$7AX-p2sCS#Zc@m-KM5w*18b{ScH z2sUmLb(eA1HrCXfZ_px(A@Q_S+~#aUek&SfScQE$XAYKJHyOFGz=@PythFAb&M|5e=w-Ki(Z4pAku%7m>j$e%UXG~M2nhnLykf6dBIftp5g=L;T>r<4Gb%FI#OGIQ!#ztEQ1 zI%antBIoqbI;08EO22W1Nuwrdr?Z}dD zq{#hhrSL29Dl%asb1TZZTP|9JZw?Hq-!&oL^jy8(1Q;O4yfpZyH|qt|Q-247x>@b5 zV@Q_1!W`dFepLJH!7hWogGZ)Nl_FKiafNQWkZ)+9Is!|v<0oRJkMYGC_wM)tzh%zv zEZ~wHI!~qpkpz=A`oN(CnG!k_OEBr4$w|@RVi!5JdrDHV7Bjsmwsm`*HIR@BRtqc% zdpq+f)Rihw2$`v1oq$3tc~?-?(LF5_s5MtmRZ<_nC`t!TbzyoZd}(0|o!+S{1PAV0 z_QKdw#sa^_wJ$fvlFQCfx!;$?qUH>8iRb1eg!mCN+1|lN>AsCD95lt@3E%CQ_q?}M zjZ=fTx2_L;ujJ8AI^5vAJtVTVCl5Vw4;|UslfjvLNMvhI+VzO<@5fI?exU&cjnw|h zi~w#iHjU5#fV?C%2Wx05R|N<^LOKL}33wJ9wxOw%uS#ta^JYzT%Fe1bPJm`!x>3P) zJ)8yqccd(v-Uf1)4Vk51l;~k_-G;Z))15r8ng-o(yK=B{Ngy>HM2#eL0DmiU!A8CY zKa@>MxXD}P0f3Fbg0;03eVu2>0O*rfZn}>B?wr-4m&X-va(A;D{?=ztdjUoUsc%zO zf_lCDEIzeSTs=Dx!l{9PYneA$VY17Q^$^by>pqb*rxQmaP0DFXPP4&k+kK|BzNx${ z$>AO8oAYp`GySO$oGc2f3XSBev)N|b42VEdQ#5qyq*`U$Pt}b*HbTZ3X;fCDNeqoH zy4yWAa%QMQ#lX4MAo7N_Va$ie>F%PZPQ~cFm7=6tiP0Nq^&hCSn zbbS1nA95%Li;LxLo_$Ki5pcg5E)~$-nhq3npycn#yJI-XvDrmQ>$~-+cOb}yCpA&} zI%*oCV!c-(#{spnlH&jot10E^q7bl_1S^V9OLcS#l~ZV4#BZ}5va(F8DqND(JX~3r zb#}`J>)j&no*sLK`j#5|{*_KlJl>BfW`VKgTQ0sn4jLh82E-Uk+`TJVjZnq4t6J%K z1sB?@NaQwg4%i4iysxX}#IpiODw0fI1^8GEh(ov-aqZod*Sh0nb3|+QXqW>}@E%4aK*iT$kkO0hdDSTJoW)n&~X89mgT4k+iF9vza&*CgXJu z$ox*5|DU~gU6R{K(gpwPDXK?;o#|P!)uc3Yx@FyFLl#9zHe$2HqDHp;V`0clWEI3r zAPHnvu}GuYzQexZKFNm1)jh%^5I|;8I=08GtyM%KJOV&m{POwd%E@XQnQ)ZM!vmXG z7J%c!C-H1}ARrs6b&b<};5&%P#hg-6IENB~b9>+|8X=#(Xxe5gVas-h$TW6!OSHE@ z0c2e(4_vL=>W!*`97%YRSsyCqxYt$jOfy;U7=`XC>7IbUPDoN?19;V$mVOr8X92T1 z=E4^R%HYa#a?Y?E2lP^P-Q-avUU)mKC9@wGdR&hEWRNO>f{pfNQDQ39OP-AMPLr^& zD!V*vT7^GIVG7i(XZqI9E_Ad8)>aDshvGb@39KybtT4J3b&^k4x=8yB*TvVW6weQ> za@}r#*sQ&?b#i9X(`9)!zBYw<;+KE76EdYp_ikYP*q40dM_Yr=$_k0XOO8-^2z ziQiwgtz31=bwd4&ofL4_;F?ohb#I#ot7e%!S?Uk_` zXcs}2mh<}|%1vE)LzmuVa9#pP&c2Mn}uzo0wb6Est4UU9ELPj zRNO<~q_Ye*!0IGDvp^@p8DDX~fRS)!B^Z`%p;N6ssT0!mmvBQW@~*3J?N7!+D)ufZ zN$jW+VktIsRRt~29}x*oX<=tZnDtV~w2dj*QaV|~&$Ck*9A2i>#mTZ6)Je}IB)sF| zoHNqRKYJoYiZu@Qf-piMVz9k~gnv?*>bZDCbS^d2fP zxsH@ktg4L$6`1}Z^his1AU;XEKWv45=9El`)^(*9{F#>LhWj|veVm~_WIRvwAqms2 z+UC8?N$7TFYO~?Ote^%Gc!mU;=%LXzB-!I^Ekja0O6}r1nX=55$j&MNq}rPb*%TcC zW0d}fJY@?p)KMG+j8@9|?3Wr|Rt?jip@oDKLfrrpS#dx9pWOlGt!A{8N0++v8f@t5 z;FnR1MKxukGb2ZyWa^TU^VxrO!~4TVvXDX;V(vz$#GDy1s&>Z1K?gK4BMmzKp<}!- zd(;I(t2W`Qa4N9oR8!yNVroLNi;h23CzD(-nIuHEfiuulZQ`uMJ1D>U5CK&rGlHgC z77E7oo>vPdv3EG&ik2=jyrguiG5{>KZ=hPA!nNkPM@%b)hW$(-k#w0{#nw4FVj=&j zMQ91olY$}X>u350O{#iT?_SVs!_~spKlks8p4mOJ2;H%Xki} zL=`6i)y|$>E1T5D);sHKW@n9%M(Dj%T^Bq3MmxLUps4M6oaYt?x;s5SDM-4%JVC|* z=yI`?H$WkS6e~||cJJbFb*1~$9zm2CCS3z+!`4zAaNT_JQRk(;jbPX9)z5&CP6n~W zfEG;%gh*jCq3s!I``JJ0+r3Z$dW7DXR##XFIHLk^!If;9JbT40R3}F3MA~^}0^Num zuWQ#r$;kYSBoL!h7+&sbNSM1}nD1uW;yQ}~M4uVa7!t5lu;{5pY0#;M003H;ElJ}M z{Z534#@T#BtSDsg+RUvV+H}I!ME`3*Drj@IbVqTP!PmDqpS(1&&&ajwmg7~PZXr7uavW#ux%Ou1Gh*sv0$GObt?2W>Hu9CNxm6SGPl zjHr$7phOn3snKfkxU(QYF+h!}&uY@KCE(}jrdz%_O=6@Jg_0g&g)6oSMA5_2#NfFC z%T-M;M7<;CxWz~zGi5)`OmQ-hiDG1Y_8sCVp2kTm-jHI%KrF+WzvAU#FTUzGxsqrY zQZ+8VdLqjaRL72Io4x$Y)e&GEdndAp1L=#gNGG!xW<6^}cz+GDHurVga3YoR8_S^Gn+lc8R*6=0cw#ltBFFKHNU{xzQ z5{V-Af1O}&Bax9*-2g(Nnx7de027sT`MApJQ!WCdKm98n?;j^>Z1SH{o>iu}K8nYG z!My+R%34*4^cr-+l=A3i`-Jlk9m_D7|+ zm9d$MDO2>{-Xy(LGfh|-nmSnLT1)qk$~YKR=k=uBnJT8Btmu-pl_3w-Kb}1RNi zijLs&P~$UbEayUsx=DU`^UWPS6AVZ4ziPmORM#hlo`b9_Csd&rq)?NS2fz?G_!OFR zbJ(^BTbS+FwzA~ury!Xi3qcG&BLqSmbwq+ThOh-`5($9D5Q94zt~DC%fT9Y9o9K*) z$&8&s(aK}ur?zHgUIY~?S?bNVSJB3B6W6O-{_ZwfbUTNOK53nI1{WPK{r+V6rtNNp zGH}Hy*16Vbq_CiVm{Vn&G7qL72j`ytC>GKNwgN=(E*F+dugr4^SV4%_U9KuC=rc_p zZAjf8E>9UgGThW!_?Z^|nTiBGw7coU|M&m?e`LrQLP7syh?#k_qDett#kY@(zx=uQ z>sPi%$;agSR4vYIi!(7g8HiS+L&hWIH^ZaLuOkimhp&j&UwpT|R>}JGQT!}@IBC>2 zax2ZLGvp)iM4kzeDrp}ApehX;3N==0{xhcpD*s?xoVgaxjo9sS_G=yAv@S#4>a!nf z#hIU(sy@bitHoJL3b|=D!vum;wQ=DlpDE+~ah?+5qSe}_54qSr5eHkGd+lmba(48L z_icdLU(%`|XW(DbP(qk+rsTMGD4yhjomk^#bPxDsbpvGqR}YQbI&XHGW@n}uI85YH z0VEeF6F}Z^bl#N~dS->5X`!Dz*+ErDG45)y=OlN-HlNYw5q3pRaJ1WJn(OqbBZH{@T3F(Xoy<^1=?F9Lp+PBal{b{Hl zCon!zu-DR~-phVaiuGE0oO_>%SAA8fwf6A!L42+cLLL5(uOFQ0|G@0{c=qe&8=ck0 zpoRhw#s7RNTNjVdi^qRPe}b^$e?Ajxpu(k>Dpy${Z>2+UFIFn_X5Efc!*~yspZ_rE zr+HNmFzx9hL^;VxTk#mWwHotK?-$Mf4_fd)|7kK~^}C{7NTtBi_o$}D<40DqYmVQN z?57qRNMCy75UNw^DWg43_OiwM5#ytGtAPnywA|J2-*=@hpQ%R$hVh30jBxjneK9jp z4UxXZNTGM}pRj*1=-}Np=Dm0?^v7!d;0*nPj(HsLkJTKsxGJ#X6Y>h{S(Zr<#=9L-aT3Wq^q@xh{7$~s2nva5w1z63*E0`Mbq2foz< z`AW@KgHOUtCNRWO^9cu-l0!&NEqP|iD|krgOQq%;3{e~$Z~OhD-S&|^lB!K)BFR&u zmlU$Jkvxk~GxcIOz{Y3J?fkEUw5`0{hyUi6?Oz}|&qq<2yN6J8z` zZx5YPh2>@Mg8Q2OHaAI~9;8&``SAvo{HS<5 z#&_48`V@!T7!s;bwipQ`-PftYz^a_%-X@9FXS#nSXG`Tv-h2 zq6w}^82;FoJXZ*OUmTvC{Fq?Pd5yHvz+YuYr{AqGI@I2#o>uPbf3jcQ(Mapzr%nOm zUo}n|PqrBKm~{O`hWB;f=>a(he>jz*k$_Euz1LWt7zCB5xC3*QO(?%#l+pfJT zmyJ%F@bp3L#g++vi6Iha_eRBwB|Y1`?vdJv2cVv4C-Y@XT~wM5S3mxrG;;e-FRDHK zCZlKdKMq^D{-kNCj|FpBu=mI<=3`=Fpgdk?ROl&~aj9P;BeVOkJBs2XR2#FLUS+S7 zCDm(j`q=ZT9aYuVRV(Kd6(ag3VpLa}+C*&6TRWY>BcUAMkz`a(#=BV=y1K@R(Jef_W^v4Xn9*`?_*}@Vt z9^{B^0@f=0^Pm4zBxdffh+dMki>kxBM(D~=lr=VlwCSSESNDS%jQ1~23+W|UQEhkn zek)r zN2S&W7qYE^NbQ2WQNjbK#_8#isu%vE@_p{Bc2nPpBeEGFqNNI==+nshqqMd^*?ELAYplqzxr@M6m%#!DxW4@k%thG z2jMLw(Wom}`TyrXiPmpb{hxk92EY+|zukO%tzUOc)qSGhqakD}{Mb#exc-PUYvijU z??g@u z(P1FVC=n|O>p;7z@_UVKtA>1%2r&DmaZEuNzh5_I9^sfwBo^at4+AjLp9!UCWyYcM`_XsG!IXEclhRa}?oQB&PcjyId(fI?MCTB}kfTIsK;!Y_FN z8%BUK$l-V27a39J)uEO0SC8(?X5o5$aVow$o6`Pgc?{#s8-s}Hde|ye9C75-7{Nbs z^3@`wJs4M+T;|QPYh9ym#QDZ0>6m&N z!C>&72m=C~4RJZaz^KPc4NixeQ6g@3f+8b}(+Csfb$#{D(VLs(g3%8pHc~UzsQG(>hZxbS8H@JXY`POxNvNDWR78+^V@c-V@3-nR2nVQiHW2 zna~YMP&yCJo;Ft!uoZ>*1pY<}^O2Lt2r)hjoe1w?}6zN{LH}8pZUYPNeJDb#$#u13?FBEwQ17wQjfHEBQ~Hk%H}4_rLBIlp3q*CCDA1E`-95NrQY)O!>Mk1>JItIe{}i-Y-On$Fxc zfRBZmm@oy@MS*Fq*(xNP71c{#>wA32g}hfODQ~_iSC1Z*yXMhj7H*wc?jaCkf!5dM zjodRmI7&B;MPYFTR2%}PbQ+b?9=1>cFbJ~asQBh0U!m&-u%vvF7?yuk)X5ESi{*f=6N8yWXT(h-+>$0B;Ii@md2Eb(HD zX=N-AAlEliaf9f3o@s9i9=SMJ0&a-ZP{LwdobJTe9;1)}R9$j2}rqeLaUz_tnz63f=De9(uBWud#M-SJd(j3)T`ED?{LvrzkC_JFN7IL(>q7cP=Oi9Cyc+hOVm~b>)^$uYL;k;o z6zD%bKJZ-t)~3IFQ{U=Z9%-L}X3=S!o51{+APCGq%tL1Mt05xI+F3>BAb)W76NGM4 z9)!1wuFW-Cs+6c*HDL z?!~gu+OwF2(esX+blyL;G4i)>Xs(Ss2v2enYLYKIzL8^(J@6uzts$ePx}PnCPsgzX zGUA_hcJ@4PH8Hi(_cjDZr zw~QT*nmQyk1pGm~VH7qu{*wDDk&`DpKdcBK5;u_aEKriJF^E{?6+{&fCL4f!+c?ud zSodH?nJiWu!pxaa=1_`#Xbs^F%~u}xU2U3$#%3#bzsr35^hxVp-$`uC39{A2D8w75 zfEKZ5x@RS4hN}kq;ar{?uhrqfTz3=yoOnavNA6(BJ42LRSXS){qT0@`B9DRI8T1ys zHui{dk09?bN6c${-lXnf7LtFYpa#jaNqm<7g9Y5qXDlfmKTTk4eXf#PfoAHmt^CZo z=Qc}_vkONee!B6OpK~3culAf~1!h=#(v0(WeGdISKT^s|X9A^?l}PFA8~_Jp3WXP6 zRA6VAEjQO^V-tp6u6>aZp(BIwaX4Nw5dQ;s{M4afhNeyDgDePuQ~M`j#lrSJR7~vl zJE&B{de+E4ClZ_x!Mux&UNXb6?1zS?iF%Iyyq-g)`&yd(w^?8d0MCX@Eo5Z32Vsr=N~A*qnfb!Dii2 zCJr(lo(S6*y~f5ThkDx}zbhSZ5TP`8fBAVtfDJ5)pQ=Su-c^V48Yo#Q57+nT(j?{r zEDMN!5}iO~%kL%`G}oSmub*!Y?{dd;^>reYjRk7(=(373(Et;I^y8>MvJWN$MRBr| zdY8(o$3!yd0(UlvH9Z&((3Bw`EihrK4yl>F+31ULU<0rXr zYttbcL?OR$FDrn>nM{Xo-yRyFI6y^fxuZ<|5t#y~P8=YE8K23Si37*v6F@aE zm9A7mVd1s@vWm7BYJ*MM+*NHcUM4t}sZ_1S)mKnz5bxk}i2zvzk1%#+DsWr7UE9`5 z{!rc2<#tDbRX@BG+q48oe>7=qgbC#XMtzBm3{ot$XE=V}$IS}hvFzdywrQU zLUG%$wEo$nZFx#zWqQkt4LZEvrPXX|lo=6Z!<%w=t`v{Q!LFEz`T2AR1(%Xf z-UJ#-uqFcX2D&yBgH;o5qVkX!PtnbC4Y&@-UaHO^f8&$!XR6HTFo`?|45dOm@FK z$5Oj**5dU`eImmvJ2dZo{Inknl(jiuDz3|RpMVKfw4 z=arpAlxAr%YZI1L1f)$SiYWutP}tG<=EaKr)AOd4i_tijm_LS%**rH?l2e`4YW~z?>g(oKT1h$_87ftComnAp#xR`UTMPd*6#Y zUKW9qUl3TM--Fg%ue;mw={6QS7wiG+P%sm5{u4xHoyq-2-c9s z{IUn?3tz9Fhp>x`0NFV#b(%k#sA4ZS^tNx_9_pc7J^Bg~CH~`>e2a)M>l}4p1)1x? z5?m-$KE!pHe5+*aN6K{3pN!55lLTP9OM;T7a$Y3CNfFWu3E>@4oQwgIb|M9ApI#AR z)Kfy83i=B6t5ISAmyiGH=m8K1KpsheI{9YfC4djeMn#@hebTHlk`;{*iiY5Zc7I;o zK~&^4s--6`qFrj<6o)N3EvzRZJ`U_LN(`WAA?%_vV0F&CIWO!F6O!$7rNbe?%2$Jw z)p5*A(g7lQ#*KuPjb z5#dEX0eqM`v}aVbb0Tk3S8OxS>Ar5t$pA@UI*ljX>Sc zj76}&WW^n>VI8;P(m~<9X5lS|E^6c9ZPFRFIY2M}Y?}Vk= zsX&W(#Yd>7-Q{PDE-nO2v~B%?<58YpTZnd@oGrNGka9fG5=3(oWt#S8W0TzGGE<@g zd01W%P*H-GAy#$O5*{?So9hWQZ9ip&V(=)dDa@cB0X$E>}?Zn0h2)wJ&R+*VVodT{KS?nMdkq zN`$8@0ei*y8Uq39RUcX~h)ca~G5T9fW8)h7dYfV5Xl2LE{;o80g5vs^_+#Lp$n}Ir zJ3}DAXrz(%La68XSuK)FVJ_@2nP&b9(TG8Uq$3`u4*+U*mTZdb#`kKio3`247DvZ) z6}Y#I;}mykpSHF(tpCjdrDv)R%;{Uv?yP=@wJcvNMmaTkmC;BZ4O10OY@Rnz{EC+6 z`b`4}xOO|xYjPv}1VMwIR5=F^s!HoIv39^Ch`kIL`(Uq$XRG_A)qB&VG-Pnet}Ix> z?<|-c-#zyZBNb(m>qUE-zF@pWxp{Y?uZPRKyQzD5JbN~{nG0zv{Kjn9R0=Z1-B*Hb zrs?m>s!^xggdLq}$8YGHZgA-7Qx&W5;zFd8+^~>}?jPD!r980ZvgwzHWEa%1aX1+EBY)~Ib=ub~@M z^(ypZXt$jP;;NH??5b*$e^KomjGV%}KYGagAYhk`F=vN?w$5NEEb836dVf$BfK-#G zRKT1`*nK)`Um|>MD^qnEL-4AqArGt;t{50j%e&w~H1lx1YG5weEZ}39YgBIP^}dAK zVeJ*sw&X{8)*Tj``n(%_uG)}~G$KbrE2t#xq`%v4C2Q?>rkICO(fu4f>FtJd=eF6b zAV;q!(?!Q{W93dVJdCVd8q@WQq7aP8IN4q%m!F3g8JDYbPD=00JibPdFOo$eTFl&c z=Vf2DZ%$TI9v5AlT7jp!F1_&3%gdQ@iLlZ4wd@E=sGU%`4OHoCJnUF8)6s~y#S zbv9CAsHJ7N?CluwxF>OD|GFS0t zk~_z`EBJIz?azfbQTa6EOyn#XhY!|ZPLdr2&dxdKKPI zlopWaBbgJRIp2MZA<4^0fDCbKiZKjQWMqDGD@&SDKS7>NPumt=rn$@$k+gi*&DC{1 z?91C){IQ2}n<^@kLV!Mn);~7&_p0qLvgwzH0p_MT$22LErpOP?>k&gf+y0F95V!Yf zn*B_lm!DG4y1W_~QLC`FzXxY+G*QAE<)=V-t4JU?Q%5Yj$>|P(=t)@*O$((2msP*7 z2MATD8i$dB+vZe5P79j&l!j3y`bs(|UehCw^+$N)fZR(cRRa|qtNx9(UR72iH_SaK zkz6A8+-wcQHBjGuVC3VXkiVLm#ZyOKX4mC$*1^~h{S>;r{FR3kRw%Zn^WfNFE-us zjnK?1nIfPg{z+~ro4=vnk#qvi0UPNioJr@QrMi}sjzUEd#^6c^lA^~ zDW!wO-YALIV4r^bwzQR~%RPXETI-0=52g+e70EPjB$=9wZ-h{~>P>CR6FRneN>rkD z=P@{i3EQ=J7wX`Z%Zx`N`1`aNqznMpf1riApoUpI&7iOA5H4zgm5;{R#DWwANZ75M zNSDfshFCm)6c+PR#n$3k3elmGEt1g4lN~f5G^tEsSnTg(4d2OzZbEcu=VAcaZ0y*k zhVxw*Nz!50WU?qF{p~EJScK`R2EXW}QI5%qO!`vW~iyLK5qxsr!D6TbYs`1fyT@l=N^ zAQ-c}OVhkMYSM(R&Nh%C>2@_@7SWjAh^i>VdQNC!N1$T0zVXg%x4EedwnZd~f%>LH z&fhFlcCJFmbVjk+7WRBpg~Jxy_*L6^`SRKB8m4jK5&*l13LPugC~t{=vlSY^>zw(J@Z~{x7?(U%?9p`ps>9KlRQ|;)UTy`UyNSVtE|eM!s7M zvpETkC?mMw8AP4Krc?|zl%Y2$SAqz8PgSfWG6poCV--nQ#@#Wx^_8%$>ay={jcW9& zyB!aa5dJ<-1e{_}H_|upO{G9w&|-=!pJ~te^UYL3ss+|+unIG#u9%DoMp(h|fE((S zrPx1P#W9JEz|)vCIzWw*;YYhn8Z-MSqAl`42&!$L0JXW75}>_~fL<^-uaHXl-OknP ztRr)6S|EuNIWe5HfPM9=XU;I;DSjYvWi?o2wrJFNJsJYk#ZaRbs`6zLg*oy^;mFrK(fjn1ild_uUo+(%2DVsAR3TzCOA3jY{orkbO7lODNF=m%%F-fkl$wS z(y)n)482^xfZzvvJmXjiC$I3C@UX<-tk$|xd0R{O$BfgOl@L9z+p=C=dG*jFIoC)j zv}ZD(zm|~omHs>RHD#i{L^`7WkZPp~!DiMwGovw>b2B219$nJ9Kz0U8AKu@-IV$(J zJ_xN_SpKa%q%_O4?GZcTaIe;(GCLbs0)R2B(Z*1eH-ZBqWIITF;RULgsz%~E!H0|H zh_SR6r>f@=ismp$fi?muRn)7^0w{>qr|)>>no4}e;5m;2(LTOHJ21Hv+NnJLwCA|s zAn>R;EH#Il(%llEzM!Tt)Sl_9RGOtwwOQIY4|vp=wd0^mp=lF5L0FyHOpB_n=xr&NL%h&3$!?9sp88 zPx98Os>!_c&Qibu-OH~mLQ5{3nVIVe`GwC75+<>07n)M?EDkE|KC>mMO@BmMe{xvL;DaN%bdrppK_^=|Be5FrZ3`&}{XT zfb_a!gyjgRTYNW^if=qT)w2#*0BgZE~g9NID= zukUx0eJtOheDSIAegcOolpcT+`p}BI867@ey1=UOj0jJO55CgQTCC0=Vc*ShN!`9^ z<$thuICGzb=2bS(t9nC?*NDUGzRUGQMw4)$b>+TfKm4c6C?ZS$-*GJ8FZaW zF4P%128E#0iog6E3xt5a4Wb#L9#6mIY;o^g*_y9NhWcx$pUh~Rex^H|O+eFv-&$Ip zQ3h7#JHV7()iQ_O$C4b)EFbS7u(27od4)SEmmSVNH}&0;86TDgEc_Ab5#%J0aOD~j z1>?A}7PwH{Xo5(3%o8$Cf{G0xs6%T`{Fuh*LbUIzR`I%lmYxf(&v++xgkrA}v-&*^ zDu41C?{pMMle_2g?qEc0DqDTzINv)JHqq-oG_7^q8(k)Y>>+Gca9j_Yx&nrlx$H~S z=DX7WlI2LH|0592;2fpFRV|0!feMW}pnUN`9`wcQTfyYX^_^uC|@X^KT zGqFO%3$fya$Vx`pz7$4^G;vGg3}U+TUdB_eOS=?1ZPv&|p2{bQF^a=XJV1#bnhQq+agxL`tB5dmEPo&w;h{1HQrUsvXIl_ zP2IP(nYlCaT5{Ty{1y_myFegTG3mWb5n(x> ztN%V}@0gUCRHlfPR=6w?ZPA{)zadYCCd}+;T7j=yCf#P)A<&(lT;O*z!NcVu&;c>j zkvL>dEUQy1RRw~&JE|;GHn_1;hFAjDhJAuKF1x3#WP(yzZNz>c{^2vvWGp%4SqFGvL! zxY(YbbZ2u(#HqS>rh@Sf&v7<;t!0#yb|CEraucI{y{LA8raymh_P1|h;9RU%iIs;@ z_~-EN5xONQqr~+B0u4^mSr{Drx%!VfVspl1&g2NL{v7?T;9xpE5Oko$VWccu7!++G z)n?qY_2A6=(a4ebk4(Q8?rg-#B_A@?WikYEgsYgDiP6AE=rjht?}zvhU_t_?0av$Z zvx@osIgZued8{Kb+D{PaSXN?_1b*>u)A-nesbDjcdS?L9P}Mw7i6p3KDyFdY%Ng}> z*$tj)XzA@H6e|j(6dsvfSgQz5&}Osi_Ad476uU(rHQY0pErBfxV|*!u=4(EDHBuVJ zxkWstFB4o@sz51$*>a@gV=F0-cbx67@HnN&UJ+xqybvn0{HOjSGtE<_Y2|TLf@Jao zzQ84B4kocnvrJ?hVR5`;IQv-fIfoX`Ywy= zI=mQYus+*et0VhVo|++4qVZBA;>wGv-^-v?y@F45P{Fi>?#Vasp=chBCEtj?2K9v$ zdK*eBSQ8_$<6-o7LWsZ7qWqK0{56yArM%gxBsO!$oCG%M-FCSxGji9+D2ki}HgacH z@*3e~?tagt(cSNoHdFA;p^$K}-Q%Km6;uVY>ANKlb(d3^VOa7+q zZd*e&c91nG`@S?syzX^8x=}C@4pw0)u7od&$HdM5)tlAZ@R5~vQ z4S}NEN8&qONrmOS(w--c^C^YJ`1XLQ zb_XW)UXB$Us$|jfKG)amI}tmF@fVMFjTSEI-g!dft2o=4`dTYvn~l;|da=50ASVpK z?TFLZSdRECd~o*Tk3XIZEunt5XV$1;7#NdXAZ8i=u#*3Fy#$_F19xIrUS}jyM5Go> zHm5LbuYCx|w8Y_{J%=IDeVOEUe(lXcjRi7uaAM*W>EsT_y?nB?5k|Owg2JMfccoYGJ@J2UPrq1|x|Ld;rI4i)!9kZ?*@F0n!Z*gBMl-45V3-NCY) z=xH&*?-G&ZrdXs#bhDJq73#!0eoe(>ax01>u+pBEWYWP&sI9ECB{x4n`uF<15QOSZ z@_buSy+R8x`(z-m2q?FP=_TL1HY{LFDKd%LrzX^h;6tx7u|heFOQ`?k;_||Y3|=T@ zKKh`bWxrSFlAi<#Pw6PJXR+(BsgGfY?9=)r+L;VHaLmdwlCq2V`JH`cM}-9kwtqnH z`Wjo890=*b8HSFGfSRbh7_3PSg#c1K4G+v=bZTjJDvkTrCHjmS%L((fGnr-8v~RlG z;Z0*0HY4x~4G$TkHt~=ky!0ppIB+E@$auFdZ>qK#uH9?V{#$eEqiD3!4TSt(>SmJ} z4D&sMv2J1ijdYAdceHbTX!P%z8_iR0@ClSU_hh)fv7VApFiBqkDB9|T$n)^bUw%p2{JC{T3bRCy3l(?;Tc0j<04Ekz7QJ8Y#9V z)qPOgVKO)iNh`Qo5td%>&yP+;lR?s+1Mly1<~ag>&!*MHK3>9eM4E%Q#dh5s5}_6! zcL^FH*aL*UupglU(d_H+Mz)8|zS(W=%4N4XY}=R_qMoq)slQ?5h|RIRB(_hl79r{O5NN+|4ud z{;5b7Y}AXBC{;x%({v7Jr^U%4VBCYVJa`>y??dZU)Fc4g2|ZjKCi^>%ZQU)h6R~M> zebJe60y53N|NRtvm*~e?kF41(i?5!E|J@hCrGHb_`ypq}}AXK8(qMOBfKlGo60pXXE5&-S{;QXwuQNq?%~14ZPX| zM!C!JD4i{#Qzwe=S$%JHpul$YtMgEUMfwN3Rn0PJaoTX&h;8fJS~S{K`{lLT*DU=> zDqYKD&;3$u-h8Q}Ee}n;7#wH7jCd_n#P^-l0$t@RYvq^bN+V4=c~fk&8s58N_&DGPjS4`!VgKalgO)J%-6srBsfB z>B&X#ECJFpI~j-F!-X}EO1`0`G->vY%cPB`HJ^x-km)U{%D&F@%!>z+oQC&J;*UBB z%+eFs8(yW)LuB5E1PVtL6g|Y32T!e#AY9NTH#x$g>Eoor^2g^J^HcgHMtuY(AU>hS zU)86`YFFm{#?*=mr6)b!3I}HSXTj~itYO8S4#JS`AqUU^3b3PbR6eOv+3@RTS&igB z*-FmRh!mBo#UTsg>($<2vjGh%$#yT#&iDHYQy%{O)6i1(yxBdYGV2wMPv^^rt& znIJ)%6($!#N)&5HP7cERDj}f|Ws!?lV^R&$Q+(g=s>1;FH{nP~84FfVxCF1tu$N#| z-BwX1$WV@A!Vu%+24fJab~p&K`pkh%b*L8&%&P9rCt^3*6Q`2;Jrt2#(jJf(SFWbp z`NfeW=yB0~Wu*(U(DTCDW0EqJ;_X7Ug z1NnMs%t5`aaRbdjg`8;?WH5(SyqH&Q&t2!+cwX_jLX7ugU9~zJGo;#=g2FEA#?JHX zoFLbzh~)&qo?$EW!fp}`&geN>*22PF0Wp*fR!**59Y|6P_MG&>5z1)1#bF~hmV}*f zGE)KflxHJkn+n%m_oh@SOWxTxtJbX2k8ok96Xa0_LPIr+Nu%8N;#oY8xMmQXUa-$N zQ>oB`@NUU>9x1$Mw54+O=+EV@`D+RFI`*aZ3(u>8l9pMRqA0S?+A_+w{93HE53(+) z1KB;WJB8xsyEj%oI=1xG7UPtAlO3sVV6sepb9wvfn`(1#v*&rWOe;c4Go-BwNfD`0 zFq=)F^`}x*te!6sak>_kur};R7pkOB@I3=8J1(7t%{KjAxoAijH}7y~TJi_G*nMO8 z4Yn>~5Y!6EYI)t&cEo`@_!5k%5SC-2g{nLjUlSbBESQH`HamN%M35dvHaWKmoaf4N zy~M%XDT1mi#P1S9xS{^^9jk(5>K<4?pnS+KRJE?lyJ4>mPpuq``x{~X81?E8lcrPF z%+Zo@crSAX(LCG`W)ZJf!+_!H-4EfmzS?oR2#Ks9?#S4Qxq^lAk_m7&eae@2{ z#)#!3{K_o_E8E?2Rl~rf!eqP2N$d{V6=5!SK)0$`=pqFVVpdnB>bedAMVNZo$+eV*aLAe`Q zMBb?8V$%?F8ZAisM=FQwIAqpZbgFADD=m73bbd7;cJX=t%&rU*C9VwOIT^0K7=0xZ z;t9Mzp2Ll3?#Azy?`)%rKlZtCOh|ZB7CUy;U*R2@4Qn3tku`rrx2t>2^y2d-`8%>2 z6|)iN#X+S~xUbqP$Xz6v5~n_E`EFvTu0EL)$$DnS%Ip4>Sy5(6@9p|epMO-lLwB&h zWCfy!dfSv1mrdPT;Ozm0US@D9)hj#3IFj|nc55A9LB}lLU>JNHpajB*A@ruceb!Xq z8Az+#I=#S&OxZt9s6M-g>+aSvL)6AC8ac$(2_+8ku$8o#K559#4{WMiQhLn=Ro${jaa=pPy$)_W(lM%499(hdx}R zXy~J@uQoQ6WOu4j4JBGA5z8Y6o$T$UF|L8yTVq#~7U>Rd{POdc&W5%vc|QZPyUiRL zONPqAE{1Xooy5i@Nv(UZ%-g0kG%&ok74gM@1}u#Gt9q}?Q!6yEV=6yg0k2dy1;@*p zsOGBcI{N?gIq1hqJSK~}qRNikCBsQ?W4FT0F?h+G^dY8Q2-u)$HD>uc>qwJg=2>Ts z8*CsMG;ZDdg0%yp1_oe-&9~;cL?{EGHlr5GYzBjLiJY8q<%AAru^OOr2x__4joAAk z5>ihh8x;L;+Rt>Izaf*lrBRd|^SeG|)ntEgK)w|p%Bo$ZC znqbf$AuiLM#?xYgq)w)JK`4ol$va#(;yc5~j_f5oJl+jF#+!c+l`_hYpm$*0~d#F@Rg`xMyxu)kBG^L5GJ)=%Fj zbx5zOP1m?2G+95@4#`a{E;A^m%V(+Bk-my#c95_C_qC+GDEHvIfIk^fbMEG>Uw{i@ z#|-j-$7O`!LEm2L@CEK8VfKe?G3rF>4q{pLrAC;FMQf3+V$TPaZFO;dx9Pwr-UC%; z8WYdqT6d_uv>^B%C3-d5rvamA@nryAH4!nH#i_01k95ub33ekrhqAw+V0jw`V=HeHa^aA!Fs5WUuBN|38aL)s3{Y52oK_*yr z5>ilNd;Q$tV`Nm!2vE5^uDQTc6@r1!lr9DeNNPSGBQaX>WkNyu^!*UA%g-5MaA-X z2*rU@?*I)_t{u4BW5+$3TQ|~=iFLbsjVT3#6{<^vJm4{Zx?bNLf88u-T(s+$Z{4nY z%3Fs@;Ak+6LBC9@fTMi0X3|Jk#ECz?*n#_|o@ z6I063YL)ui3(*i709)KMgAK%B0paMxVHqOO9w#zsL?2}ilQT0j4v9daIu9?vm8Mqe z7a3trjU@c2v3k@-v7(P}6fE)W&$}D3zE&#pH!nFDw-`*`nmvzysT;B9h=n%{((rw7 z_N-a%KbWelY3Fww4SnmxLV_DQ$^8!1$AwN||3>vxQ(kao1~?u0d9{>VV1gC)!I{Ng zgg=VoH;dv{y@R>jx6;_vLj~o4JcERUFZCvyVz-qqC;cp(ga~ae%Dc+r)ot1vu?;i! z$((wCo-ED-wbu(X)FV97Z?l3g>um$G=tZ>~*$M`IC!|nEIth?c>evgrV!?-L_cbzo z0tBMxhYrgV^51C$1rwyPb0rGnlFd15X-tmVe|otz4prQrD34&t4aql$6hvX-8OKz!iV6uQlI zyUur%;`=#a&diLVXHu*HsJ&%My#O!+zYCfw>o8k3of$g$=Y7XU|o)=D&Xe}S;NP%)SBUeGEPMp`xyRkRBh`1)l$;^_dp%?ztvNZA^Lkma(3Tp z>UFiMgjTUC7u}&AegjeLwsj1gc8%;SRCHOu-jI)7Ta>;dCZ(xk9e=*@O6Ezp#kqvE29pnh`( zTP^H1u~8icR~dQ<%v0idG(wiJ5|BOaRPgReLohm_5oDaj_1=P}e|Skp_N>0CH^8#@ ztXm$o>SXQOFL&as+XJp;Rqv}t)^9;lz>E4)Yn&|Cqft%A2L5GQcjw@%$CKop?WaLqsO}r$aa8*ux9a8o$<(YDr9K6&o zkm*r<7}|mMBLtUq}pzwx9I+l2 z%>tLw`pGC{NQXG!bwUyunZc)^=t0;kzq&#orC>`en77P(5Y1C5q%CqM%6#&<8Fi%3 zr2EkE7h=>c<5Sd$=woqypdp>(Ky>YV=b>RddHi*`tT&q}TqjJ`aiu8=ef4V7EkJ!% zNeDxE)5v62nVHoc)ThOqX{XNGm^+YIT89v}0oo|X4AZ;spa~K3K1EbgLCFwYW7S+&OT>20HS0Zzr1MFgWQ)mvB6>$!)6;IL41 zK!kf>W~n(|Vz4Xu2@?>ch5A*8oJrbhI;Ir!$4kf-*Bvn3ukVd0RId z*24WwU5Grc>m(0$zn(`GVua#b6)oFkQWRspcF1yM+QBG$-@PvMx3)WMHpZ);Uxbr3 zEcmog?PU|)sge;ySAi;aF(r>~v#AU#PdHXeRQb7S3Z2)nFjypc=*CSH9~+w)z>dhl zSXr%?^tG$%c7NmuOgBg6$^;r4IAO^)z#F&urm`m*a_MMoeYHA0|M@COf!+kQiK$~=$LExT*8a3zq+-3} zm1TooeRGyZ?}Fa#MjoOWJzIYw@;oLlhCs&@P5?pHL|LmIxWhs#T%~1RxQ*t*ZZsDs zCBe=Zmv5|_w9N}{XSxV>ri%zZRaVIs$NI2ugb`7S*=Hg^Z{@A^ZbHg*R2sx?IC;kZ zYm_t<-C$54Cn`tI_vE2LP+4+d`2i*r>!%y#IIv`iv}wT>DT1AAd3})I8bA3di2_Uq zKu8yMRZJrWkSS>5+vVr0!3OfAU46GXsIBA+8TN=#k9if$;0Fm>dHpe{ZWc|JPOy@6 zIoxAGF*A3I2EVuq{JmTTZ8Ip}sr4HilWgV5;!ea(v-WA6EhFsnac{*Mn15u}suNT& z4->pTCX|?N?cV>9b3{60+EF`#;5{SSmndHE-6fBrY)VzPG-E|*`F1^u+d>J>D)Iqw3FYxqhJ0Jh9h$riI$m$xS1n299Vecvn9M zZ|0JJSKdAJlyq(ErJuRgCx!XJLcPnf`~Z0W4;yN?-NvQ6=75b|0|sX-bcY*Z_g){Y zP&84+#{@^6oxGc_k}g7&Nn%e>?KL7A>&yN{fFGX{Tnh$=ysk*Q(at_^KC8hR5GSPy z@DD`e^77SN`2bcKx)K&vyRz2%^J#MM}a^0BT)O}lTyx5ln_D>9ah3NyF=)zJ^aSq{Z$MuOiw;ut4iROV>ZtKc}E1Q{Sgc*MYP2j``D{AG!#mc6%bMeejJz)yo6=<=SG=5*EB_A}nTEY2w`K6^B7|f;a?%UNHNPe>B)fjy9Y%dw^AFFW&Bg&VzVF#ug+u!AuOv1iF9BW+8kIf`*f6#6(PyiAIGh2&aM;;X9oumdnT-3F|(O zrSqZ(e{X-YGay?Of7?8dEU=A2Qg?3qXNq(j-ljKR}|tEHKTe078fc8VUbKtxH23lzq(!pm|t*| zXnm?_sMj%M1)E%ae>7-|wkwBW9L%F;2ct_eFDYW9##QiTIfe6$gs5P(Q^xklJxz>B zpA9Z8b?;}vcn843=1FIUdQkeaA3iYUCct4*E@YMu54@U&v|>uKM0;XzS79Oq$%Z`j z(4sxXhPJNSPTtrx#&S+E7V0~JtTJd=7`k1R3H8a1alhAmYrJVk9h?})acLcr_YdNT z`awegY03%8VKUrf+%q5p&P(8uu45$3_eMYJ_nh?O-3$L{Dm_xh#-G(o#Yq#gFJ+Q1 zr4t`NV?XHqcYsO*^;++Z38Ov}`Zoz2m zhwEmS0^AABj9@g(#p%_2DyavSUhpCq#yEBk4T;=DhBksz)y`Gk%=M~#wE($n6M5a0e)o)s(w(fvoFSb~qlai#D z)!|)|J>y%^P-=oVHT}V~))j|KnO+)HMsNnzv`XO4coSVTn?@`lvHbZ?JiCqMGX)-- zPsLK;`og}9(-IWyAgWz$fCsc5y3I}P7v<;=Ldh3-@DjNWU6r zAgZ<+QFvV?_Fo+$&}(L*bnPMLBt0%z9v56VZcC}{0SEga<9N1XS-X?rSsSea8cHi% zEl^6ZMz>d@X^KNc?rcAR+cHev`oVZJwIU6R_sh>Yc~*xEBx;ki6I8jfj6v+|2L#eW#O zlur!qeJ;MV*qh-_@KM9r-@xCW`_Ab=aDnrM?R(0>ERi;apSZ3_Z9(lLyP#4+6Vd#+ z>L}_8ZGu+IoEE!J>z%9ms;_HBmLZqczOya_9G5;0R7WG`i9Ulcxg6sG6*f6yt8#Ma z&h+x7+x{`xSFT3kQHvRIMZhYi=jUPHS&}-O9PCx!oOjH}q!(dzPe&txXEiV)9v`D{ zK`qw-n#-n>W1=^7h45H?x|JVwX!%!)BdViVj?d7IiCEu zc*e1Bf|{ZSSw35(gL;|?LxdGu0Ji=rD-mfShyzQgEuWG{jC5C|sl@Ja?WA|iUO*6nkSJ4*ny$xM3rRio^e;hw|L`1<6byJ$3^GS41Qm`%wmG=Z}J zBBZ0nP#T1$@wB{n*q{wNN4ffIxoiF>>w0FU?m;?x2m8mx*W%l9qO3F8aNC?R2R&%7 z$^ir&710!QD6i42#Obl_eB=RHIxp=W{|q_P1~I9{!#ik&jODr%)(g8ePRzjaC21#u zlVy!gGyUcz%ewd@uAR$e$@aBa4Ygc1XvWjLl*?D$?VJh-f$Snu2|=MbMK8fGCig&C ztD%08xh2x%10sys48=DBt4V5t=E&3s>VvcUIm-S1T%wG2DC6@Ss&1S0Bb_9W4YU)w z8k{Y18|iCBS4oSJIRb!$;pLSS^_`=m&mDSXr;Zj!d3}0-Y4#gaw={J2DteO&-aUAZ z!JqUH$4rb7C|=rk)nOQ#str|>QF8k$-L&+&Qk5OT&QY-BnX@`I$_EWYYrbNZZ7Q2U z0w%c0VRwHs2e*Mk(e~Pi$2sHZ-w0d_%j&whx(4^mtpwnuHrl7qMy$2(Rf}I_0~KR5 zO%UHA1y8vp>V*f7)QLD?71|ECIG)s~n|^s{=K1Ss+rUFFK14mt3Kw%t?HO%ZVNF;Z z_#&nfFZe>>?2=3mXO8&aCU?u1ZPjw=+cmnuJkFy09*S5obLl<7tDDv9c+V1UY*(kR z#QDIP-#Ed7L(beob_Hag$WbgTAmpc?o-8;DKsm3pPguj2g*w*_hrU)>EL4t+s%S~Z z%Ws*8#6f~KGug(HbWlydS8`q>vzr_<%+INw6m!sYGscY+~$3*9{sz}(jPx6 z-yWcz!m@mHjP5@s6>l-CT4f!a!sQr4O%Vhbi6)?oB-?D}WDZq_(c!++x5DZ_n)iENSRePEtCdo!8)KT*M%5rq!X=iH*M)u4h_Z{bIe%G z7HM6e5@8xju@?se9D=P!o0>^v5f#8kh{a|pPOP@-O%0JrCY9gXH>x0ZQI{r3-%k8A z2Qva}@$HL%d)YoU3It7jUnHi(yr_%5`&CT|TU80=mS&Z6@2&P(e`*XRS;nj=rEKBwzaKj2Cuza|7*1v z{-}9GXSjZeNHK0Dw0Qg%A+~t@S3(TRcznfyCq0GlCYBO}y`b9G03EBgjX0rJCp+e1 zqT@#$!2v%cUf8@hY6wQ0Wx|LoNJZq}O@b{`U#YmLXP_Ms8jnlm!{eyt#&e;$?Jo|^ zP#@kY43sn;Kp{Q=F2TcJaR#$$>{aC8n&k>sLM&V-8AmBW73+We{or9W&CC=ukOd zD?0^G$M-`77rC52b-y++yL_;!YZL{mZZ-k<<@khOPiPcIfwS4V9%}uRuya84c&Wo( z_B`fd5>v7q(jCZ?8V4-gZ4_atokc32{UTi)nI!;-2rdY{pc8N6O_;Wx>^4vOzPbyk zrvb^*EdK;?z$e4dEgS3-wuuyvJ~BL-M@lrx%W1`hmE`P19@|7^@U(J$7;Vk31`zD2 za^wX=#yvWA;uU`s-Hj<7`U!iZsZyV!8~JCdxE}djfS`c`Emg$i_{4x{AIXh>2c8p& znAJ*@u`uIK`SB{@5usteg*6>W85gF$Ch=DtU%temJ!x#A8;Y(hIIGqxGtJlW2 zv?#RgVUtH+rS4S>R_o?ny;AD)@tS5Jj8`ysLhW01<+WG68#dkSYV2&~^)Z8IC$u^- zBfRblLz1F){Yiz_Bjwfg*|A)i81DP`VxBv!2KguJY8aZ;0pe^{gculUr3OSV8E({N z4fB27cZ<4hEPL!d(N)FzD<*MQLBQHLBP0;R8k4Lt{NQX_amO+7ftsvdFINPTRuH7H z%bZY>Up_FzTr%+`91fr2A@M@toKJ*4&v71b|JkN_yiF( z$k&rD-_*CynhFa3rqP^t`)VOeKzfoBIvA2|oLiLJ3VA_dE(ZRa$I{Vk2k6rhm&i1i z0{(tsmJAE(pIx|aTs(TyHiXJF!=#F*9T4SG4923t0}@uYDi?RBI%^oAlTMgpT;e%? z@O|9^I@^Hm$v$^oH7$_r+sPdgg^-()KfArqTsofHgd05G7fnyWqTv`%nA^v13-(U? zaKLfVH}4@v1eIia1?(Wx>VAn|;@ub73@|EauOa*xvvuk$0j8sPmH^~S;5f7^dzH_Z zNQ!BB0t-?}%XNuuquBuoUs8csC!OtEDiHp-LogFFrm$i^3G;a6t}d$dD~NKhjMsQVI=aiU|WEPNVzmijGV%wSCakx=lKtS#xQTpFkn>6zRStQST_%>fC)hDb?qzC)$ufi=8Df<5yo*T(7>?!ja@D(3u|xCH z?c7nihfZ0rDn&QctINYeUw*kJ0Lf_@j}_B6RflvZ6^>Mg7_oRiSjA&eil^o)p2k&- z5=!o38-SRX>Yv%AbhiV{`%rdziOczqe_+!u>Shqe%f4>f(kuzRCr$Zwp%j{Y5Gljl zu7#>y$^2Q}x2ZOo^5F!n3RI<39rnw;f21hV+OGYTF%?3CITRqXcCd&-(?%>BYOT6z zgjx*|-{I+<-Ytg@fBVKa<)Oi)oeP)T$PA|k>J9s5f^X0DY@OYl&F@592D9W6%nm?Q z*>}kSyS+lu>9V)ewyme4^TW@BWjh;nl%Fn8C=*f(%h+|(-@_2L1V;TXW?vCwJWJo50Vjt%HuX{Y&aiXbzJ z_Z?+{h)~ElbQSqHq4!a!i~=e>0*J5WnXT%4Qc$aub+uoFkc!2Y%i_v8>ZYxnM>c8m#fGuIc2ogh6A~dj3{q3}8aS%&9p=2t8I-vE^%N;o# zx$#(UNi^fKb6JgS$!xEby0zs@DecS?Hq2*^_FRy(X0{%>XT7Fgegrbvk86XXn%%T7`YLzKZ_Nk0O60#G<#Ki+}8pG?d zPvv|z)W~K{v3`*FTT1dVGo6}cWEq*sa!NWn#8bQowbOgZTYACkpC?OJ8f3z#I5hUs z8Gi!PXDjssYqDE_QhWE{j5rI(%kbS>2|_=<107FNtB*Pbg6Fp1P^HneS0oa1kI@6J zzs&GKj632}ay>*49YU)R^T!f#*SXxC%0o|DOVC`%)HwshsVbZNW~Gcyg!D8;Q0}vm zQ8S-(fNRPdQb88RaU>2*Vg*Oou&VdofvaZuJhzoyAyzCpY}JqUfOGVc<-R-BVVfZ| z2INp2k=NB`E%o5>Jzl~xv@>g8wVN6$gERx^Q+Tud9ageT47a%ddX~VbHq`r7*;wm}eL2&n_v>9EM?V(^b2JCgxPB-0GHFbVB%sOj z+r$Y<1#*+zVG;}%mNN6(Yj7Jhl&NfANDXJTB8=82-Lrk^k*&LHB?rbHii``}Cic>e zgYOG}x1WzZmml$3n<@-DaW3lo*J{}<8ozdtbNuHOC1s=(gzJLEl!`{~e9z6Xca4fz zj=jR+8`{cK0f#xM40>2K+SKjU{(4})Zzf4kC@1)=A*%!MZEU;M><>xWXMDn5sQ~yy$uf#qh4>>ZFM1$*VrW^j!qi zCq#1#yzs9Z*0Iiu3K$284KabuMg3SGbMDEDE}#LRzyfiWpiX!c$+OA#8%=t2-i%wD z^QKS0^Q4DZUN`-FF&7R?aoj1|R*V5VIwU^YPvOdINe3&_w;CC@*!{ zi&4NPt$JaqWk}zupMSu?hWzAw9RT%4VXXXZS-(9rH`N9p;9Bd^Pxhbx5L(Gf{k^OD zN}4_j2L8=A&zj|)7EagL;0I?v{p7y_EjQW9IHQ>#Kl%>+(GchE`fekO*~))?o_b7p zZ(sk}J*xP(_psufivPjTk!QiyW+wn-c+=kF+v~d5iPD^lJasGjAE>gB=%nYbCNoEz z5Zp5odRDkbqR&G@rkYmEHOH#(OR$Hskl@LESVGc<`E{p z+3AjP`aWi~vo`BY%DV~akq#HW(@Bc1*sUthHK9gjLRev{eT5||O$5gIx}H}pfqp(X zi~mN4#Q4kBRqI7$h_C=8>YxpYdvw%OB?-hJ!?Q4#tWXAdiBbuJeSgZCLQ)9B6J!MC zxjq%jbIqVU53Lx*<_X1#~f*p7<`Y6kR`KFN*RC^>MSUw~`P|Lgm1 zoaQoFTTJv0_DXL^FtdgPXR026@wRdQ5`)vqmyso`zfolcqmGQ@d(QkuiHS4%H&`Si z#o(WH!qda_IeP)2UU;Ko{}via7WtSbJ8>3T>3YK!J*eSb9u^uS8YW+@cPRBrQEgWT zF`|Iq>ohdpM0Ro!2-#P4dHv|C6OY4_n;b)rnCx>5=bmuXhgP%mxlAsr#iPRl?;qC# zMQhn56wCixqA%Ke!qc8q4@CkY?x zL5~ZKxYKvdrao1qd=T2)25?A{@wEg1;6cH}B=e;!qh+j<+>%NY1s6fBB^k=tz}H$K zTBEiewRFT&N`}m^J)kYbk9rq5Y{j%NpU;F^43spAK_$(+;EHLiKa(Dsdw1f(wt7?l z>BnYa|9;wByc;2I6nu3m`5jKft_b zS=cQ)rG)I@Xo71AQyzY{#=J~}24BgrFMFNfTQ=<=7X5_7JS~Df-_`DtP9IjAl?o}v zYXOfCRn+P#zL4H%u)PTPp<-Vn$yqM8=85nEXfoFwDxYNq|75`Ph%6S@ z)0_yOj*(_~jjHy_CPqvEpt)921RC(9SqAnjB@{JaXK919+B_&%L-bl7xCI2ndRr4+ zFH-~D!3~PC*ltp!jgm-7wRD=JIsFW#QC|45TL#yDI&}83xuEA!datrqoXM!Rt^YQ4 z$$k1Qn*nJChtZLEfWdV)NWD1GK&?NmukM(bLz320<41mI*HHC+CO(nvcf<)zVH&D` z`yiDtt#_sf(iApg+_2!Oh=;>&*Y*3-s6J$4xv;0=SbpcGtK_*K8CdcZt`6^n-X@e- zz}Rr3L7R^o(PS&kCVZ-~nu1f*#B4U=v+fbW-F;x1W4%PM&A3X{X$d4~sVbH_LX(4e z)gUhGZL^x{&Syn|xxfn3aT$%k5Q?wy&jA0RQ-TMqcP3uPg=>C+T6;96x!qAHpL38X z4h%h{IsO%1RADN|gCo&=f>+%wt!t89aMDSEw=d)resL4C^9Y5r+LgVdZneG(<-mL1 zcUwaO^IWglApqqD7iLAyk?S!sEa~}342;F=@)s@rh0Jn{aoHReZx5YvugJ^Zg@|@K z)tfv>sWMKiNi@))l8PA~54nN+fm3M-EDz6ZE?UoBGl0w>+f^$Uy#5qlD|kR2YLKp% zSlm5!-9aRoWLczSP~|N--H^L@`V{|yq0O4Piag^nB-3Ii|83ofcPkDf;4(7vJ!7;3_Byg4N_fDxR75Rg8f(yC$O4i4I&K#i4zmVZ1))3nVZdL~Wt&088eY50q?2wkwPD>Ns8-fNv838pt{2c{T2 zhcTT?bK&F#@KKF2-inPPat^&F{JPG}PulqPVYz`N(c>n3j3q36<)2d6V*22oKJr-#9lSsQVg%%!{mprR> zo2sqZWXV$zGxFUa%YvW{H0ZqSyIaCBma9qP_5rb&az+S42WXLEQx^ge7oC`bm`BK& zi<(E(!?n&fI(PO`iD+Eu7}N7!ML5uieLFN5`v}A}$1KH;{+oKB0Ccn!srRDeUVtV4 zQAT*w<)40{l|nqExvn!i6C9s8Lge%@(K(G${}F|Z%q?`p5j;C7z$)IArf@R*pGTIu zMDcp-nWlq3Dkzzh>Bl6oVNaEhY|j%aaDyy)Dy%R(%z+Of0J`LW$^gis2$&hqfkmfq z+0{qZ65m$3ycd&YomWd-)=sD|h4r}3(m>$O8>50WX8+}$=6gsl@vme&6RD3*JMf?C zdy`5MT-7h!ovHagbkr*9Lw8|A=Y5;!-opVz?8#I5waTOc^F(*2kA#%gpRe|Z^2H$R z7M@oB%?P)9NHVsoPo*Mv^ROFxbC_h_B(7u{thwsbcCM( zLJ#P>snA?fWB8#=XJKa8qWHCG4b$2W57i{gXccXJMyteF5CRF5MC;qR}Dg!x%CqwV43}Q>dVE4^FC~R;VfGv`ogtlt+O}W_;At+Yo^D5^tqWthu z`v!de+G52911-<376p`CQbR%UY(;^P@Ncm7P1v4`X!&llMpQ8-3pMg%+n90S%qt_M z_g`D!>;gO)vVOe*DUkYS#^)~W@iARQiovDUobbV`IAynP=3Wd&h!4i7&XU4-IBZ9G zFm==@kNFZaW=?8&1ZCz{#i&4wrw@g8#S~ShjW*3D#q>xvj~AH7vbkvV2PPVdJOG}w zpl5%0_FCx8uR%fHUrUY&UAzJ#&&Be53nRW=Dzc$LZd=vEb%2ScPVZCuYVp(U9|Ly0;V|P6B z{As}f%>ad-ijL9IeLhRXV>gpf)L5;S%uLef7bu9F_;HR-W5;4b$9QB(UuSF}czvuGN;Le6;wV z$7Oj^Tu#t4_-}D%+IdSZY3qzsbdMz{it8^fWs#VyD(_oWP=+b+KHfo)uY=(sNzeIn zAU*q~>)#AtKIxa&!oULWb{$YGeu48ofl0##PAv5EJ{G#Qh@!jLTo-1>v)u1)K&>oh z8@2p|jA{}k=GVSIzc>z966mTD1zt6$zNo^_;?R&(v>#7md9aU=X?~EOkxMdGamQK+ z++C()cx0*v>3Y}dNRy9_)x)%{Q6C`DYj@qao#1%5lP5F>>ICWbrv$e+c|5o!H+%he zc~UEL5}yYysID!w zRV>pX0|(VHw8Op>O+UqUNt{t0)36I1$5IeIgs1+EyLze=MQ==Kljiah0|Y9$EBfnL z9-|lMqwv*qF-RHC3LcyDs0f-EDiyvw)MFb0COw7wQAl z<=zw++d zbi&8Jb7X$1H!EK(>|mZ4?xT{JYg=C_PBB&5YJXBNYg|5m{=+$=;K2_4Y%%zASZZ`r zeS~4r9>Cvx1zp}N0ES-H!`nln$bjK-N7#d-f@DyHin8|VEFWRtS9kGcVVr#O-bcr} z4Y`_FbG?Ny?$mlRy^>asxV@frB+}yA1m5l_s%t+~GzC%bSJ9>rdg}<${phHrLIReR zn2g<$ip{N`NjOo0cLH>EONb`P~K6vu^pWl<$5Y; z@>2qDa(qo=A8X=M>-j2iMo}3<+7{}+Y?Ux`nl3wW;H&yKCqAbG$?SpsZ?QxwG26^n{1Oqy7;t*+`o9XKjE!bvRH^ax2of7m9M`@|1TMCMran$?oe zlp)NPM9D?>PEnjy3Waf$qUf^R6`$3ba^@A`H2YDSOJdWk<$AiQnKk%>5voD-y}7qE z^%c2p&33FiHUY))&h6B9tAb`c8J?joa zkX}eH*VfHwV>n|B8A^aK=)Z>)!gITL4+9iqb!tF32&gTD3jNQVLhle~*eF+qth(-= zQrqeP-n`cg-JpjelANntwX0es07)_$oa~7!4Exh-?C40*SEaix!V1J}=N2Fi3BtM{ zrB;#qCMdA%&nak!LE_piu2Zk^!C~0R=0F>XICCI47BQ`5N&-$@@6qlVqGekXL)_bzyJWOhj?vIvt*`s!|Axx7eD^=T=+`0Q#o60`%PvZPN(=Oq&) zro##CL4w*-@Zh#v0a2q(nfHKkksPwPS3}DqDfAp3F3c_C`F*3DzER@I2%|5{-fLkP zl#fH}8Cb1)DfGtf=pB>quOOLaL9fQO53IRlA!r0vG8gJ!RRhuAzkEJC{_0;IoasLw z|BF2`?T;G2tvgrRpS@kk!rO}MHEi(lk01Ydlq*yo!VaO2o*FGW^yHJ5Tk-fWM%)cx zULF^ZzY-5G{{R8#;$!&3KZgBA4$X~T124+-@4v@_6f4DIp!2_~|L3zkDHFoPj3qYz zGh`~@Gnl|%g-MYxsn++1&Ppa5JvjTt-8w0?iSlG6It8DA->n+I-?fGaSN&d7Iw;O{ zQ(D$;vs@};)O6P3%r-P4UG9fo&ST$od!U;TDudmLrZ5-rA_|_xXjQK_4yj3JQQXW5 zLd<9~5sCU>UdLXOd`O^FDR+T{?(cX0JjW0ZR)^UC`>c?U{XM>nI zoBB>@bS6bcu`LH)ePDnA9DN8m^N+LooH{r_`zm-qC=|IY5p z$nFyBe^vD>s7SS<)~HrOMn6U0s9Nk1VZL+Ho^{n$7@xLF$nyTNTY?2PCuckmSg6Et zCsM<6E3-iJd1Y*yBE~8+)KDQ^G6Fl!GGeUBBJeug<^B?rGCK_LUtifjKTq{%jXMqL z!@(~4FVVZPuXPY@_2|##uK6oaEcW~IF}r7HMk>-W?LIwRLpiZcz2-}%WT_xj0q`Y; z=YQa`6|=7@JrQztMu-PxEUt$jkRUw+5e5qST%DW2U#r_qB3MehCIT_~Ye z9tY30>qEvO=4u*~#)wBIVTel0whM9QQlwZ%EexRBx>rd>6ULwTSt+pQxc@f0KnxqMiOlpCHh8>AI)XKXqQ>sD_z-vUQk|DJ5Tw4 zR^QYcD0cX)TOPJ%ZG0(iRGc1$ArP#A-C?g(QDH(a`+85&Q0%KSXl89hb;Kxj6fiXhYGwQd>$R||O!^yctucij$Rw;8%k zWA@x*UC6vx#*O@Icj#fl0TW2#JIygsLea6Wp--HZiaOR3L~z~g;(#Yt1Z@%vyNRU7 zy2`;k;reTFklFIOyZzmeve9$}naoH=SKNQ{lF)qXH;pV$v9&57rYcRi<_w?-d?~&Z zCYZ54o*jdHd;mRn;QtNnVPJL z$ka6;^uI6=26dhwtk%S8Ra8O|7OUF8@j%1+6N4~FLg6K7Nt-Ej@pyTuI$lDi(YUp& zO*GU+=-i29g_;0OIN$7qU-#Ws`W;bjQt$u-Ejr?q_5~{JXk@q^hSZ?=uBz?U;8wM_ zDrM?vml(kIP)jiQytd|Jb@c-LWw+JljWcnpvEWaM~9&6=IYw)5>p)8xM9Sd?GZIh$0`Rb z4LNw_;jmD^C!u|G>r&z&C;^K`HAon6A|CzGa$9Rn*8$9R5F$u{7}J)}*akN^nFA9W zGddm-C_=-JGh@|QH@E&Nt-TZcx($9rk}kA|s@^tzEl*$mBtZ2=VM*-|ZCVSTRjY-n z;jWLQ(#>F`4UFh9TJm84FIhMbZIqt0WcbdTxchErQ*s&<+l=%|!f@#ZafIjyT0RvUH!4(hYm4r3Stk9P?j{Vq zkk@Ia_a$ihP_za7q|i_zy>Oz5kyaQ2)}Vs6(;c2y<4%}$)kZ666G%53>#3CcPW+<#PwK2a#9@|kF<;lSWX4w z5jhXTkc2=~Q*m^tsU9K~d@~Q1OHeWfT?0^;Y;KWhPT~S7bTsFBB=N0&v%I<^`-F*&}~*+G)rS915V zU!3fTHls-CR5o9i?EySBK_9_f@XAS^tN8(NJX_@^NWwNAYQ9 zbU+cZn3U%f6jFqvhhvba;K;!$4y5mJ<$Ck99M@W{93KZH05wN?CXdZ z&iizm<@Vk)cWoaz9_*Z~-CM}2)i3+Mz7qQ`s0g#d@<@^xf|X?qE-1)H%#nx#`c!0I zw7ZnYnpH#p9}*X_5^`H*;hf>)#ZlgROZuQMnZ`Z&23){Z9XNzJI4PT;D!fHOp6`fw&Y&_?9}TemhsPxv;&6w=>#FVX|IvH$m{%r7`P* z)t<#}eaaqt154lFYF=|Pk?rj{kOOiDZ7nw93xM0g>dwxY=W@c+-oQWxaS3`^-YBzR z?F`3LFv@u{iyTThQzJ_lK2W*q_Yg7*j|g^+41&?23C2&&rsOcL+HqR~eVdaOs!dx6HPkqjF;_aY=l7l&r35APJ> z#9F{Cw>#Se0cCi^$cWXfWGMqF3X>in6JS!9RKc*8%#%JHgXkC00y4NM z0{h-TYOb?AjE_Q?KA~e|q8l>`h4y%DL6 zP6*I_ab`-iUu~)ev{i2liESTTBeZ>3paGN{l?V%$uk{^V6^DUR^6HgXb>CHoVQ8v$ zhAZ+)H!Z!+6bK>g9-JF+U2g1V2zIgIfw=8&utq%RU7YVsWJCvEMKy?JH&kkS82{F8 z+mRosS117eu@5^a*tHbHgM4F!49zmQU2P3)Sbk?-@t9Md{dB<>V>>Zl%y#2q6Nd$h zIylN_!^ovr1Dw!Yy^FoRaC`a!TfRHXN?Z=R%09r@W<1gA<$Eaz>zXO!EqC?bPyTyk zSj>@mzsc}`urC)4B3X%gx2a>-Ygo{_E$9Pmo$h|r#NA?z98J<40J(i`ju^+$G>S9> z{S3N@hM-kcBnBy5cGoo|2rMgM$Qh5&(S#M8RNwMK)FC*P@A=!C@?@I_3U;{Lff;%==8d;)qTt-^Z?1sJ*M5lb=xR=f~qJ zI7}H&^BM8``fqb&Ue=?f9OIR#JY`q@kA^8%bfrQzzBPNduK4yHW6-q_M7b|8NYg8n<*DF&_>BB++bGAV3jhw^|DS_qVdHnN?YZ0?5{AH{OWZ zwVEU{3qW1+^5m1Z|20w!60iDSq?Kqm&<~JI+-qx*meU&>Qt{z3i#ae!RXw?i)Iha1 zBNf@ENUknRNtxu*z)%ri-n2?ctew$V8adRyq;nPB?!WO##+``N1s)0jZ4f-|&m362K7B)Iu{@E|M3#N>%4%@3>;HPAe zg-@QZ4*qbck!}x(`aImg%QtdJ7TekpHWH;#9V8-UO7{|s-s4S3$0JmXYU~50xxYQH zh;O;<8TD{x&8C?NEPN|XdqobG>WKfDpc%)UIBHMj#MTl62;yrg(!qpDBp!pX{qIAZ z;;Bk8eCcd0MgyQJ#!(n&D|Z(%jsdb>VByt}nY-Tgi@IwLEY9{laA$RHhno($RbflZ zS{zgBgKzEo!|FLS*s!k_!diS6fj>ziA~E;0^T;N4O;w9tYp($vl| z-L#nxN6O%W%1uUuHYb=bjQ3YU`mJ&0ZSY8@9F2hp?8dpXQhBCgWyHzvJ!Gs{HgDj;eD&0t1|`NqtyVOrq!XId!R={K3fU0jZ!NSh7)U0&?pPB zm~y#KJjKa?OUQLX4U1Ihg$_<`CZEK*hee}G@C_eidVl3LG??PqqOcP%a%Z#~%Zx?2 z-;IZ;cqKRd|!qbHjrUNe+K=c(JE%H2u%2!PaL&6?f9&Fud&};+h>B z`&*XHohi;yrsK0l_zmvInncE@=*`TKa?VBMTU0(W~s29Gs z*on~oW6o~7eqTUhM>!eVw;v74T`HI21(oasf!ob#EpStI_jCFDDPUJPm?e}Z+CI<9 zM0)l@9ANfejy_O-1h&?3#un%Wa=uC%j{Z2{wPj^uFRBi7U3)kCv7P?%ASE+h%mdeZk3`rI*UqYD{TL8M6!6c=nfje*T=uss^GkHF3Cg+;7z^E74DT=^zbPwm=0W0uNi z)uw6hf4-J`@Q@fof(D9}EJH6?c7e)&X;tm9MPb49E`RP9)kbQ;fIYTE82A7{G>;6H z7hA-LVZYt&EUt7)#0_0X(ox$(+b*glB6-EO{_}C$-PpSp)$;ST=V?$Cp_lR8SnOAS zdtNU3)xB&Qw-@Hik);Cda`TBN!ava!fKL2SoaN>nqnU4hp6&8ESI-lLa^u$76Mr_# zeS2T3nua|fx#Tv^)8Z1(WRe_!+M)aai-OI!NREy#JXJ#iwvqgu3(-b#Nr;SA;!kV)F z%QfO8M-ycsIbtO-gd@RHLM0g2)klo*;Kum@03J}nw~|p4)}~G4AGe3$CK{s^2Z{Vs zwnB`OZpY6h5S|%qm1h?ELU&4xl5G=cehghCgywBB>cOGhu?No2P+%$scEVRjormT( z@bX0!eE+VYySBz;lrzE}2;DWZ5HT?XEKUe0EaeKF7)iJzkR9BdyiRu>BHQT=6hPu^EaAi+jiE4TPY`stp1ex249m5{pf z%}|kDm04fv8B3(Jlz@&O1Z?5~kUgY{@XZ$Y!%cl#?hW&$e*bxB-0=E>w5Vo~xVW8| zmlztoZ@?@X4siYA07F2$za$B#Cy-hOfr~W0fhg|U&q!2|GP^xku0Bv`Gxo`Jy-Br} z!?tY@k=x0E5@;h|sLs_UKV4jD7F_?yhcH`lFB6=Y6Pq{Q!Qm z-5AqTYJ_Vb#-zr3~yI$>WA|8BPD67`+)hmv*-z@r|2yHG(B6^b_ASy6Y+U8my&_|$O zy?hKdPHsq{mU1+wiYYjQ4JA;O)&2|VpZpTcJEo)B-;4l#Xu)=iyQh(4YFcoC%SU7; zcF~JNOjwUMNw**$jg*ibMXY>?VuCImxRVFhkGVfHKutA9&~GH)}16XD);b%)5Bs}1#xt&*dJZbr6bw@v8;mU{l~TYVb>GC z>~ns-C#~UU`m4n1JQd6n`jwWgETz_s5}S8*Faf62;wMEGxuyBG!r}PFaIB~THHIT? zk3YhAQP@NIp~E~O_YZZL#mz>G$Y!|S9AS^AP)`(w$%K?<=4Wqot|lzI^fERpu?7_r zvG*j7ZC&XLE+Xu19u{lw_L(san47S5>pCQp96V;6fqx zhh}|K5Bpywsr46!0fK(|5`Elk+iKr;5b^8V#wW<0YH{C*(~`;L*@6--Ffb*tN92b< zaO;ZD=mD^DDCoiqMON{>DZ!$wX0BPvXJNHF-|O|5I`??D*DzanQ@hY#4w2eTjiY*0 zR&QJEPGiLCQQKTfh$ZIeqR}BcE!xyvim7brxZ_owH>%3Umm(B#a{S<%7;Ohpu3KF* zm!gkun}vG4(8p^EU?|JcFptU#KLJ(qSZAD-h;u|NMU|6nb`?!wBwJ)Wm?@W5lQirA#SQMeEV&j3$!l)0 zWULMePhK4~mMtPRSS^<0u>w|}Pe_b1&IJ%>nwf)bu<9XG^Cx@zs~)f=K_7hp01(bR&sX8_CeE%VN4G zf6S14DW(tz=QSBk`lPMfYj`jFq27zV^HhO(;qBG08zHye8*}E{WxBuCasgJAe;GW? zrQcl((%PyC@3MByL9bl99`R7*A{a%|##;Qa8WfDn*HIX%dgY+L;#62_($n5s_(h)pA(>2N9PBo@-_v?R-J$vFRlIISB9Hboi2ueXOBzUpaUL41Z!#+PZx~jn^m9xYY ze2_YQRe1bM-A>FzISW6~P`E~O&RF2}pvXruGsgAA8y%u)l0dtwO)A-UXSTJn=FsI6 z9%e1VdebIiYJ9z_T{cmlORkUlt$5Y)#G%)Mzvo?TwY=Lfu{%v9IU#)Ki7{arEy!xq ztobJ~uY7U5T_x>6w1;cehOG4mAm1NUoO*;4_6Ge_2Mz0R_ae544>$C6Ws=h#*#{NhtaIY~gpaw}dIHRq{4oL@c7osKkrCE4dw;Bt+r z$b{9Rone^-^=y=EEp{rgZ)z$<;atjKYDZq*8#>-{GXq& zqC~xx-k4nHQ9Y+^UX7zNjl?3iHWIDch9AO+f)69NZGJ9)E2TMbr~Vg{TMLMUeZFK~ zW=J=!ql4wGoEIii32Ux_Shdd7rfjak{ur}25P^kmi;hLQ)F7Temv)x;h?Mu2kIuwr zmZ=B+{ms|zS8`v2%TIQpVjNW$UB>u2@}M^MHql(V3}#4JfF*vUl3HTS^cBlb5uziub$p$UviUnUP`7sb9e>KP-Ar}+~tL>Pyym6y^N$0 z`}6hlYWI2w(Kvh4307h~Q@pA^ih71gW>n0qWI?7XZ=tQ*ej%)W{34L?f7o(A1Pvalnt4sjU&S~sl@ zGoZOS&aN#nb;6_BtwAif`i1DD9JxAk za_y){-Fo@wKgF&%0gvaz$S@0?)PXP)?tmxcQkYRU;&BAQ*xc+7a5#3(iE{Z-pJ?=YOc*ke!{B zoJ^==G3YZY&aYw7K#=7sVzD3=ut#T@5^O#Zm{pcELwr&&1w0Iy!bUK)+X`4_S2fU4 zZ%6vg&k18h^%I*d=xkQN2?H15th6S*(*;>$0<}Di;k*sFxIKCRVpjMtSZ}PDfXLcd5>{{ zIcP8DIu`C#Eo7XqE)gW-SQ?yAqz_;rtc_mhk&_VQ^Rf$;B)_-Y0HoJd?1LK%w8tGK zj!BLxt|=IqTogv1cKqd}?1y?Ey8B)XqJFzAw@o>x{}8>j;3?xq8@-~2s&g8P)*c`yDJrj#(-YzG3`et2%XdL(xdW2J7$&%|kc+=CyOwRF1W9L(_kuHdQe=v!#g_O56 z_%!wx;dvjOeP11hK{&z^Hk8<@?J~ZCy$4)OVIk;iRsDl%b`N?Ijl<}G5C)iFcXc`g z4b3i|Nc&y2^T$aRT`7RP;a$u{&($-336s3htrj!U=?~o`rTh*OS*Ozc;q1<9# zMdRSqEQG` z(#Vj3E06_g)R^!n9BR;&^<~@J^!=}OBMfBmI)-7A?{?>|ldTMW!D0};XuEj>7J*py zreFJy{gMyoFqT6LVQJISRPNtSthMkN!TM2jhlOzP7stlIRBJx3YTqg2J4g_gKMeNlT5?;_TbGO$GU%XxcE-k^}3;qO1l52MJ% z)DKmGLqp=qc#4P{je(EkzE3ap=a(7=N@o4#FR5gs*hF0SZvT@=B9&Rwl{EKJd5Xrd zW~LL3PVx)(8!o%57eM!$40w$CmdpOZf#g(00!j|_mtizZ{VU);6E@N0uqxiPkh0_} ziISdyQ8pe@9qwU+Udm9j3x}(FdWat2F=fU4PT;Tw>>4JOjT7 zG!OePt3vOp-F3Y(=C;gMuZ0bCf`mGV8ad;X`9Vk}=aTPGjadgBH9I)M$&n*Z-1uG` z_rMd^b@duIQ_I;KY`nxDSE5q)^V$`OUMp%u>m#4JH zn7?w6XAo7dcVP8bofr7c*mT&XACVVqJ3tMw*;LCz3rw^&;@d1?ljZ6)@`~r&)tY|7 z(^2RGI`=yr!UJzvoCSBa+(%6mY6=F47ZHUabv5wQTPiY!x^dd=^URG@3%mu6b5SM$ z6iH(YVk*1$Xh^eUPNyH_J4zFp1ko|25vgc6W^V}Jy~kI@UXC^w z1fi=spc|AGuD_{@BXiI{4LJIEa$ZZ*7nfBS9ttc?4d9QllSr&wd*VmVpIj>A;^Nz! z(?@9Ztbwfa#&s%&4)TUgEdlkMY&k_`bCGgu9&0+jySjS)kv7DL46QhQW$LP4PVy7% z?->ta33Svvavu>@e|Cns-Vl)7oYFEW!(}p)>1&#-b|)@AeQmA=Co}t<1a9z)?dA8b zg6QS<-+WEob6H9BZ~C*VdjI5JPx}Eb{C9R&FyJw)Ho5v>d1dAtt99ugvOl1kSdFw{?2=GB+9PXNEIL~Ax6jG9DK11s{5H92>n?jdD zsj51)A)-;HL$fxAf+3cCgPTZ22fhni73-1v%x%LSN<+T3O%75J_U9(DGQUGq0PME9 z{r*spQV<7{otvX2#oh%4DJjN@LA=ZVavD)r+e``H~iLkPbyc#$!q8emY%jm%ALb)JRbilm5tUf06qQY-n zqVja6re$@0QEr>_$6CWI2B3(r!cYKhWiNI_u~v$;+3gK7R?Ok0#kFb=;j3ruAqBQ3 z(4+NN0Mg6W;j)@ii-u*?c9;LD?`DPp91`A%ld-do^ZXMLonOV9+~1rkq7zChOihEv za4a;#x7sfm<{o(!6oZjunvL=~r&RtVjap2rMTRv&Fq)#Tc=F6E5o4TGBq9;evSsnc zBzELQQ{(b^@vNXMo+?g-A7!03O|wsgDpd>bmqjLP6+VgmfT3| zI0hyJz_{+7!S|8pxa{AC%??%G*4T|nhX?-VXlv+d-|2?xV|k77>gd1959D< z60+(aVTcFdw}`17K?DVGphj#j@+l80%*9fq=sO=RqR*1%o+PfIf>O@fc>mAdBpI`% z@uUIo_&UH~yz#Sf(7>?TZV!XU5}8-%9=qI{PHzr9-4i_L$&gNqRsHQSh;PNGHZ8z< zTHF;W>*3uyG4DrDo8UU3 z0bOa_#=UGG?!(8TJp|%}5Wm!e1uVONPeya?>Y-U3>RdJmt%-c+eKwBbf~R2HDSVRk zEXXCr#kov4h|Nh+q}I+CKN8+@*=vsO`%5Jlk`RHO1i%HrK(NSnI8!z^^AZT-5-;7Z zzr$2X+69hcNt|bmuB7fWiY*_88!@Uou>*Ryqwo58wbk_uCr-C00}VjHSBU96x~xu|qI(0sjoYlMM@i4&JzH zy1xUvgoCCLw>Ip}iz{5i2(nVeaU_h9eQ<)I{?E~vDY=#&R(eY$EyBe*RvGU7akXNB zoWiRXgVC87Ce8)1bXsIx>Ri@IaML}`s z-DdM+BznC?R5NL=I7NoryN8;vk*GMNPp_Pvk-Mt*CK-o6!-s`c=!YA5+G6b#_3f?O zITGZH9Mu%MxWEjI?xb`kINmenZBeYOV4HG#{oKwWRxr~jL=zn94io?Dm|PVr%7$Bn zrP$PBBdif8g98LcxUkcN-(-*@RNjpG0u@^z07*#5ok6#az^@1eumy^|jHngMn4Okq zpDSAxZ-Ngt(aYAyKXg^R#cJXFaJ)udpN5s%yZ|jV7;|{e)L(g0blv@f--LmGQ8_CE}b$Hu| zjZu8|X@(*h`68<9RNOROzoS;FDp1R2f2Bf@C2Fh8oLOpMrl=Lo(OGNCUbUhb&&XoTG?4??o@pB9u2mTuTALQAm5~ruOBkxPpt%FuQyfmh9Ccn>?zuP(iczA7407D?J-20m1BmNZ zn)IHBP|V_WXXJ)cjw5$()@EIDO{DE-n?*kUU;AQ?{!NilIh!TYNg63LQAfX}lrg|p zzUw=oZ0*Yz?yBujEnlCi2ZHk3gMHUp z!MKmwcdKT(t?JusIb& z|AtW5q)GW@3z|hU!QdxXu;#uAa=KpFrRvyf0CSNAl%y)i78)!a>w^sYa_iq|g4zZB z9NngUdGG3-0ml)>yU}1wz_~|+6#=!LLXjvG0k)-aV?fqs&1pGEugka)m&eTJ;3t6&+XNv|MRIQFS>e6?8l{gr-mVI zc4JlJoUb2xgf)fbfQWZ-3$kPj{v)gsZO9JDdgq5x!=CdcNi zA#;QrY=L0p$HPgos|T1PAa=kzQSO$9(>rmQW-~I|pE=NEl9rg!ZgbIx;pxd7xAvnF z9m~v+kWn2BYqGVRL+bcfLtnG0mb;!k*Nd;dls{5QzeJW!pAt|BNd^M`_p#tdpB@NeYuyP0PBq@D{V*o`y3mLnGef&BE`ub?1UM zCkEd5Xd7PLG_cL?ZF37;r)ajFs_PpgJNcGXqm6Pnm^W&YVWdE8e&o@Yk3+S7Wf+qI zB%xZIN;@J8XK~C?O(yB0FEG(~+08mtM3!H45%Pm`;zLJpA{7`gm<)h~c)h50;w%{; z%r66OU_v?CYWRuruEZ(4Dp%sgsy;3!o}DKfQF2ZXV&4$P@_Jv1pWL@&wFUR^JKZb5 z7UKU|c+UU(7@QO<%6fkESl4>;J27yV7hyjJX#5Kse`iTsB^BGTeLDlO1?rl^^ziHs z;xo&j;YD*TMKL5%ZIVQh#bwq2V)3y+EK);#1Irwz!xX|D+O5@_6?c9x&n-$^lSgC2 zi!Da!Y$60V@gf+AliEu18Hiq%WG$}}#>7Rv67p;!V}S9{An?n_?!GSEKhNzyUD8(_ zB0uyS@wNCCe$9S)A-;V4JK_L5|K@A|hj2an>ErOz%#5_IB)sW28uMpw6+hC);WNDm zKRORSV(wJ^Q2olui2U$E|L`&Qs+1)8y8O$n{M5IPBj0MSMj&mCOl7fV4Pa;iOZ6vX)EhW)?Dm64XJ1X{;2?^D z6>}P9h<;prn5|yG^U?miBUhVZ*J?QUxilA0lbTSRCW%*BF>XP6T&XhUecc{nlq@!_7#7rA8K8{m4mz(*fYY8_ zLtY+{t#6?t$~a|jn{FWt5lGz#Girb1v-^^I3H@Vj8t-=CB=st~x%7gTY;Vb@58hca zIjADhVe)BKe@R6MiT%BgkXR-dCymLNft<$1s3KATj*={Fsr%9U-e zzGP!A(D5qvxrrc|))!$>Vs_+~rAUm(HOT<2U;4+i^-Q!Dwtt(+nqB~B7@HF z(Q27R)3!oE+1B-`FhX~A(^~wroqnX$cV78&C|FG`B04Bs9!i&$_OgCc3b+_K1zXAG z6RMJKSlWI}AObut)u0!au|U0|z-@bgX}{C(ZWE8wMZ}7WOM)&(Dw8!^okVlu8bDTl z;mVYe1~s(*X@UtdZ16mw8xF16%>ZSG#l;gBC$O=A=Z->H2LtCQK#D=*XgL;H zzUW(b$k}Wzi^3W2*owsY>0uvy<85GGNg9Sp#C)G%8)K@{DE>ia+H2Ta>3h**ARy~B zRxlxkM^DSbnC5z~JLkrjYuXpkr7>t%?~vcqTn$r}AE-_)Z+;kzA3yGA48Tq^48T7j zT(h>mwd7ohdJg|CtN;nSjR=faa{Mugs*+|Y^Z5v6lLuD>eo|yBa9As2dq#BGu!Hzg z8fGr*G75;3Kek20^y-38_%|ICo`}o%ttdqGN~CuM+p*V0z-^zgt<$@Vt_uo6RH*+_ zSdrCU*rzLDp`OZ4-1HhXgw1N)PGCC9krP>XJqm0UX9Wl{+DsLL5+~yv1DPz;QRn?u z^=shEu4l1phL=ZUK0BzLTbKSs37N=a4JfQqUJ|D`Ky!j?52Z_$5MA&5x}IZGmc006 z{?WtifR*LC^8wz@1JCJ`S2>&3#d{)#G695Eo0e3HlqPEg1UQF|YvY^-4j+uk_y%pc z2geeOJGtzptXBkU#5hCqT=Ww#|5e5vGka|NlAtm9D>P{QZzal3oKjdWwpG$E{oQ*~ zK9a@ZM?&RVBx#)_i5#CWwH?0ADszOdtNNyOVFYq$&J9Gw1-rx3u#l9f35r`u91E)L zy?OnjU8WEssU|C|#v;jTiaKtBW?YT1Y2G^HS#Q?z@|^8n9EJ5l*t1V60EhJYGE+|f z7TeRFXtV1wO`%kTBtj*1Jo!|lOH@*;c2z8zfP=e5LJ6ZaCB9U?w1fm1fYEO!E8Cid z$4QqF-ip^1GGc=y9TTxq5sLP{^os2`>s6y9rxxv{Rj~G~LpR!mIw;!hUiS5=Bme?C z7m(39J=Rla(h};CgQ1dY4}j}zI>5I<`yJ_wHScQJ`wqfs*_Ad~i7_>>q*pI)?%N(b zR2ln-!@bD$smzY9?jA5V@Fl00vNR zjgKWDnBr%$G{S)1WI=8n5XOq_AaQ3#WVuab;qn>aq-bVEw#+i${+$ zX-q-*gq3PvurF7iLSS;01JK!?2%l{EapnC6@>x`}4Ti=diz~O7)ensg?M#J<~$#tMkBHNDXrfJ2C+0zco zku>p1U{8#~RAyQZQZ;WG0Vx`cLf_s>xS|BVb-U&bbWK{FpF@MjFORAW;e{2ZHU!Uc z;v78fmxrf^%_hH?)`ZzYk=F3HLiIUOE&D}N?r&V~V0yJfD5S`1+)I0{rkf~a^?`MZ zFxm^2@0DN@y}fPp6-^m)aHDAAn3u=pj(wz2&>~@GSA+zUIMWw_ZG|A4$B3g}c+alj zlI@-&#I+#`Qkhf;l8Y|0TMDS3k*&5O~DgA47Ta?)EZ{O4}@AybEV6+zU_Y>ODWEZ zvfJT@s7st%X&AP#2w4tihi|yv796{w_I+x+Ybvm)4n=}jj;>+V0$eK>8+_sX$LEXuG`cqC^;Yd9!P{qb`{fe&)t}PUN zLXv_|9S2`FU@gRAT&gW1K+Q~}Grs9JSvO?XtNCv{AbA7ZgB6>1cX)M@l`4Iq%|b@M zTnAmpCNz(&D3DlCh9XC3_WGvjmg4`sz(|_bj9ygu)$5U_SJ)E#% z-0)QXBBRlcm_`=8Dye`g_|e(q!<3^a4(g#oQep+XCkO4Wzq7t9X+*(-_2S7BE2jus zS};&O*|+9JB(Q+HNll{H2_aIkp{ckXp6veF^r& zw(dX>vH4uxMgnU=rn25#HDr{{Oy@9ejtmbc)&07PX;=)p4&6qMZa_czzJFb+M#gDI z>F*3!@wTR4?139tm=T%}n)=Y*9-h6<$0HwsgB|cT@eADa7h3&EIIjPBj1SC;DjZ#m zTH+;cEfY!k;R5sb-=g2kPt`p2Ea~}|DsDeC-RakC+4jMBXoqB3T*Gra~)SiO0i7H$;eYrbPbyf{YntJlu3+1ZX|WTN82 zK!A#9yH18Dj8f62hLQMGvTF57vzBPTBg$5dh{6(Td~Wa$TuD>9?8p{Ry+QqKW3^Gr z+qA7HVvunPS0_y+n6~biRsBSycO12Ph$hjwuQ$4OGmN_>>5kx9Q}#K0;mNYVS5G>P z%b6gM?zCc`>W|gl6iCdi#-}n1Q-V(l9)#|n%@ToDJ#w0jRVBWGUw-lF&u$UeOC!aI zz*!EPZGRZbWiOl~*q)(Gqbs$c2SD4nhm&jY_}6K=^jy_3XGgE-T5)rNtD0E=qT$1z zso1W~6aU!MSBHf*XEO=4RLns(wjS)Yikl9lgNbBgN{>_(Mq(~Ug;tPYE|$Vl1lm(>x2x`j>l6j;o|Gk! zXtiF{L>#X}p*Ed(B8vE4Ki9uMzPzbmeP(-I7&8^f6XUQF-Qg~?gzhYw%cAayDmWtb zT`eL0#x7i~>l|aATm|MIGzn5CdfVbd^jLO#E3RPq?EQnAl5D<@5cyfwQvL6z{bAA8 ziU@U-H#a=jeP&NvJnfYFFC z5wJ{fuL2bzJcCtaEPB&QDI{H=-PiWg3bm~3ydL9@`VDPAJV*IyILLwgt!cOY-nr2e zT7`vIhsT#XB7}ngJrjn$JusOK#s`z7%%$~@l}o_)e_m204#(xi-A4Z@c^F)%N|fB4%syA@Kefl&^Maj=`BIo_9b8reSvwnJ!gBat|R^E9U z+&sjKH6QThOG6nZ9|L{z^3A!VjPti&owMm<{GKnye(^Mx0wceo%r8$~onyb|a+Zh- z4+BT0xUzg?%$kJe#)?}bD<%-@*i>Ewy*MJ zbPu}NCg5aP2_6`9Z%i5^&un|#%&H;ir&}5b4WlP&q!@YF_ZM$&*kdpFj~W21QS?5r-1t<8?!s+hm}spiEPG%Ni*as=9jx zzKPA*eB0R*#Z60XlXP_+5jgNeNFs2ke(Tt-?AWkkfhoC7umTk^>&?fk+yK*&jW=YK zJa^SbaV}jSWJTK0A9l-Fxin9`2K8*U-Fbhyj5i7QA8ogUJyb;mRb5<-_FgK<;t{bC zJ(H?A4z37HW|oE7lpe?g#IT1JQp8C$Utj8Pzva>ew5Y)>Co9@W7LH(28*EY$ea^ZU zFBVz@dR)W~<8!ipW4tCE2uIaaT&pp1-Y=Wo^3d%6OIY)CtRJ~S4|}!6QtbOu*QMIf zKOl0Sy$}|({#Q;hx^|K!-Mya4Dti}IBvS!OfwnE3Ivu5wHRLm*VEDpl3~cRy#F}7; zQc4A&Bg2)!Gzj%tJghOO*irpM@v^K{-9Qdnf;;LM*_?cwGoyW> z_#$MMv(JMG0B-tv(Hw+5ZrXswXe@0A-oK(CEUeYqoaobQYVEatcrj8+D{NX#MJ<-Z z9vGtNL1iO>mUZNMYRG>?g>~+U5_8&DU0VYMS~EZj4&_pgr%H_rFQS~Ou5Ghge*>R9 zRnO!oqU5O`$rd?g`->TAP zHA!hkAbnTZ1hpD4D<;w6N}b(==5hkMVx?JkGJ^Oxe~H_@$DuAus@7@h92K(B_= z%)4G`I&8O+RZUZz?o4YLZd!~$z<;`oO^2XpF{zcA4KtD5bVR}d14N5h4u?JTsM|H~ zVB2hk@~yvHnAE6TIzL}qtKWlV#(gv;;M;EX1F(`_+EsfP#El~~!Pt=S?h+eR6rl;n zTtB=!wA@>D7BRAf1GFiL9nLc5m=PrHT*kglB2MWD71QRR%}3K^+9oR}Ww04Zerl2= zvK{v@rL}dol(KSOq~Sp*vWUoSdD#UjEY+MeMuSc)DJrw(U9`amf+fnfn&R{ zTNIYtHhz&BmRI0bwb~_W+p?>h_07V!xlu)vE`woC;UjBcLgmRfM5-gB)^7{_4J+glIrgWoxsz3Nb)miA()eQ)Ax&10C%ybVLr3;hqZ{4RL@<*9xKU zXxB>L>(2|+IM%s@Y$noxB4usA04zy$Sl6yV;siJrn)67hNrG4O9YTX6?a`aT$;2Vv zK{NA&QHd@e=x=9+^D5Yie&{#2xp(-|a&{-(iW_Mln-hdg6_k+Z(Q!lC2JiTQ#kJq} zE*7L1)YFq7%f-E2Va`d<1B$Y8=qm_Mm^0Mhi~`wAcWDnPb`qLDUS)xZ!b8}YL5|he z*TLjbk7>;0i63c5Dw#0up&{D^sti!6zUTEES@h3{E_^l}QtaZd-A8AB%ah#I?A5%m z3s@CsaLrHT$Rx~&&(t z*XbsSi~I!5XPBd+esgGUs}|^42-N1(eQeX*CZh|5mWT|986$E754+zc*iMA)j}6oS z$SRge7JXKL{-T0ejI3G=820yDwG>b0zTEF>f09uP6!(;ozc!5;l((>lcHol4J>rdX zbA;_(9FLI49T?DV9T$HnN#8v7*0XvFGokX^TKFmz7+(7QI`+B*iEA!B9;2Y31bHm8 ztGH~ptFI?D6PeUVgebsg>&z}9xFziJ<{%lnm+AoY++91D#%%MynSwttLS2+?M1S!q zuLK9z@Z3PAdN}3s4*uy=dF-f%#21i{j~x{pPx-0Xs%NuQZ>p^deZs(vxq@Ln4A#fL zF>}um)kEVoppDKrrBMfsX>`#v`cbrOOxe|R2b&XF(DEvM*ob+& zhejoG?#p2B7Fgh1ZqqTKWaBB4o!iqI3!il*0h~}o>B~x}tfrBxlWP#>#F(cL{9nl+ zamXwUXZ#5`j^a8BQ{_PEj*<+6Y5ulclEHw+O~c?+cT29PD{>gz;+o-wj4ASb6SA_b zv(gLGjKc3ojPiMv3MD70^#aL${8LtSBS-<>8fW*D2xSH7ullX=fL~ZjzQ`olDiS|? z1#Il(8vDw{O!@7wuDt4fL}!HPWa(d{R7QdDB0^e(8EeB&lzlIb3e-!(hmU^`q4s9^ zA6KvIyQfVB><^Kq@4kC}FI+R(e`HTPY-DJ#dz5ScPHF?Pg4?!1sXz2qL^>bN^aNPdg()5ilo#>Fh=H@I?1MB%*T}pkeyFhl z@`$$}{?PVod)`h(I=G87;0>^&4ED7h)gBCqD)|0jVya0;*gWS4YgOwhD%du)^;=Aa}!|Rv zD-d*xaI48KR!EVSZov{3g%?1x_~v#7XAp z;SapeRBXQQB)+-nep3_O;55aH+~2%Vd3J3HFzZEcj$8G+L6*7j5&@PO$P5;SgG6YN zoM|@_Vj9VCM^yMW9-5z!>(JXkS((V__c9UkQhYZF(WtU0tVlRSsL;Z3wFJN~F3}&w zeA&%2pc5w2^!@G*-O|~E)V*frfIq)52#3nj(FJ;HVHYnt9sQ9`gS@HR*AU6n3=JNL zKSIP01C3%LY%~Bvdui}!^7CVeXsn`SzF0%k+!w(IJOPbs-wedS)CoAMnwAw@Bx-1H zn)OXB-1S}Gn`LjP9D^KNzB3m}EhvGb&9G_uDC?d_s;C^xp(YgzDyJlFfPdjrf(Gn( zl5@Z#N3={`(V8dSUqc$8+%f<8h(*d?w8)>}z;#yn8<614twdlQ(-cekoTd zUTxQ&b5Val@Hwa!Yf#v5EB&B@K!b+Y_v_}8SBT=UyiFvmJX<> zjI2}~508vFj=r#*aEKhm|HENo-O!L(eu-X&#eaTB@@B|KUUgLH4idko` zyaIar=d0hzdO|gWV#ECA>wk-dRe-})H6wwwdSzr>h2)R_J^}(Z{Z8n;pau9UV*$R3 zmF?4yUvXQfTV&|&^_HwYFE0Kx{v6ywzoPQ5Qf!ZZRxeVcX|z$V#xq{ zHIfkn=Bc&yAQZYs#c>U9t88TPy54nlI|KHU?&U<&U9%gyj_WAG7O&W$VC>_3!#EV= z8^^Ku?Dr}I%R-Mlnjtm-`@Kt#1|XwrOTh@mU(k?teJTpewz)P>OeY>5o#jTc-L)qys`X$a;jp$Sq-|z#^onxHa~nKKOC1B?b~6<^M*6#ynuuw`Eco zD!7ghKmn;>zn5JnX?NxMy}=_AnT!q-r=&K4!oOI|VLS*E;>aSw$%OpCAZYt)llb? z2Nar3r$GIuROR6R$@3iH@(po1-lK}p_u35+PS<7W&Rq`lG6Cj7`Us6E32-hd;M8=o z*+JKL5<6>xEJxR0^MZ?L9d_X4x;QAVOlS6{$^GmY7Z_1!cqQt%ASf``t=TiFRS_?x z@H!Rkn)S`TT=WN1nz7KGPLkC?3A}>Tbhz`@Njh{VRj`|toaV@C z)TYN*&)UP=T$6GAm28)ej6^KO-oKdavvQT(rM#WEt2deusE+pbb=)otmp}CUV&fWH!tEKygnzYvJmB7NuDuerC+23WQj)D5Z2%f7u*2iT(zr1H;t&;P zcGcI1%|?t6Jjrfw`Pl5H3sL`=7i?@4&xRXzruZ(mgQUHpz}+Jut6Gb{#&_>nQ}!bX zy0ree8+LAU_Pl-CwxTVKO=O$|uSN2_wh2tP=9otC6+)dB^DjJa6Fb!JWeoUDE-FZ! zr-%N=)So~>U$w#>6E6-1iS5jsETHp7bH#=kAa%ffRbC6*CXotzbmlQ|OtGej_*nW& z6;Dzng(+Fnu_jXaobiNEoRt?6c^=|%E}CWU2>J8lx&Eb0FxPT2)us)$dGOK(egWwd zrWsGT2rd<<%fAfMK6xq%L-OE$ZD+j>=cIVM&B@EyB)?CviMY!jojvJgtxU*jGe%45 z8!O(upgk{pKnSQX)53|0lvl&O#x_%O-=F{Cx4P>9prNa6_zaoHA_zEa%NTdsh#O-= zgv#cH;0*Vt+_g;_XpTLV5agRy2pFZ7mw&t3Z}y4p)2{O?&<^pP z;frMhcg2Vk_oD=w02hRTIu!PuVx|RGN9?pkE#AGZYSd~@&4R<>{(}84i*hU+Z1M1n zHz*>%YAVSDVcv&WN>|%zS0&A2#J!;LlcdX6-~{QVWmv-PUf35vh@X-yX!g z%c|_TghDddi^P0Um+6h@xBjq`Id(9#WQC4AF3AEu75*thR}ugvF$8eq`v4pIfT7Sp zYknwnd%vqTji0of3Rh5-qr&jLFz+L))YM&2_;seoRcen^Xb&6UepUu`BaV%IbKNW} zrh_tD(+=mdH|^e{Jl>vy zBF5s4`iP1xLL5A>&DWSWRLn9zn2F*|jRPgntD8#p{0C_-$zl3?SmGv(Y96BiC zChy6;)W5OM4gXeyH1+UR(q9kx=<|Y;T3F7gx;4S3<2YlTpn_$L1(FzLf1tjXW$@I0``c>#FFD4OXG1BcXqeMN&w{RkAQJlv1;haj%;}cP;e&9esZt8OG zYMJ$J55v2CvrZjXPvF`goB9WJ<*)KWWjUHl>;@{V|NSR+-$|CQ(Xs_~DK1j+tE_P^ zmmalwj5<#~Vbw&4msOJCKe4Lpj2g7VOp9ph;mx5@C~WX;BeRQ(vJ%!SDjb))cnT)W zA;2FJh7U`x1E!5BIheX7`_vvpD8=`yqC~FUgyQj2@xLhxAohKXMN@ZoIF1H@<<+ze91PZyM0z|Dy_v6%@@52D3YI^Q zd#BJtqgLhU++xdHWU#$2RS2323znHB?DJZe8Pg}-Igi*pQ7MIK%b?=|cZSyDJ z4iDET$7%VQdWQgfE|rf&(eN^HY|^d2CuS4pbYTi>^%f&~P*V7*OXWI{ywHLZ47y3t z$w0ln3VAxBZbjLNg{A|G-A2S+N$r&AIFV9dhPF7TOi43=ACil-7eaeb2;N^x4DL%a8R6gGd`&y`$jfJ6 zXkURZLH#02io?HM#`>S+(KFZwgVw}lunt1z3h^U@9)3wzi2OvpXTSLs5`1!j-W1~= z?J+tS7~N&q_ysj+Cj^2y;YiY;Js=MZgO0M`Nx1F8(Y~+NO-Gt?oYdG#X^NU(S?qC^ zKIehBxF5?a4OUE>TwZjo0 zM2h4$)!Sxc`!vq&1xBP4mRE(bVjQ_Uby7dVHeZpUK5XLMGVhfe#q`-I+|UsL+H}2; z^!3J_OZ}hG@*yeCdT*t-e;lRSlQ*Kht+s8ogqGmMjFX-~4(gP@-uV(LJ1Lib+1BvT zE9*jV1ckX|g{({_qBh23SU2K%0hxn^8tUAyBC%nHVA{U~SHkg$uhkE@UkihF*VRL5 zlSs?-3Aq#}WOy08$fbWUF6*|HUAeXIBwS-vcHJO?E62$p{GsQG$^Z@qCH60&qmoIg zFT?~;UGI!loTI-WtRUb^J!f(Cuw^S}`$HE;v6}Ny0dnO535-W+e3I(Fi131~`h%2J zzZb7)Ny0&6X`V>bjunO~dCnx^s0~|QR_(IE1g+uJuHTB2LNbk_c%*-w$?fUvXuyy2 zgZn(2qK1)X-!GD94&Qo5O-$~nor79qIvWPcigK8fPKlvar@45Xqd+;9;Sxol8fctceN?UASck22OFG1{4-r17ROG3 zrC1r3eLqex5DWiL%zYtkQ5y+`b#fRF%)I@+It+ubiNcNxqv6`MzO$l5(-U2h;iY!B5kc7`=yG3tN$M``7kG^?3Sbn zSaj%&z9lRewYH-SKQ4>y5yKd#@g?*wo5nnYlh!Gz!I^n0cH&rdo^1Fnc~#XvCX=dy z@VwGH-2xo3siF^98r2A2e>#Pcpyk&F79`QSb)?7S9Bi;oE;YLG4yzyu2(I?xr;d?j z?7TEq$WXe*OW5w6Z1Ro>vc|*!{ZyHr@}}qCOq+WhSJvF?xK7J~6_4zffZ>W_?eY1?1=nlcnUo|9j_56*@L2@9FmOSSC)G zb8;PN;x>bKzN$CPj-U4dBzn-lrMrEOLVJgtT6Zq@Vj+pW4RMPkYyM|NwgMe8c)%3> zdysr<>~b;q3AM_cRCTVS_`Ea?!6D>{4UBoee#m{!RFsL93*!A`G`a8Fo3I`Kr1%160U9y+ zfnPYm9dr0TXow+f$Wh$}P2`hoyx;%$&wxPupZ`>QE2MEpcW=2iw1nlow7D6Xas$;n zwoc*V{d;(0`Fs8`M)|FISluNBreQ@jj?RP1C6^=qQ$Q-GSnOLb0A13 zU$e!!!6g?|av0=_tY2mwA|^8Su3nYD2^XyD%0=5RUq_zhONJdR3K9+~X41-%&*o(Y z0hosdzUi(N)7lDm^1<*Z9aNnGm~yg%);>OL3P(~IK$Wa9T-T;C@cH$*HG63`3&^j= zK1rp^Vv4xLnWn+Y`c%b7jg?mp*bA9jlI#*s^&S@{+FPIAw|29eX7Tvt)cCt|3kb`)8q)ep5~KfYBF zB-w%pJhD=M@F0;jYasa{6nsoVp@kQ~o#;zmncGtM!pwVp*zg=Ru0n!za^~w25hi@B zQ^oxbU~6?lk$)dy7?dCB2Z)5)?$UtSWwT#1yHz`RVO}g++OypWcNtNXjyG5u@u^H7 zDNk_1I>Ei06!?|vpsl8mYGwVrQvEl+->K#;zf||;?^E~AHnSm6Y}3I=xqZhQ@Q=1) zci;7QvAitqfEeRV%?=)Dz3*yhq1)p`w-fS!Qb!3pGq(syaag4cOR{E|_-h*(%i{rp+mSMtqA z)_QJB33f2(y_1#_(?Ui@lpd>iC?a)q+IESr`0;XAe}^?|TDq!e`&n1dUT^Rd0`z6^89-ePa_R&#Fz+-v4|pQ!x2l$pkAyB*H#IWLlGGZ2^8iUFP=&?3UPL!D0Yw zeCb)KN|Pc#GIw|sA&w`lU|Df&(65wCX|iz~Nh4T0fIlgONIuyaL`R~UaQ=Xv_u0n) z83mLrh8~$bUm;+}l`D=O>)zF}V3G5Lyx-|{zwCFkTH3Xm&8_1Pk9j0DL~u?j-T$K= zo2_K5S1(-KEokY;eV$lw`~`zIKZ}cR?eO_4Og~8WJ6q+mZOUc_PLEz10qeav^muF4 zFwXp4Ht4ux1r|YTZ-4JSf-d|Bs_>7BCOo+jOs5DZS5BY@cLuCGYE7D-CDjaY1$v*r zwlF?+Jz*N})|`g+bX5cYm)U@3wzkDGg18zvNCvOr=G4qB^@BBNozf5c{WlZoT*aEJ zxhvdaq>-~+-(-Y^*luYjlK=Sn#aki@XApB7CH}ll4 zkfo#LwkO2*1;XRVJ~5N`Rb#7GfYQ@sZ{5EW6|nUBLXm>vOfC9bDl~l2_jUD9RMbv% z5@^owmD*xYdGuWYweLx2OBuO^Vba|}SX*A;yjH@%9JG2fF%i~M%jA3J6&F7FGf9DZ zxPmN`&OpE+H(Rc%eMO%11H`xjRpU`DXyF1izcyEOZ0~npU=cQYZ~QQ_dbp3yj@BK9 zk@b7Cxh6agRKcz&GIU_HSxT=ouw`SQ4&S29l1mI-4%o4-_t1oJ0UP{%*}_?7^2-b< zzrTe8263m2kEkTbB_k4kU?{D`c&`s$OG&Pqb!M?rAT#ihXpd}l>r#w@YBI+&3WMxq7^jz5w-Xg)gfWj8f|uo6BBO zI0hZeMJ$;IpC952OilSSLQtZwTLYGSUd-3}V|*7qBrvw0{6&T)N3f{Akw zXIZrur{vS{yR*BW7Efm7T3DNvtnJF~ z-kjpn2{8e6y@5U3^&7uw{b*6;*p^6CfxnqjX22dgKz?&*X}!IUD7+N=^ZNwU3Jz&q z&aJZIE(oE6LAeZ7%uvv5MzIGNQV?p4LaXqxZEL)B0-uC3Y;?(lzfHp&!%&h1Y1`Fu zA(j8@%P&iymN@e45c}*NfL5+$ zxIzB1-G+pB-j|zdJ6b&NmBdTl@7a~?i1taN*yuRWDUvE?FZh!5f)HgVtHqxK-lT)1bFe}b zVig_8E;bHXp}ZvDX(#|NQS1_>C5YA#6s#3ZEUl*GRIq`ub@JqCl9$w9)gV;I0- zE7ZiG<7auo4d!(*s1m*TTK3T3R0l@~$CER0iS#N4n7C?gg$w-PMk-cwDkD|4!H`Q{ zYFh7btj%~|6AT^VSn`rR&yJcp{}0b3VOnZFMrQitV33Oc{Ep5RBQcm7(MHV~fh%#X z&b=oZGjlO4)#J4qbaa92Ixf)v=#0|gsk%%3mG_*`FU5!S#~CzNsdHQh$=@7$SwH87 zZJX74H-a`Xl(mo#K6*oxDTluzxG}pIs)SDx<99Tc59^4-`Qii%&uq+Xv{7Ax<{`?G z@Qeo7GJ;J|Cev#|Gl?C-D^ORUfwhhRwc(B#ud?K17hZj(Hn=?vJ}!~`AkyMuw2vi5 zB~p;E*%4e%3+MxOfH;nX@&e%_Z@z~)+0S_F3#u$j9zC`xZU}zyO3D0_C=S5&`7kHK zal?B|p>jEz%v^)!x4`YrAr}a)DmaFLNM4!LmU=C)qop&k9CJ{n$#lSW^NS+YPC^dE zwXb6cf~wW36fdo(k4O;{5`np*41-2=7Y zKdOLRdc+?f_$GXfp%Kf{)L9+?p%sZt@LSuek5P0e8{8(9Eaxrxd@}Q`)t81wSRLf+ zfDAYM9d{-+l7$|8dTs-cZrc83!M3eR*6Lkn?On=Ms^DM8&f3au9DjWI{-BEuY#F>rDu9Dk*}1$7Yq*4 z=Up@0G`5i=N-4pUk`WR=!}REk(9WNZcb*-LNk7@)MDkJc);+TN7*xowNy>2UP;8ci z198~OSmTJP9Mje@31-Y%MOn6NX1Ur| z-F8lC6TYzE3!6}?QU0@5d_M>e{Zro^*?xLdM*%HYIxdLnYEPs&fbcAQ1DF(d9xKaW zSb|{KP#;!3arsmh>X*8m89xj~+SHaW)YbA18a zET86hqkImVha`;(`En%8x$PHX55(3Kr$9CCs7E?*Io!6NT-n0BgGKi$(4?riNxrYcspqt9gAu>+e7 z!^|PxSv6CccgPh5N4*2_MQKYGWj-Um@Jty8>0^b+J47d zGkhCLQ{gjVNepGR7|LCZBJD>J>@gxkuP@56=lV$RduLXgqb!6lJP@^I)V-e@P|mom z5H0b+m@JtP18Nqfd2CHsFJ9pnZI>C7Rm95uRM;Em_^05dQsjk!8O;0Uy|;lsf>Z^H!3@niqlyKdvj_y!~t@;ZVpl{LWHmb%BbZ)gPLqX zP<}>m3HRmDytAmOV~er_iA7iuKBGZ+MsskK9>Glnjsu#|76v4hLOT_ha|Y4|?Y(I? zWlPR*bqu?uOe&IzXepRtnP9`wH7jU&6ZrKk%(hGw5V>mhk{{`CnB1l1&FK+{9UD@} z+}nyhl$CJfpiZb09!ja*hd^*4dBL1$t-q4s3zt%&Kqt8n5>X`=5~ zSZOG71YIhYn}YIvyjgs2h#w$r|9}2ZfLhIyjf{s7$#9-H8r#?m7ib6;q_O;G9gM(b^Vh8~H9TWPB2+NLx3Fm)RZnkC% zzuJf1X-;DmDh5upz4JE37W*4;sFsJ$`6Jeu3{H)?#|EbcJH|R^93CYm40P>yU7fRZ zy^Zs&$@hR0RZfPSlhiYzk}y(s0BR$fvDMSu1zeIKOBJa+zbUstmKlZSjyF)fo!_bGz#PJ#pjUN9WVwKEBE%>PM+J@H#OB z^lRk*xeL!@h@Zdw#YEa9UyiC>bN`;{6Bdu3ivPJtoRz1~1NXOOUy#8a+10i|6^`yO z<}+h5ufczHn#9}K&Oj1%_G}y1mdBm?qNb@PKdGML>$hzGj@39 z3r7-Zo{whSS-U#^=UY(mvSLpL7)w%$Ofh!OG*YI&t*K6OQ#=DI zmtXtc>*0%Ucgq_wtD!`p{`ndUu?4}mpdW>crt{ho83o5{s|^1*vDTHP#yXN#%U4ve ztXfW;*;8zTNRo@y@XcS`*9^}q8Dr!MztSgAXfv`A0mf5U`=xYKGTGtfTq0ZVVW@I6 z9nem8s9+Az3_w&=I~(*)5M|-QFLQWGR+@eR0An0U%e+%u99D=1QYF1_(8{{Hy#rh@(K(V6|{sPkZ21^xZ8{pY7v zq|j(3soQja8ZsFu3aK~S{e8rxgDi;j;qoAw$av6=lv-60Ye+UmRI0b5mFh^K3tx!C zINtPhTuV)DVHWa&KyxIQ|=f4#rF_}x7$_`?8RFHXSX63GjD^;A!M{HnUi;8SrB zU!W<2AD{gKp<6FPcei62uZ3T*lw5=o&%`fK)V5`$|Lkap5t}&4K_r)<*Yss# zBU-hT?t~@2zbVZL9;MlU0(@1-gYK6W<8UcHEf>5?Mp5$aG|`4t9J?QH5R}X@D^hbT zA@0cG{%~BlT&XSv)0)Qu9X$qRma(bWJrp+wLJGeI3yCQV%{wN^33vvA4hRNDKT0f6 zx29za)lqod0tE6+n;jsSyR6Cn?J(@?RjHbY7&H7~m@HUjMVitA`AfuZ&bJ*o>zsH{ zfn4hmy1r_X^B?tl_+G`oyL*PI#(efaWzC?5z-*q zF`9s*BiIZ5i9NWRhFD)QnEL_e@z7&}QxawW@CJmbbA;bLApm4&B7bIbUMObZwrf^-YppY1uDo2G)qw?4g>d>quJg6@B@EZ(7 zJC@ah6uATM}D`2q0>~a-S%gH$~SZfkvCuqOyATlc}Zk z+?6<#&kq?bk3^Y0s`8HCMzB(JF+O`svR9L=2Qq%{z#X#|Lry-0=wc!Q}M-4v8+ZvW3^UoEou*iPKyR_x)4hFI>I^eAxa* zCjQivdymQCADz8A_j!;x5PCKcf{nRVj zF?IZzxMYTVD&n)J+NHUCX#i>R`Oujx4+83`>Y{>krq2xVoL*gw{o<(?ML?-kOyYtb z6@c%~@o9BAO9XP%HJe=5>vI0Lo{u(%g4ehoZ%~@yP11OiFHfdhJQLZ;(6N;_-kPY} zw%GzoV|9K3&CI`oX6B~EK0Dfp8>6Qr7N$LVoJUSS<~cla0jXn(QO>;16r&uRq%%Md z?y?BzL3kFg%b|uQ9k`xId%4)YBX1wi$ zoXG1(WZ&YttwdPjPz@?90h^l{Kv1>@{6d`e(l*SoG4GtVq*k(P%TdxL&{?KD!oOZlXi7onA+zc(t3=s! zz>z!N@m=POXIW}z&kiFIt!0NYIc!UYX!@4A8fgm1|Cg5G$v;t}qU2DEhcCygR=)|~ zxLe-ST1m-JnKGj!`{f|BZ_M?D<+zmo^r0=q9R4Jh?6oGsgpZ%}eq(F7WE93z&p)lV zxHymJe91{Z<0}}4UUUJo>{UI814}Y| zTSASz&@`VIf~v40v^VO7;Z%X8a6NR9?5=JrTqN{hL_DXd|4xrS48}b4d8Ef-s=!W0 zE)tPjgb;4%245Mmp~gT4cM(ht@{wit`Ulk

    vF$d=iui;88L;#B43$Mw_j;bMYo-p{nCw z9*Lu7hIRr(^~jI1;3NBfF9}wJZJ``RZ+)t!t@BVkwli!*3A$0;8`iu>Xw-4PWkDUn z9BYlf$@LLnNm#oDl_EZWz$Tu>C-e zhdD($gZL09h}XBhfp^$QDI5sQgP2lGM{%!?bqp$lAx#X9N>oO&{633!DMz$9@jSGiv3CjTZB;~ zyC~D%Np6SoxfpWOnG6R+QdhxKLRd09sKYu8Wl-OB^s$9pkC>jw$%P0qQN3P1N5pz5 zp2F>eH#fy3WLW4S_Y7TAU|c1Pa#TWD@i8WNwxq2h!m{U$NyaxJEOSIQ)(Z3^lV2sW=4 z35c2;LPS!KN+1a=7uRMqEYVxbj+KpB_b(*E;JI zGvy8P*mYA=1=T2uJktUo7imEVUpx__)O2N7 zx=W`ao0<)#;H~=A7oSE2qKQXKSe$8I!a|3Dli}Ju5ye$PMG%THn;?wd?(QyTJOyk- zq!b~E2M0XbLq#kAptdevZ>NcxT<>*qM@4atn4=yg5ThE;QDc)nLHQIMpNY=o;ikEU z!rt|bF&Tck#5t9$#t_|-*gw9=0vP*9qQ>8Jw~(+CVEaZoni}Id8xV+PsN@K_3O1W&}%X{}y$ix#_M;-3M$Q z1}YFR3W5^$y70td;Q>@o8iDffho`e0(~Q>t$@p#Sx2g|@Ho^Qw?)yvk_GVY0N=-CFo7g_hBZY&O!-M*qOqiMxu{0Ecep%ex_O7 zD1tN|+`+n%QAQogb6;rov{ahbgNrVzK^|Yi9ic&*W1-oBU>c%fK-#q0%=3ki|1~W= zfY_ovAIz^u^Sv+XY~eJ4m^WgMRJ**~rE$}OT?az%uiUx&iaCLObYXx3RG$-KglQY5 zcP|+!(CGcR$o?ztG=G(GzQ-|y5$vA(g-7LJg2?M#ZD#iD-r!gYc)z3#7?c@eq}B{x zUnim9C@BtI^X5>Ow3lRFB|dj)!Pek+_1#{~3KOP3(rYyg0A?|xwo{REIM=j_UR!ug ztC)JYp%fOfZ`fv8wYes(l~2vrqiokO?kEYZ$HI-8&pL=VY8Gpd+V9rD^Doi$J`{9} z#5)hfZ}-rYt|HFpUF~*oFvvn!w-UzZoQk!6rahdYSK)WhqSSP#0gKca6>2CFZGwma z)sjhx3qC;iG@_;88mJjE?usU?Ptu@_kzK@^ltGqA7xw!A;4GQ|gD(o?1RH*WBj=d( zQj{vk_hU5oUuBzKdho{Fy1yxbbzdhBY|JgjgEj%z*9uhN?x9&eRT_#)|6p+(EeC?f1@$h!i>o<|p{)c-0!oIrGtBUKD2lAH(*IWsCMAtzU}WU_nmbf5MRg4bzrC&&2b`=5R9_I zqiCGA09@`&o~TEp{#Z$T2C#l>=9pTu&t5>kZ1b-?7${6O!&|4fE(lS%X=Vg!x0(D! z_pq*MxBcFg+aJj^7D_Ba!m+)vc1YwoF9TG!hOBe%44*(w5n;qvjl^*jV=m`mTDA>a zXm*2Ek#qV5YM!-uzpobBw$Vs(80EAw*EsAf) znz(U>5UImkG@2I(nF3UHK{}%w?gqpEEXx6Q!%ee|gWU}M+V5eK%k!%Jn(OJMb%~+n z0OTB1TOy#7aEZgBaqSb!xbX5`K@eGpqpMmle~+0}dB{gzd5C)?l?eDV-0sqq75wv` z-$OTryaoMFH3YBif)=4y?Tzq2&1tH2=(a;O{nZ%-BRkpc4->i997 zW+t$S6&3?Efw%Fta)INFzUcH4Kg6V_akJk$b`g^Cw~&k(K?Y825wa%JKm#)Hg~_S< z(Cw=GfiKle$4xvO_(Pg%`*J_(WLttPK(9vM0&AdQU3Ra&|0t4K1wkwkmBiQ$j6Qbxgar&ns?bG!(S5 zIqZ`TR^ywUc^Qc?`oM#nXoUjSF+o)aI5;>_VS*@eMc@WJj%Oe)%Bf1bnBuU8&VDV zDp{jAhz`X?7Ay&-Z|1gbtAI4JRrIxkP&j=^TnnCEU zBbIj5oNmi@48tkE=u$`xN)MCn}p6Z`}?j!^1k_{Pw@Lx5v`8JZRz>Fq&> z4V=K#reH*xV3dM2aiP16@Eq+#LWKpPISMQy)^QA5+1w`la4`ZE%! zKanjkrk0P@v&MpqkC#KUw!Q>rRgFC?3x;F_6d_kCW{mL&8Am5i;@F!sWkd4D@p+p* zxajn5RQqG`p6tt4RduU6+9NF0(hj(|C~?yL@nUY@@g6 zF^lIa(Lou-s)dNKq#*0apiRw1Q8n7q0Z=ETvEou9iL7PawBc@=+(z9cfk_Og0pXYe zP*gEGMA$NQ7|PYxVw08xAZKMUm@y>7q&Bw^*4IXCRXRq9f^3>=F^HqvFKfqXP8a6b z7$%_b{U*%FA+!CMS?2Cn42MBTRHwbwSHBZn8nXK(GA-MsA$Oy3c>SV)=5^2J%V z*Fe!CFf;7DV4zvx)R-cgs^ey#-<$Br`(FSx^a z!6^;9-PXDDL4#rEZduf*++iqD@z1?;x0Em3KhMR#F3?7J5pub_JkKI?L9GNMBf+QN zdAPVQ!jI1N-(hE3bwQN6<>h&tyT#{qJdxKF5-zeH(eRsus2n;MiZKONzzcMODlSe( zfy%fvGY~H75*w0>JgNlBLqs>DYH~uHkmZp6O1<*Nb^>e>l^n+xy>2##U3Htnxep1uZx25o_ynFY;3ev+Z*S{z)4UZbA`l1YP$8{0m9KVD!mna9_PMh$P@V=c zsBRO;CNt@58gBfGv(R3e@ExHrISD^mAhuxn$yDX+NmI&LWKKePxpKs8Vo!8oAo3?0 zf*qRGK~XYc5;k;|0mk8va3R3Hw;5@g#L_jrJD0^)0hN|<}mMBgpA3B2^LFIOX z0}k7q3}wp1y2O+U_pDx(KvP@Fx^^#ub8N-t4BbVlfU_~jjTkDb zm_zcK3|md%Upbxwb~J9~^B9Q7loN{7r_VQEn@>$BCckaZgn}G9sOhmudn)N@BpNPV zHGwT8n;9BcK$x`sx@%Bw`Y1SaS~i6<5712!Y;D!@Gy3oV1I3tVd%-=HiffH^|M&-TB7 zxxsuC*{9+Z0eO2+zz+~8j(yB+L6N>BH_h&y*g_A>n+I!s5>rtS^7Ge^%hmZgbT&Re zx>qtUt1w-XZ>oXV4pld(?gQ#jPvCIdW}(d8-}=K2PR~`}oY=exBq!~dRSiw5W$RaQ z7};t7+0|iMwY-8QyPA1UE-W4^S)+@D$=JB`@bhZ-y1!KffZula48(RcK(vt}0N#%! z%jB(*?EtnEX)6}}Z-=#*enaWF$s?>>%=}I~9Rw_Aba3Yu3)lEfoQ_o|b|mR44%h}j zM65}xZz}m~TqT-V)+bCKzYY?5%7_jT$wzZkXf6@ZnVz<#64`7m#w1Blm?f%_uKlvH z!O}-(!AB`H<6wVGqq4ptI0SsTnkpvv*c4U!#O!lXDxN4FqB0qN^kCQ`UAzL`STcT* z$rvbW$(im7bB**+Ug6al*4Nh~57AZcW$}R8Nt2w@YjrFJK8fo()>kDBljEc^w zjydG!R6s_&Jrik=U;cb;nUfORvbscU%0JwTPcQA=90usi=vo6XdTk~+p;-<3e@0Af z!Xc$1gYYH$agK!@qp~V4o@5x?p<42@_}84R4V3j8dsxh8{kKAj6!HJA7B8YjN3xCS z1||Fix{HyiCRCcqaDn2TNVnS3Ttqou(I0?-eTb_WkG)9);Z%$!7#^4pc#O)3;vX$1 zPHB76Q%?MBE5ue6TaiX0>>X(>W*hM=lMO_=U~`eDS(&gc5$rL_GU!m0*>WkM5|t<; zw17c52BlI*R7&~M3%)!mvG-x$7B|13HTDOrYzlFXhjHF6wP_`v9J@CpYOQ-}Dsr2fNMlY70qjCVcp8 zSJ&cV$L^7iQ;Y2riF4sa`uR~Y>}xS1U9G4XYl0buRAqz{^&NU7Bh!Q3YO|)Q!|)^X zD;0g?+ejGBNc+HJB~;*@3`52<$drRnODYG}1YHNEv) zlWTj@tp7HKHnycP_A)Uhbs+*ciWht`>O*_T&GRFX04)+)P>DsofKTtsw!XDUs;m3W zqHnXjIlQ$-1%ja>?2P`ZN*F z@h)|msPYzZj>sQEF?iPuH?G3KBy1}Pm{hIY?KLM1v%E92!Yv1mjm^N@X+iwQ#G)v<}|G$R~E6pRbtx{D+Z$Urw`it zva`araw}ZdrULKc`uy{s)X2UPW63ByjtUU!b>=FpK}Nm!Y**1pEOu_=t+80t?YXEiCc>{YDjvZ zXDm=73y_gyoq91qrnC8(Yq9cLxW4_a)T9V(rZh&MkP=}Nq^4@KtX-pc(g*yq?T31G zby(<1nV+wZC~*mT*N>@}X~@(7)Lj@}yt1n{0XW-#J=PTL4aE{{YE@f_6@FhGyn|tm z>#9O#!htmQ*E)Dqh&q=YMjVvMd|L4%07tpS;b|_Jb zugE}kUR7hu3INW`;^OiXial^kDgR&p+Nuw~Qx*Fc7o4;v53#IOBh|@FwKnp_ zN-cn=mdY(qwGdM$L>e08co-2$1=rpnbTtCj+!4rb412=x<~k*R)H+UE|7%i6A5}du zfGEv_c)(g>lD~SeT4nUEPletJWirUERkN`h-==AW2_+5tl+BQ^XRI{2BVu_5C#FcY z7j3_M9m(Z;eebt@TcS9l=EfQPGdWSXpU!h7<6AHuBA49>`XT~}5IhB3Nairu zDHqJNREr^mj(k&%#ps+w<>q`1#-d2XMuGv2ClS z`yc=QyHBU~5?m-@*H^pO18cqR!EAHlLG91lNE1p>NcvC3#f7A$yLcv*i9d^rKil;b zSBt@2lBM5F?8ugUk~1bympTK;7H7&+IU9K{ek?7UV##80AvJ)xBS=MtjBsIRvL}TnLTBxef)e1QlztxJ1lRWpa$?`E&^gm=YvMIa+z|Aps{8 zVA@0{qi~wv6#)Te6lCt}4k!e-z-d5k_0ry|^OMy1_WttGnfUCbxmWo2H($G7NfYZb zU=6!OmAn)ExNwl@@mvOv#~-l#k^BV=l|C2wiF`El28dvuX6(|d5SGDTF^yJWAKJJC zC5Qv2OnCBtgRjH+|2K1$ZmIxf6?+3|g?MmGyp2``3JP0zrJ`HqZQmX?A%V%v&6bzT z?77Q+x2uP(7(XOI7n;@^L-Qs!bR88~#QM7m1J8CQ&d33{pZjQJl`J>U17kx)Xij-<9oIE<(Leqo8#3M2mAfI`*l;FauZ=CkL@4O?x|km zj4-W_Iyu`a)#it=G$RE|znaZ`_zIC7=JFo?+jv0)MEkFdj4O{SQ>g#<%tDN#$P!<1 z%!nr;OB9}2Mp1}OGF(ylR}3|$y@5Zg7x=oZo332+`@IbWPcE-DBHida3MDu) z;+hc624Nf1*+rP}s)llZ68|qQm->EkAB{EAx?+~hQ&%(p{VSZI`E_w|uB$$UF}gY|n}usVGlLOU!9F-~b}FaIU0tF2 z))YIMXPVoeGZS6p=$lzDbsyrNSoyAw?6zj;ER*VjL#%? z{UDa>4p%G7NB^W6>eUOxGB%d4$RL>vbrqVPiPxs%sA5N8sliT`(P71pCwKs(1lEXV z)G?IvZl`5R`12WilG2MPMbvRwhD)=AW!yh^t)DvSKu2Ms`Vuap0+8m9oBFMHuKj=9 zy=$}EMv^W1eSU>HY((5UqrPs*o>zw_Vyvx}?K$n1Y{}Cx{ox=$66A(O5)?>oY1`5N z{Z`g9Gb^i50J&wK6EV}?B7v+T9##2Rxz_7b%wwCx;AKr>q~(cF)*^ZUc^%?g;)_={ zzbDCEp)Y5xNcv<>TQI&TrKUj+9y_RLS<=_tm32e0v0DOI#E6p4A>$5bo0o-;QCYF{ zaGZURl+(UD@2(LI5K}Y&fYva(DMcF9qn$vatb?~$CB>=3?*pDovtnqDa$f`ws=vS3 z_!)O7jZVz1O}Q~DsxABs#ig`;$-2%axfs?H(LX6%i4w*l$HT^}L%W`UVn}7#Qwom3 z{6!#!I2XRupj&8Vu&7&2pQPUa`@sW2kWz}&qc5xn2pb}d!ufv$R1sIf{^|U-1w^m` zWj_?zc50L=!?>*$qW$T-t7Fx4GDFmHRf2*Tvs$IvraXOndpy>f`Vi~FQ*|NWJD8+a zBpR(E(IQJ>5DOW-^7Y$Spoy-@B4A9X-xNKrH-@T0I?vV*H2hlAlm9BfZ$5HWjQnm^ zt9l6qq)<07)7!D_aopvQz*NL!NN_n!kQHJf=o$ z@{F;hyCUcB_zM+Y#cPvR2g|6)iu-`Z=1`>>tlyoTx(g9*L?H4^H=k96bSxxr3BA3F zOF?qrx5nNyZ|g&U=;%*fo>)4fA;RrSHsZU&pr7`M#}uF+y15>VAXm16?od};om3V@%)x(#+fDz8xjIJ zkj8kvXZ%;uOb}d}%gqG&ttpo(-WXtE_R8~V1(*@u{+TD1=Wv%uY(Aq?GfMfIIiSpd z1ti}oZxHZYK0{y&ljbe@{(IN+W(p7&V3helv`p!qRyQE6dU&QewUDVGSuH_c?boZH z3(Kn!Oc&0okZQW$O02iV&+UsEP4P8F3&kJ*X`n}rmwM#l$n?8nf zw5E;LgoiMKTZfE$Y~M_!-?tqLAW~67I21(+cpG*gh{;7kq$ z28=2pn5Xl&U;D*P3cBxRmQKX}%Jv56K;w*FBucfW#fc-4O*GK>b?E8jDY?9BZrw zQ34v1qk|?q1n~epK*GOni!5?95PBvO$&74TbUcCbsm(C9!_W`E(#8x|ad^qv)zQNng4+$CV!%Er3^%nTA)pJDzpMij;T+W^GVc z`6VZv^Z1d@>_2`KVcJGc3&+1`_Jzj+s7TtEa%YdL`zRAb|Jf((nxL{#g7w=d&pay^ z*s&~ex)S06<_rfo*&Ml!7o6{)Q}P}=!K(AT)iy)loqS`$rDE;2=OB!VUYoHFf=lGu z4a!sbhKtUC>u5W1no>$GrRB|0ACNQzck5HFbqzY@4l%gHflk{|oux zx;H_^m=@i`1n;kma=A(;`N)(X7T99)72E!O?Xe*eL5PEXs_*n}Do_rWlFpF9sstYi z!g-P*UA7PRoI<<zNPRjQ3ug{P;GA##`&Wno$uM+ng*gOyQBh#NMR$BoNN zPQlHD(_*BIBR_?d?9ZWW^E#oc>xfMF8BmpZ?F4jPg$TTy<5B(keaNS#eJAoree1-L z)o3CIA1q5kgc;b8x|IjL~z6{uatNW;JAtgoG$F$!q} z!Fa$J#^$ZR?uMukC8Mv*UXKMB8?H*(e-Tawmorn?5|5K1Fd1IYL^tH0c*^4f*ewWq zi0KZGzTIxM&U*m)y28ev|NLha`~eU>lN6+9w+%Q4G#p<1RO3~zKp zui6HiVUuVL$-X`9Sv{6&pgoRs{BYS@<}a5i%jzkhS860fxobYuL0iNUWE9hDkh3d9 zu;HpZy26bzC6{olFnd+Ztzz34Nh`aFeh|}=jh9CHXYFbxSged{P=s^EL;(h<1PUD8 z;(Ri+OGSbm_V7@NjXFfsxhRj?jBstC^`okAAxhJ$$g+ zPbep~u8$Tx*3nd2+{V-+NQdP4i0_W ztM9k7kNw?2{rj}tPXOupQ*`Hq4gDw)pbn2TS@y^ZC5Chft3In?+DqKs(rd}P;WWP_ zHTFo6B(NXp+7&2^st4%=NN?=h_rQ-poTdk$l9$J;MtS7b`tF_Sc2zI#*~6}3z5%s2 z13{b^A%YSU$QwczL)Yf6*6=Oq4a<=*c;#u-{KW_a7(@Twc?(m37?J@3$XK;Yb%*NJxxNE^ zsE}jjm7a8MW_AAWX8T%Kehk-K-R=$^V|i7P7TQTkN2<#7SV*V1>Dhpn=6u4$H5MD7 z|5H-^EHPTSW zgxY12xcqW5w&` z=a5hOBniY)V2|+_-o5H+k-zpg0kDYHsq%?`gr&-L5EGoj%<`LHD_eR~KlwwmR}WIH z(QN+?q=k#Xg z&)e+^F59s~qy|^0Y>9@25|`)O2|2K<(D&e^S1ECilcOL^rM3p@+0*9Hr%9$E5_Q#0 zM55+Of2dAosfy(un#*}eSoJJBn#1TD0b`cY<~aHP>CgMk8zWbpD6a8!<^I$x^frqJ z$UyP&5JGWnv+Wnq9Rn+>h62~H{>KtK=68&(E2Pc@Hq}I@3{Vkz9j#LS00=B(w-|s0 z3ADYPvCF|tqE)!Ho;b5o<(L$Fs`=RNIvwwY&ESpw&PaL+wGnrKf6gt~RbOrp_ek0X zM>V$YGAehj&fcmA{(Ud zrG4e7o_!;J$qO3{XI@rsnzh`kiM{>2Uj1u*=>EAp?~QvBv>W%~q@`Ng&Cv3`(-$Tn z_B%xlEPyI5uGa^jHE*`cG1zN9$$6Mx$wm_8Ysy<{qj>TMcSA;6x}!6y(Bx}uw)>%b zcUF$#>dEKoT0Z%g`t;sKva?z}G6sE@$FkjS!R_-jAzH#rEtzg@L#&_Qe^23Gqnqh> zDnwECn|<4#)e6_yZb#2>F)}s_zn`)3L(V6}PZzQj?Q!%ZkrbUFxY^!o(o%wj(J^A^ za^VTv_>SRYRiql74+_=dSUw`fNBgJpuKiHoo;}}y^?#5{IKd}m9o><2>;e(b(59!l zg>pQWOIJ9?*x+$84tBPH5N5<2K>mM%9bQ*4I|L6$c%|sV=?eZs+`X~sSfEpUCtbNe zb(3MOeewtOKL0y3CJd+g$t7z<%9>vw+7E}ISQ(LkXiKJ3Aab%#{^44XLY6h8MX)TvQ@XJ$x{Cma>#k*b)}QcyNz z&_sO@Y-v9?dL)q$$G}~#}Z;1AfO_XVP%q>F7&xFDStdfmEh!0@}^pZ0{L_-sXl{9 z)#DMOfkLATD4Xka!m{6PjTaEtCtoz<3A=T(w?tG4d!#I>xglKOsNarx%QjXOf<^lu z$0f=BEByH_>pvl4WZzotF;S`PzhbE}b-e$0CbF)2`qey%vj2)d`Zm#t!i34bjg`sJ z+QSb1ulQg|#?0Cj4u52I%ssy4^$-2~(n=CJ6RwOp*DvGye$NCa%h}r^?Z}wo>V4ZO zFZl$mnm8Q?e;nGMf9}=Rrajj=2|r|8t94Hph$j93l5Rl7ZU=JJo+1dBy5Y)2qYy6F zsbg-Ig|2y_siH0-VisJVXcQc+`J0PiYg8`^e1!8(Js_(xIv1lk@cO(9f;1OF(gT`G zc^G6OX!?bdxe&2#Qc^e_f^|>Eav+esgl;Zm#N{=pq{$=9+DoeE78|W;6tbj8uBK_x zd;y)V_NbQw0AI;RQFd@jHh|9+70eML+mba*BN8ITP=`z;D0ugK{L%DRnXCEbmoYXb z-IW|5GJ3K%B1VQ6317jx80ZLI4E+xDr^=Yo;1sVB;Uc3mVh5+NGl5oiGNOo&BEj1d zgs?Unu-$eCNNBkCVM=twPfi9$P<|x(B$lb{ym;XP1oii;r3nu5a64`bJ*UB*C&98d z^AK|N;0Yy-RE<3WB6mg{kZ@PV4m7}1Xw@xSvqS+UsR2#H(}*z+vr*1j+Z7S3BCDg6 zX1FY!!PZR~`L7$jKuJ!ke-^bjhNGd9rM&7chyx?=;B_gEk^@yqW}{uV(j5>J+%0;F z=x9On>itglUbxtDdbNaENY+Z!p|{Pd*{OKWKb$4xs`R9aGpy>ep!U4TQlaknO!%*C z&@7P>_Sa#^j)!jF4>hVnT!q~fM3B zb02bJa}n3}KcA#cj{vVh|AzM>>wLM{T-7#TqBQ1qVtgv#ZmDscsW-=1KOkUn+EY`% zLyha|6*#>*cgObp!Q@Re^b>B{8RQgLRa&?^2XnI8Gl^yGJW00gBOzE1s4=?C=a6xZ zTYWaBcYG*{eDh@P4qDL~&*eH*J#H^i+f%o8aj#CftIs&VEG40hPNywE!izOa7P=g_ z_$x?8Pl7S3*Bycg=JtrJNuMIDS+j5#=^9WoZ*2n7%9~)WLKlhf{r-+R}Cr1C^sv+pi$Et&v_#_o@lbq3`c2Z(>ll zs9o&a0Ti({vP=I92GZNww1I`@hlFm?crib#Toemzs5`ob?2qmVj0Vh6ipeK)47`5( z_HQpPeFY6*L28fA z>B7t&sn}#=6R}8SV`Ozt1Vd50vU=aB2Xj>~&x=cS6>Lyk+JH2lYKC?lg+XU_98F-D zG3_O5=a^b5r$oSEC7C=}HvaN;dn(GP*+l9{t;91<(OFiAaw-wMAW5eDY$s&qNb*!e z3qb0n9rmO^>+Y>opDiWUM3U*k5a_MN_1RT>szsW^3%&Z3-Gq0)QHOg@tC3Wj$r8bv zw$RKl>=If`?sv^$+GPZqnI8|9)<|GA3U(>L7=zre;vou#6FG%lv&kXKA3t)R#v5~t zFAv62z;Z+GfJ~ZcsMBlHgCSS?<--4$e^gg8duaAem!JTAA~GT%2NJL}f^dt+Pem^^ z6=yFOQ}>^su1KB9_-}_k=d$T>$15*?sXaK>&Jx^F%jk|M4TU0@H5LkBmi8eY4|GXv zd(Qn0EISiHChY9?h$UF$Ntq5$dY+l-fBZ*uE7BVGnSSHy^XKaSq>CSVbZOHUE5PGj zz(4wCZ}DI47P$wVmWph(rq;?pD^t9TMy*0Cdhp}@GailZpWJl2B;mU$? zag{Qc*a#x9*m@NdU`bK}jgqJw+7eVhz>cBEh}5f69l>)@Pd@9I8?nlCA)7t_X*MI9 zEPYDJ+2GbXt4Vi8EQ*GHm`UPPo;d`!!4MfL|IUG6s0skoYHt1*Z$vQKATRIQ0mx1| zjnO={Kj_C>tE77M5cWda5$x)0|3T?na44+&zjXVysWWRebwbd>17c-_N38zsxAK_V zHZal|f%(UerfJkmrYf&iujhf4>u=Q~*$j2GK!5+e^Y*b|6QQG+*M*uGP^anKkdc-V zXSDFK{;FPdrz5M75;E3jeZS3R7DOW~-GkD-V6O5!H$W(Pt;frlGUmvuw}Kjqx3*OiN-gjhEUbqlCAib4Nu@NCSR40&g8Y`{L* z9S>7lEzt2|gN3eu@PZlFelM+-2}<*k{Yq4q_t1B>!%>G;?`Y3qL5eySi*`|asv&XW z)*W)#9%M^)@6H`+ao254j*D%2=GDE6<5mR^J5-Kb0-DLh=BoYC$(5)Wi$G@OwWf>f zN%N{mCiv}!`?~QjLBW+EXNa%|^K4+o&hNtRbtR`x7WIin#(6S(r?L(nu8@`UZv1suYjp*GJU7f*@2pu|wteY&FK4}+ZVT;CXIGmd>0|1-(Ie6DU zEr*`kE^Sb&yC69svvq#1E|@GjNYO+p%Gc~&qU$RqTiFVq&_~3l8AXElQb=pg#F#$8 zzGS*w#-^Fw(y>-V?n0#(GE?Jz+rK})?GQPFoOCXI&_i@4*p}QYRC(;TcWtd6ns=$Y z1PEjJXAr&d{>|F-i9v--B*dCaa*c=u;L)7z9k|2+EKye|-jH@Xw!Bx!Z09AM!*(GfOcdiqg> z?l&Oy(NM`>btTVE>Lae|dJFaaxf%tu>?09)oY${?BcUf_^OO_NRQ_-F7G6qUfoxT- zF`b31v|9W^z$5TjPi>!iP5tbXC_t5rRhYBRaAp6=3jq6QT&#;kB zx@N^EZC@_@oZ90Fv~;|An;>J)0-1nS)V4pzb^c!ok50`|2)go5Z<_;jc|+U>pl;rZ z#c#c@srT-|P1RR^v6@%7VM{i7^lE>KpJq`CWt zDWEpHU8CG;py?i3<4FD7u7pKe`SJxzcGezWyp2~LE$4gX{OTg6)!=o|w{o0$-a-W8 zSe(1H=#vWpZ5l}n(;F;$+=NPiZ%eAkslk{ zq4AH&V^ehD)qZ$m{$t*?lAnnp0@{m9?1fQt7oad1Xj>4wU23NjnDmM$zi^eMh@Q`6 z&ALsy2LxIhgK$&0aSpwWY!K+J1PG7XbzSXKAQWa~`WeB(xxK=n1e%}(76|tR-9TWO zH$dB3xjeez>cXxHmxN4O9%-t$>yBs85NI!3j+mL$66Bdu>SZ7PJ~Z8MRmW#!6xsbT zMR2g6SRhkxjI9u!?ZK(TUY{2`52{4Vpx@r|%~yPS*(Gm$s^qlMDUU2%;U@s3TBFHt zo9$ZfvE#5u2@5juT;CBFD%?!IvL)x(phlB%$kRmd3!GY z$0e$IJ@mU;d2K43JCe)w23}-~12vCf$a9JGS^-MHDWJ#y9NXYG_$yIh@Rksfo&RKPVeUhT`bFg;3vzn`ZnC zwMFB9mOT`tC~5tm^nj-1AI7j7F8RnlJ9mI~G%Zo>e%Y@Af$*eUO2!aMtGN1Tq%}+t zb5M8Te_W_;oF24d`o`&h5OQ`D#+hC+D@fceb@}ZY;bGeDXvnxwq3f#d_G?mvHh$P> zQb;?o|P=BI>a` zP~S#kN`y+g_VTy)`eI>dTa@&?PU18*B*z@_gx9h=2DF4Obv{!o+))B)nyy85PN+=k z^8%=ukSPifNw-_g@XU4C6nyiMq2R6HgV~o=JrT98P~;u=_QR>&!^#DX(fS)Nf&q^y z7oK#uk7V~ph*@L7Nqn;1K=fj-A&j@Df{MdSzy3c*yMw{7pF!W@Q`W=cggUa`q`d`=K&l9Mq~lTBORKa1eJ zg{`!kc1ja1$N7?i_4`(1G#nTAl$td?RgBb*Kp?C6@iBPKtj9XF_-CX3*{;gqicBn2 zH18LDVF0_P9^3P(uW!{pNt?-u^ZyDY%|uj6iV%Q{Dvh;c9@NvXR_pw1eDLtfh@#0j znG97xEW$*t0$Ca_Agvb6p{LW=JT2IfAll1#N`x~jk@rWfriepyDm;(nq=~UA=2XHx zPOElz=uhn)3%g4Fz86j@8YeleF-)L-lh2eWlQuO)S}K^p$6xns&X}A+Fz)isVTgh9 zXm`glM1BC;H+a`n+0Q7-CyPIa<(A7fDEmV-4gl!LPGot+yiMQr1JZkNR8j1MQW(5P zaJ*bI{wO*RzmBq*Frf#`EX6-G5e*Q}dPiQ$jrznww`81@{Rg3j%<0qEJKqHxYPd;AFfb*hJUg9cJ52?$L9H~mkGZ?g?dZnYhNU|_(7yS|l zr#-Z`K+fb~xjHx=F5LE^je_-Tq%N24GjVztfd=ZcqI6t!hfJ^Gt|%xL6;_A1&9Nep z>ojYxMiq*Ujo?@!lIkM0s+gQwsF?QcdVT$k1(_|~Rkqu!AZxc<5mBoFw~h?(cz-;3 zY?Afy$V+2>xfhc9YujxLTRA;6+Um0>$E~z@fjBaDH|gjOAaQ#hjAFwSBs*l%&I|BE zGBjJ>4}#D6CyADsk`0^@W&1Es|_&{0z4zA&*->%lpu($^2 z8CLto{@t&uJ5K$q(Ij^J_+0@p^tRDO)8A9n*(LJo#9|fes5c!+jN+*3CK$W1iGY1vpd0NFEn z16$a^`5uUD{#$SSR#59B`AT4Qki{H7mq8*fHWd3*b{XJ+}Lv?obG}MCN zTzg6UU;ah54BA-_yX^OpuHs-b>1c;vyV6^o+7Okua!hxBj|e=XXO4a&?Jr1COBg-- zz`eoV;)o8U__VRv*%ZO9Q|sd@dmj*QJ2)drmW}Mw$j3?tLIhKW91e+x-C&dI+ZI>$ zi-Awk=^XB4NZfrJKJ_Z}cV7<&``69sgDlY`vBHangJ%(&7O2W3NehF-oQ_vasaOPi zHg?n06b31lDjN#x#dsnqWmwE1xkUtosy))hEnMnbD>!B_GHKl`Q&c2I@cISAm^Y9? zXQD#7O#-Wz+x5TOd~iR|b;aT`^H_hL$_(MzbyKYc(?$!D$7{~(1BmjoB+M&M=lXch z#?)n@UXnpncWd$C}gj1Z{gY2Q`ga@(gY1e#~F04c%l9#d#hBK>}ACkau@1aMtKA9%Xc{Nje z@&}*z+VwVfP7>fePPh!PhNFgPNSqN*gaUKWYg#MhG^h)t!A@7mN_pxIL!Mz)kh0*q zpk9@+o{ql}MDNABT-w{PK-j>Z0P)ay#^!5BN2{y&FW0($T||08L@trU%K9*h!X~OJ z?)b_v!Hz0W=TxV2qSLYF^o4TMhER5v;&k+hC>ZV9&P~^lKd10mfz2mA3c}hCv~+!S zGHy122HXqG+l!8(IqcR&{q|{&J2QzLHSWHrbLly5S@$NL{u(_!bQC@cY=ReQO0muIj%9`<;qp z3^TOjfC4TmhoyqStTsAfVz7^dXXHsI-f_DO28`1Q8^ zmcC-<5LMox;{}@(+|65*IwNx&5bw^0_iN+*23s~7iJP$hB$=svzfwG`11Q$e>)i}o zBF3tzKWF4B*ZN2J#dJ8ki`rezNIo#Tp$fJ->!*o9_I$3hp)MdYOYJT-X zgK_LgziNBEfF?>!wE760^sCkGye(rgFvl7)16NfIFAb-;)?l#sL*GwaOe7{ijRo>; zI-yEt-gdY#`3u%Z93_kpqYM)8m>t)M<|6RjvhRl#yh1H)<2Db(4;C@^3bv=x3rSA0 zIWX8n*+2}kP0sQq)OHAZnW#XCJ+*0YAX?=d8^OD85stv+tHknsRCyUGurO;eXh5!= zSk9^vl|jOVlZV!gB^7)VxS_Wy)fAMdZ6?C*j9=L-`@q{jMU57pSVcm#`f|Q>B}FeO z>UZdrhhW4>Uxr$uKb35{sQ>bO+5=g^f~VX=Sp79@WU{KDIpMkH6l}Gu&&vLt^JU%6 z7>}JT~OlN?s!lxTdUdu+-pYSMrH zi8vN_4@i?dVj-BadJ!H1Q7{{_hARAY*_;%l(l(}qK-p?X8?iy{wE=^7<(uQ4Nz*tJcrO5?7FVi1KQpB;!L2s&xG7AF`Y0|aq=Dx3<_N* z%WZ!|a&lMdBT3j7tN*-%vaur$+ClQXUa0{WtHgYhVV7>m;rCj2fpqux=tp7H94dm&VRr&XH zOOAhA>9d)&kM`2&zQ8(Wu>&<{`F}{~Bh&&`E$WoUpk-49{r-EJfFHg0uG(2LP{qjZ*ktWAqJD*lE>{D-%X_s$fnh=~qu2roUy3A;@6^q{hMDG(;ucZuoy3N@dv`PwjSp?(bYCZ&s5}WTtXWKFW!~ z+ojj0chR~=PFvaXIm8WgizGtyI1u-^YOhSct5s(9g$FSEJD)*b#@*vbt)=wrW&XnoTlnhdh%Fx80 zxcU&klzC#ga>ly&0*+ADai>~?MeO8+y*d@6$rcdMLF2LA@;rgX6fLgvfNYAEDooX{Y&l^DQ(K7Qniamh$|fHTzPPuma0K4AniQ9O#@{+#QtY51t*`eh>Z zF95X3qO0$lbB!TDF1fhv7tQufb806oYHH!ut=}2bkaVQR{T1o+huekBu8K zD2F`F4vh=teE7+kr>IR53Zf%Wn-T8e0ad3;_VZ}Ixj49##u+T56h5IJl2z0!7 zBb+vHcN%#>950MIUZb)syPwHM0|S*HoDh8^zZSl z9(N*0F+L)90DIA0iWumY&FOcEDh1T?^*`+&3DTPMl)yMNe2&)~3~T^>fj^LFX($1$ zX{r06-CmQ1He=Ky@%N|mu0G!HY@mP{Sthv8Swqx|Zj=SBSB|`00lHUO`4S+5!Uzf6 zpyO~;ewefe7x8W5t(chNo3G#rFd5lPQ@{4qgr;nq@r6vO3I}VoZ1#tC@6sf$IAUIZ zU^R7RLPt+^ydKePN;fz+H(glC%x)_A?5;V~@723RV8kzi@2}R6^8)?*?{W^rx+Lp^ z7X`p(5$G40vTFq~@0Spq{V;1U)I3~`sZ6`isd9?!%j8SM0eCI#(!`{*3u$VO@peC(iR$J z!If#={Ol8CNdsw-Ethj}Ni5*RS3cCbi`2$1O^#*8$fn2C^0dElAldIH1dvP9u?N)~ z-BxqWaBsvsmJ){ER z5-{?2HVqjz&VdFL8|*fL51Q-3i(d7e&e!d#Wmi>2NmIKHJ`Gk5xo)2zMoq0s>+ z_UY74^X}YB(qvQly^q?Gj>;f)8;=EZL8H01dk8F6ueQs{&nY$lw{^R$T*FJPvqj7H zmUcpaJ7A;mSQuG~mp>?{fn74sLZ#BJTu%xqZ*p|cCZMXgVncSs<+cKHL6i*=Q zpiCk!9d}?5kQ!^c!!??Bsi}~=x8omVLRM5>ukRuvqJ;G5UPasOiqxB24OYv5 zRS{g#N{vw^6h=tZI@TWHA(xO6{pHI)YK)Hs?%OJ6aWA)!jg3PwF%xS`3?BJ|K=`hd z8u)1-8>knVNR^d_tO8)W*L!>9Ng|V?Z%F8`lu~tcVINA+vr7n{Mj?Sw@L12hXfw=ch z?E;2vY_Rp1M5}{}>|djcAMPRT;B_nS>o5Np4tWI_V_!hY+@`3663(>IbZ*YsUWeDN zwSeBt#P5g}>(^$n7Jn1Y>iI08R6im9(YI*+wsVM{-0>VAvrRC%t#UEm`v@@G`tB3L z(y1JP1fIMKq7As@;WYHv7&Hkqi!C^eue{m!KxYko3&0PN4F`=+DMMkBtBNPal?ECK z0X+=~cfrRsf{W&OEe&AO8L;aNF_LXxJGF~fGw zeSdrZrXEb#MUTo;Jn0u6 z$W;OSvFkpxD{)0uzNqWt9_NzdZR4%WI6#S_cvR;O`~LB$?N&vs=To~HFNu%_T>|G3 zm^+GqLaaYGwrK;EW;iu_54HRmT~Ud3Jjv;0?YKoHWwt`ZFXk5Sr)kGdTiW*5lZ{2o z*ACzdHEY}$TAg3T&b7;TPVNaAAE085A>}K@^_B?th_9jdIa8peA>Xpu_j`>RcU^Km zfBCxIb*reEeWX1;Z4bOs(W3Y4e5S^TLe#*0oB0iq@M&|}s=#;E0wnLCPoO6gDJF}q za}l+%;02iykaGli3BswH{c~sMq?q7tp@S7Xyt_rqj41kznQu z>K+M(nGuPP<*kZw5gX&RlQhhJDplju6}5!((B1)B#0dPg`(=;V@f;&$`t_Mxxs0VA z$0if1aiyipNhQvciZ}a#KPX1DjJ5?7^aUKPv=M}JlHm%;eDOX3GoANsr|!49b;l#o z#K5^|Q4WK!Ud@!eK!bnwNn$2Ko_bX0f--UmA6b}Q)S*?<5gMOXNsXZ(D%$TdzN^N` z>2+-Q(A@!p!P_hQMci=KGwOz+-L`iCQ^QKc=sEaR1g>x&SdW$7rbzrlYQ7NToCTgUo^9jiByz@1u!Xw+@#U2e6Fs-B) zA_V+4-S2DYyBJo)7tpusI}wmo)^v$7$N8Zu+k*KW!DQi8&2Fo;+x7k$zMJ%pCznk& zfSM5>A_-8QoIMm_$>RycIkGW1wV1cfNyY9BU#*HMAIbS-;qWPme*e>Xqe3Uc+_Gv; zjrjVF%7ja=C!&JR4K)EpExp(O12UU$g36{VTeB$aUd0?oo)aP(&)-=h65Ui+a+%d6 z+Qq&dKpfTb)ES_#Jb(^2=@1T&X*#bH)t3k#LlwC$miWY@=Swk3fQ%@uHQun=?V3$n zL(j~h8>R>4d(&}60wrs9h$y4ZNUcI4I0cF-4e11%0#a(KH|R&c8Nz2AT}(5tWnC~;CEC^1 zp&Ks|OgmBei~Z`{9ozE<)7|QwbCHfjJO!heMK^7va$s!fU$;TZ#JsDuY}#a7m^A&8 zLUrp({7`ej+Z`sNl=g;$FqAidTU}l-~=9A}%J?6@zz64v8x9Pz}duRg*-G7(Y z1*pMvH9$QeyTb{wcg&$qV$fY;vqB;-nCb|LHpomUFD#K>vn`}q0p`8hMax93p=bcR zBcaTRac)0GjwTvOPSI%LYjqEiJbb{>m}2KhQX9i=3{jHP(qk;@M#1fbA zH%Q9nHin2_Sp#(RKC2-SwM5tBne*J)_VpfG+^}t1l~}D6HRj+z>hUAjLQq)Lj$Lmu zI&EeW3#zz9h{s(fa9IM=PdeVq`fWxx<-2ICS?zW8D!HCAp^|;ToW7YOa@Wy zh#h2>J=a5Ai@QcCjtwIN>pdv)Sf3B-)vg!)*)!F1UXzjcDq*G)2vYR0|2edq?g-Et zfNw&kQ$H%TPKLus&2s3~K+oH|cH1kf&->+hXQUa`N=#1r?33z?KjiE|i_}JiTYFE% zT~bqeylT)ky`A-289I2=A zz0C?&sr%EKS4RE0yv@c7dKWHT_?dE)z|r5@rU-4X6_awb%Ct zZek{}!%wcblB(Ol*fW2jr;n|O&OY=-cH2XL;$UVow<1jc=sst!K|B`4_uKJiL;M|i zs}uDa$rOeI1JAmOjC9k(NCi=URw7zljP!QzM>L7DLL&Kgx`J^G^5)5>8-EdaaQe&5 z<45YVH}0px-(UVQ9Hk#2IDPhsuD9eST+f?SC*?@Q4QQ*QoaVZTt}dUjK1d${Q>E8T zf1;m8`U8mJs~ZeWF*nkUyoq~0q0nUj#YkZ$QB+edivB0ZK+gp-BR+=29P))XH6QYY zjAfn$IVQTk_&!u`ql%&wUa( z5V{RYCp^LFzpNY~*-F(Tg1|jSHUFxB#2Y`Q8^iMqk-jiXT#I-h^dZV~noMmywA(BV z6&6T0`7!+?z8(%Yrw`>W-`K!Ow-2#QM8n$znZeg#`H|ls{xqKDN4VWOta`8x&0w9n zaF@1dT4ckLu)kkZ6@=TbGMXR(eMYpIf7K@}R(F|0k!bFDj3)@6P&XN3fC;$)5s z>S41vwEI;I=*dY#f9kr?ZSK7uf+A+EY^)kH$7|qe%EzHVn`3j=*4qPFjK6)UTy#Ud z=;HD}>oUeGQ^g>xWGbM9f`^R<(#MU{mqn!#GB>mYfBVvU{GPy(1nOiCRYY-SLcP?S z#1gabhG#h#;jI()`IrKK`jgWlh%SdW>eV?LG)s1+n8MDDjB)8GF>;p zc2EM8=9x)-kI(hOY@S4^A;4&_!_|>M&N>Dn+g0QjKV0g~l%t#~C2Wh#NEPc%@XUm{ zRTiU(@i1emin1zH%3MX{`40ViSJ`G14e3@jOY-1Ptpt9DxKqvNJ55=P@HcX=e73xt z5D274PDBLGzlhOPwjXDCUt2Aw>#eg1(?tvIvVYqS`_QUu`53<8zQ#3v1C?e{3D# zjaOmA5)4X^MOt!^|ffPbwjyM z5w~y3?XU^+ZQp2=LE?239B4IGfSLJ$k-tHhf2a8oKJ9L%WdV8gbyrXF*W0sN){1VL zRw;!wP(^0uGXVmi&EIys{$;drsWc6AErqE($VFZDA8`Kt zx6KVeCtH1VPJmedcb3XdYaHf;=x?m4<5_}pm2UNW9A(+#N0xkqe=(uN9l79a662L_ zH!eBCQc?*SjJ#k$%{|5s4)x}6Xdie}W%u_5d4c7eaEJl}*{qe5~?OFmi+ z1wzDd#avTrjCAU0rNOjn0SX$@9D|JeNv0x_WAh0-GHF^#B9#BPcM~q6AtjB{7;KfN z8I7M3v<*einr^!Ts!q> z7g1uv=v}Y4y4j)|-rn}>^|ho&)U#=OIYOHXJRXv`YAQ~^+R(Md5OBMdZb}K3-7@Y( z<0R)73B`%;l_WkV`?^GO&Mah+LN;pNp4tp9ieuwuaFh65-kt~b>fa?~Mzffc=;V0a zuz4O$qc7m@WMc6Q{EnF7;5(tAKsoik=s6N2lcS?BITFk(36TY%Jb|w2$Tb16TvBSb z(OGE5iPol6o)L5=OiN|{KJ2{ED(!X}w;R`qgi@97KDtPfd<_3UT7*(cKug$p(ff=RQq~XCNJ7vV#Y#xrc$E@Ea?b9eRr`{_59^Ye$&1UWHO2xWiv!cx z4PSss&H`V3&#gQ0@<%h&O~`klqtr>YB{7^x>J6V+A(^-EsNOYO!A&K!Ez==L?ODaz zYW>^e9zQlx9!FX(c;U)J&OsC^Poi5;68*}ydGU$+3F^64UYc=4n=bSsLk0X&Zl#26 zRKJdRmQ3bO=a%a`msK(3shjOFpM{;7u_+rfO3=RD_wQY^_xgNHw$#du@tiEhiGkW5 zXz(gOv|GB1%Wca!7)_4hDL;qG^)N@Xko*e*ICh-3@YDCJ5V%ibbW9kj7^P#gT4fv+ zK_G`T17Fa5LI%#Kn({(9LPKyt9sAUF%UjT0_QA{d&8l1G{DyaM05JBlGa>mx&NWvS zaz&Kx1}#rT!HXxM;g%{)r!F@{x1DmcVHIvIe~b$dN||p`1}e^hV~QNm@_jVUoJG^^ zS{#bvGOZ_k3r|h4mNBE($c|gZbQ_ccjy@QnaCY?JM!A?mI7uqBGtzzcK-jkDKfOD5 z>QcA+Wve086W3*b0HnP&z&TD2riKb}q;k-pRDoJRu9`r}3?b)I+S@@b`X?cu`hBQi zTvg~YHKN8f(K5uS0_H8i18SegL8;)m41JPGW&{okTMX_2(50uJg=IeD6TFE7JMM&n_`Gkg>u^a1_smS( zIq5i-6v7jd&5tVy<3$A5u~9vJhJz1E zn<3T?Y_te}+W8R8ml4>BLlpwS<~oRVFL&*zB+L`E~oGNGR# z7Hz*0s>x?Mo<7x0MXJaS{c_Mg6 zeiCoVPveiC*ndBj>gwuKfy&dK@kIR2(zxt5&|pA%Dz7a)B@Kegf23`^SsaxQdTNc% z)8*A{$(~ftKHavbrheCcI8ZOe{$~<>9Jf^o0AxU$zuGWK_Bg4#AjmmsVw=f*26Br5 z7G<(*H)aa!`mRL;k~7HysFf-~6R}l^a%Vr2E18D zzjFcQjsZH*|esKf*+w1$|DdJj7&d?>oiKWUl_8ME}(!TFbC(8sv+63C;yR(JfK~67$G03Af zxNY=)ar+aH1F&P7W(Qx^G5t zFhEu2Q7!CXwUaO%*t@n!zoWK$2VL>e1zPBBQ zFJMr5ILhX*ZrjEE@wUCIPt>)Y$72|oquy=o(3XT4-!+Fzq6|2{IL=VVS~p_9emG7Z zZ~O{4Erfv?fj$J4DT$8#fshVJ+DhjAuu+9t3_)hfH4(ZeVSleHVvZT*>*4U#q9DS- zI=ZrHxb^${P#QyICVG&N4B7U_c2#Sz8d5lp3fI>Xg-8sTs#uGC&P8+*W5j?1~z7 zvc>L(KS{$DI9d!`KU4_p>VZ)s>F?$($Wm2uedXoOfp=qkm z-0ETr?S8p=BCS2I<<*FM5+{trQS=J%@q!R}tV|dpvSQgZGesZGg&!ptvV3}(BauS= zUX8GZQ_I0H4oGiehzPzHl~aVJ$MP`-P`+%7E8gSVdviQSXO6SG`1b7;{UFAD)<#`dxHZ?gNe9a5M8uBA%ar zfw!7=k}fEuLo~hn>rPR8K3*O8ggK5RGx1Oi2aUDIS~6%B>LU6InF?Ir|hz;~bq} z(!O}iEQLUA%%i1z&nN3A0&tIZtCsbyrVMjoXki5o&7<;JRzQoci&N_HpZBD@ zvmFAbUEVq%E;CpT-~H5eD7a$LZyIXHr}+`Uc1<_j*Uc2oGIE9p3w5ML1cgKN>}Gdb zN~UrCM@)MGT%d=Y6N%*p9zZ5Tn(eO0Fg5WJDozS0sD-+Y3y}=bx+1yz;eFi%DIz!F z5Grn4FK`QmW{-lt@0^~r+IZd0XuR*~^s$|2+qc>40iE2|nM zX~v^3=k%j^vYlz1WT{z@gU1dk>QM>h3Kf;TJ3}{J;yJpv$eyhH7{&g7uSva!_()62) zAvd8*Rj%AjPf0U-6Ef54$DgUHyIog>_5EAdd1zB#aN$5Ems!vmX}_wH4cxAfGqy%{ zZgN*V?}ujBshxclXhzuW!mZr;cHBa)&In-YNJM^*4fONsD#P;V+4nYpL+7gt>+x{t z`QlxQ-^%n4**Yda4{r85RN!AJzpmxE)j0%Y$c_ZnRx6(NY1~L`$^O^p{?AWj^J*S`09Sp$d>F7$`k;AA`x82`V*O99 z0NhelhO74J2xG)`D__+WHEJlPk1%ZM z$?$*j3OO=FGXA%9b*-}CGF3iEJ-L9$C>+Ii$>1oEu z#&~|wm03clf9c$={2Avyn2N6sqG>B-jYq{I0L~z_!GT)E@NRn&1zi z<5SKMv@QDjm`i$(g(KuVnl85((BO5NP3{eZ5JIRU2OQM<VFd7ATQ6K(rqMy?BHiH`D=MX|y{P z!x|m385=;L=6Ia#J$WoAFG0*g;Q~aW5KzK0iGhoic2N2aASm8cpcE7j8{HcinVQ7mFwMf6f<{=BH)gqSzWocYc#a`vC$ ziB(rV&8}kKrz_D{(($tH|C{JdD*^EvI-mo=Ab7gKnbZS<%?gna3Zw&O`>X8};9i)l zgel7%r^HOzVGks0D$Tzd7dGYjZ`2hq{yW5wSuRfp@)jEu028Bn%+|Pu^@B1yO2#Lh z38^4|u7!KFdY>{-^KOZDqQBgfxBBdtI75}R3BK`7Tr)vxp&^XsunE4knX+rm^B<5fIaJTsHN)uXGqc_a5bAB z;@|Xtcw&jt%LZ2mDEs2!!0BffM55hf|0E0)=C=U&lEU=fsOztLA=K7C#-^HXg^29J zHm)rDW(d2*k8!Lv>MeoH&{4mez8pU&7k#kYhEp4sC6l^ZkB#~i6U16wTi> z-?!?IQ@#H=hx2>}r~SEWzcDBMRi9(PmhO}Qxv`p@ZO?jtqdLe%>bImKB8`e1uvE=s zS{tRQg5+S=xOg$SdNBgFrsWJ*es>fTv?^$G0pr&elp03pPIxv>2Oc2JZh6lgq6X8LnscB#gK5}-Z zGA>AR=kVO=gBbOX{?y;@kNqBkfNpgmng+`HK`-ShRL#U>RBN&Og5mNx8Po=JvTGnr z9QyqRG0OSL$5G{jQ-wOjL~W|kJRQcfM%Lwj-YuczxPG-=I{)8YZaL?bNL}&6%-&e$ z^Qj4+k1&7rT8Y1+N~?hIzyf}c&M&|(VyxNZJ{0{roYWG3AzrO)OO^7(cBAxV7T8%v zR)$H=CZ1>s5Ak;)jeh|N8bKCHza1@$ITkdJ8lBB`#<?=nSOsR;VYlm-L~x1f*g;D z!$nHFUQS*fBj@b`I*;{Ry&9Yx~wdT%Ef=8yTK(WCjk|ePzHTRancHB+X=@m;Z)T{Zl zLv5tdY!U_ghE`2(dh1lia>bPDJWzJMCS7xp^vWD+T`t`ck5gG{U3{c>IC2TfQkDhX zN87H>z9ghMa!63B@qG*3C&jp|GB1F7rR76vxktcjq2;Y_boolxaL_tB&6uv``Av$k9y50n!)J z{^Dz<@b2P7;9M+-V6Y-$VFUD|ZE6EQ3d}}fpD!R)lWkB3g6|rOE=>_N8~MVFR-6^e zzru)B$T#TX%Ps1Im(L?@zDg;CH>lT!bTMAuI+Zdl!oNa2J~jRvC|`O&1mVkqBCmvo zoCJg{K|ktdi*D`wF&DN7RmqZ=h+0Eo5azalhEM;Z-e~e&wZ2$>_?K&vWuN8!#wutVUPnvbU!V% z9ms6E4XwCU(Eai13(Zi6Y*dakVAmY#_iAM)j_<3bk8iXyhW_m)j65{+GGT@N*Ub82j#^V$D)bZi|}0r;t=4^mnrIDQ&mz@PhzRC!~Ye6 zuG?3}%}OsZ)(=ZCUik52Yks*qs1R(~9sEXzGjJEA`5dtoG0qZvZVtQ}Ki3_^mZZUT0|O-BdSWpkqr?YN+B@o_dvXt&$$0DQ-* zCx569-M?J2sHLp=#LpE^6XD#*AKSyxemm&Z?Bk z#Tpq2+IaqjKqK-s!izbgeOq@7#{}WvYvk@naYBAWUj5spzJ_SZI~qf~tJ~G4{auP7 zNRxKI`8#V0LSc$I@42PU2LI0!d}jd3nsHhO(q?>!Jqu`oELHa#>E0oplQ@WRw%t6P z_lGFI9|ajOPo^qY$7Xn3dCQWsh1-XfV>=P!;`0Txix(Tp6ithSl=8bKS8GZXQHw@0 zGyU?*IjIeO`)^9}8eTbA#~0VeY|{7Uf@M#d=EsFs$}gI`Vl#1F2gNwyvA%>`J+@e7x!)nYSFbsEPzILoHgk(}>i2Z)QtteO-OBW| z7|SkLQX$axb0U!4J3vXOtq6gtFHNq0II2*@+7(b~HKH9kbQ&K;<_~qiJ zlCKt^j3L(o(s?fKbqqflu@WE)5>BlGVNe|LSz4N!sgdfWrc;iYlQi|JGd3oU$8f1r zcccRbb?REF+bF3f{WW|!iQNDh1;|f&1V}8iF)Zo|Q#g@*EV&PEDQ6Si{1|AMdsTr` zWC}|O#uTS523U4lGdKKQUUehNE0Oss*2hKvwkca5`ULeSs}aPm)1``1<3m*m;!jgi zV+)C$osGES+ZH7RWdju2~mcK`;qqfow?BFZxQm=JSSL}0_02;k2>*LSeRhkiCx zz>f1XzaVFMv|DdfM?5unmDUu0##~!p73hXRxes@ciPcUbh2i~{`V-}uRu3o$f=svM+(j(7zh`&Cu*d zL*X5qS^LSFO2EOK46LHka8UnB4H&Lzf9#|iJ@Eg5t=l)OUZbZXKSWU}SginRS%Mtn5;U-J!Y(92lJFXH_=|1d zXfG?V43_3(q`9E198Szkgx@$*cBby8krh_ziSy3Pvj=ZsGfTU56eVVV_~dIG1LjWBY0|0vImP{>+zY_(3g`K0rWVB)Xt(EFH`u5 zaFFAyc93c_N`kR-F!t!CJOpBp`33ZWH5`P>`x#ozuLf_Q=36{cU9fAVGYZGc<}|va zQKQJvfcXvj@gurlKiDo!CzX9(;vL)bGDI8s+-=)3lGnJ@TP!q6&#V4bkQ;@9Mh}rv z)Gu#0))zy+bDNQ?xE?iX18?uq2eZ&jD1)1t7r5)WnR$E#aX!Qk&GlWa>UJ3V!GYrG z#$Tf7;7wp~e7vK_QV+^IaOt2|K6;%N=>`+_c??F}I|gs%W%Ufm-Ki71{hAy4+Q=BG z>#)34i^I~a4X$`at90`nKH35znw{qOf#&jwFl&D#lGXIs7>;>Gs#T}0yS?{dXb#{o z+Y|f84DQO*9+nti+|7g!@`RNEeYnsK|KYa<{9|Ezng1lDL?as*?uZ98KPEcd#_p!N zu3r_6!cB24WqBFWR^n&hBmpOvkH)J<&3V(Z9{Nih3aWx8SkJl->!Dw?`_8lfeeaQs zdCZ6vp=75+u8J6lsuE7?^~uve)XR3e9jB(rGAMrcy2Y^4lwg-((unAAQ=ljyp*MZ( z`AuYJ)ZG%KxZ~DCq2`(yvGGKh73Arm84bAOGH?}=OwxPOuGzSG2JF%|P$p3Se0^Tn zXKy;Wu%)#_0}xQvH!kH*hOsM{?yE#d^E}xaf(qa>E!>>7Mhz(ypkygOBl?37Q=G~2 zZNF0fW>c@%{H2&lfi3`yu2P5>u|{(FJ+#ce8TtdP_~Jg|zVz?>o!cpJqbxJw(3_+= zTIP(*Q)^m6&D@4vp13*i9_oaIO#vw;qQcB?;VwDinpGn5I2VnC7M0@0mxL|e@bVmE zsati%U9$x#?^@@deQC^54b7qMqD|6A1h`I&r>kdVMD+SaE11D-iW}ZIR+Lg6L_ko! z391RXOHxeEdhcY8Hz$1O%q2y?-$v-cS{>fyrnME-LKwFC_ zM|J#hQF`FEIZg(D`*w5}jP?T{@Ac!HEg?;W(vOdmEGbcdz48K@p1@o zW5}%eyEA^J)n31RTc5x?fk=`TVy}{w&yJD}rahR$JPCjR+n+iW7-|D0&jqN@8tP}c z?R#pfFS0iw$LD$?zc1>Ee8+ntzt8nV+Wezld1~wJdoOW6y4V&$@zP^x&v0*--+i|| z^e5#!-V!_Y69h4Sc6_ehHU6@mtiy*LsRIEEJLWk(nU z!fQT^>j*o9hCQi3Qzp18nc;h)38$i6@;ig?e|g0cer$52dfx#ITT4l<;8Gt=aAO#p z2|wV){#?;8qN9iCG@jIl?uqL(yAbL}jCrsh+EmLLs-|XY$Qh#dqy@o`5StupNKCmU zk+hHl4t7d6x@5A7`qC|OHSSeEY|rr64M2blNk5ihG2lCaST@SC*r;CLbM?-OW>MY+ z8MgOFeRze=S!AY?I%ofJjQ2vqIuwRd)zh!$Fkg&88y-a*X$)njTPW=F%=h$JIKPM} zEi<6BLnOOXD>tEKXNh^m3-fh0e}gy$toS*(p;gp4JE@e<9#K zH)525pbsO=`&;GiuOJg<(sQUbl4tz~noPI0iI{$2QCnNp9z(Jjma#P0-s~YNEFWsI zAO5uuK`p{P2h9@W)wFSVkGXm40UFGkmN7X#j6)<0k#>jNoe#N)aPP$HBHY@8|ENY+ zC$fwHIP9Xl{oGP!{X1y)4yXE}tv+SV@AYt`icI$(4PC6pI%*MiH0;L%5+6aglf)Zt zHO$cZmnuyd6HxBvqo7qc!R?P-DALg53fYB)@2JDZoo|;{(pE5D1diGeJ~b5&pFllC z#oQOK5M%hPFTd$`9vYpdZa2q%8&K49INO7;mp7xUFet%$5K78!ro=h9=pg)?^L+2o z?;cCw`1rT2asMhP0nHN?;-)GiD}-Ff1lKu*rzQKc0hg9!I*+kwq&<88(|H4HeXXq2 zq243Mf5~}B@nyhdr$$M}nc`fx%aq_}oY{>~U6*Ea{ope*xha^}crMYB$|47ebJSV{ zo^~^Q6YpF~c4i0x=k1<l4&&wjvR(+#GP0Nio;W9*T#H5KZGN zDxk5*8$4C!$R*X;Ys&?WG+27qYPE;!NHJ5b&@!+mJ4*(9{^uQ3;moGkEQem$6G4b> zu(PSY_=7z`xB6YmqZ4-vzELk5V{f`b%OF^dU?OgtmI@)7Qs?X@1u3>t`~x}Dr|0xb z{k}N>E+W+)W|AV_ok>wGPHmH7!{&V%KLw#bY`j&BIx+2Cvpw_D{Eq_facPnM$KcZa zLNCPQM?X%9XRwn;XNj)Pk8)6br7Hf9k}s$&M3IRBi6kPHlUhBlWSGttuFf{)Cz$n5cg2+?O?p>91;Nw6>4mFQLfHU9 z7GktIDv%l4HzPWA?6RdgX+?HJ|ImuV_)DlAKgbZD_Z{t%yrN)0Ie$fRI@N<}1S~@u z7F#oh$wx1h7_qyD`U~#fem$CpSrJ z)T^YT#kc2GV^@U>cbQ$c$Bq?~5iWMJu$9U)bqlZKx;ar&{#fjxxNR&c7QqLp9FrD4 z%r{sakFYhN%H>!#T`J*tJDLMPx2qYZIo)N&hd_Rass7U9I4%@UC()W&QY5pGi-*_X z%hKEg{d;`9!4K%WEVIJS9HMo9$;sA@P~W-6h8+C#jrU!rKu?KRS?$cd28dGh=}OJXVbSf7hMv4v zvMB)!dK2KU<-Iicv`T23aSS*0zTZ1CE1^!2Do~_P=S7MLV_`>0)6+&=^Xi9K6$lEc z@B^mUYL~Zaj;<2z9P4IihRrXgj`ZRcNCl1pJF)`4sL(Br2!6I66K+EoH7sJywpn!b zeRHmH`qEDKD!p^rA*ys6U1PLmNnk>PbCSv^aw|onl_78;aj}q^&OeAa=GGY73&yxS$)hS>hJEYcXKsxY=%p8i#%Ej2@~8QN7|$1HdrkA zweuwO&9!Vrj`c^aj9**7LW7*H=dNU?R9UhjKdCCP7d;R3L+1A5>G|KQ9xmt)-256; z5b3dTuyjQ#h-RUQdRmPzf|;s)-P@Z0pCT z25y=9wi|v{m;b!Ht?8;b=2(~Uc^8aC{p)SFcF4+~e^$?}*;R!f?^e5Tf-;0osdD_n zFPdGqy??pZ-p{f0S5iWTBq1<0Zsu{`zuoumJ(SePTe4r#972f$kPgZdf9)x}N3Ib6p}f68-o1_YtNK5M0LG^<)$ zYgof+dF$5fNtACFGrWnDsAloIxo8whJiW`tURMOM-Lej^?mFYuJjnjQZ9fy9uj6+Xj2?HY_A4H~(7pH@c4T0$-x}c;5~C(7Xbpm%thICI8A1Cpyw$aw}V+&~$xO z+T(2#X_V1K_n(}``dv%E(AwP1`2$C9uDVU37vTk|vOlje#5C%~?<4 z9onb%?MCNv??MXGrxr#Nm+EJ=3l$eWYmTk$5jObE*eXt0xS+gwt5cbFMV|M#Ap^%4 z8c|Or{`R*yoy?IPz3!rZl;fd=?n4(ZA@ak~T1*LpBD8#sjF7C+7@7i^lj`)<{)G2(=!u%zoR7M! zB%77#wBnum#c$2&MYtb+D(^(|;>rjeSOf zL2v)H01)uA{dc*jXuWMVvTx*Cw`~H-wH3^9e-MpTdf-a# z=Jtspge1bHOM+vW-OwnSt9V-@pi`oH@Rc*|WQ?n4+n4>})=FlI=*%*SO+@y*Z`30Q z0lGTH!zO-%N~R-IeptWA5YXk=xV#538JN#_x<&}P*v6j6=c};RmjMjE$jg7eT>G@W z|MGfxCqFQPHrdM`4UZ3T6UXm3Nz7iWO*I~%O17&4SqO-K{tNGXix+f>Yvfb5OHOGm zqx)oNEYtGrR44cK{ch23$J_R^9Tc%$7*<=3A~a3c@A7jY-4cmnF~B4`Elz`Y=_^gp z@;R`u{fix9KF4_cS~f}dVEW+ft{(Uo7R zv%!!0-AF5@;Wu?hS5KcjvPwDi+uLrxRR8aN#jzBUbXtYlOWh*@YgbX~PP;PjS-$L! zq!EzuIf*$xpjduai^0A>Z?`T6Ns({_jwyBq#RGwS)Mk5D*WXD{>58e&3#+^Iwf<^S zu@#mr^-!5Jk4B)%jDQuY+@ZeiV2-zse6x3p=>#^>a8@NVhz{-Qylf3U`8&I2Q7!7=aKcE35fiu;RZnMQM(he#)4fekmDrV&_6 z8N!LFwbi1r4q8J~iMh$ymBcW4ICPG-|5>;B7V;kEzxl|~7kt9`%Dg$#Tv+?J9^{{L z3@@fQ?&)3JKNIVO@O-$^T=n!>DVd9_Q!^$P^0BmRyiZnOc(cdsf(##mlw*>u8gM6l zJqdTh{N={X&fEZ?SqxNCuTN%$G8;a3+u0r8FL9|&91Oy*n=nszFJMs0=#@0R=+xT$M*ceq<(aq48F;EfY^y@=xiEhcj!4QpG--39Xa!2#~^ z8tfB2es{h~E+jiNT9)bX7p6!M7~5>7z80TYBuG7;AhXT+r1*}uN>8sJB1>AYgHlmM zPMeJvw7v^i(^?4$^Qeqx%PyX?c4+RCz85&)KQ#CF7JnrD-7u>X&)v_FKL=M8;l)xt z7nY=`D34T$0?e>au9b25;8QA*$S0yMOx0=}&{7ETqLw;)Xl>sHfzz;PlnCmo(H?sw zc4!~N3@`NG#l0?x?8^*RA&7sDh?=tBn2Wsamv0jqDkwO0oNDJylND~5DwrYKj03SG ztC1kOcQJ%k6x`z|TFbvtzi+jjrwJ!6=d#Hr(uhV-mUhWp?2ZeJ4VkDxFvFsR=ULGE z0|VVBLfao6&MrJ*UvK+GvwhQ?rj>7jj5_gjF^gto_(?#*uH}P|!`d$si@V{XfPcHc;#JuZLVzpf zI3;o!GtER{@@0Jd>}u->D8e`7lab}o(^gpDX%%QJAlZ9r_N!)C)mVscLfDcohDp|i zXhv&g)H+!wA9lPcO=#Qb?bF&=j!_v#KJxp`(5(B2376w>% z+wJez2E-E>|I?rMn>VHjDilSmSMcQ@UAI#{fpULR^8oi}yTygsk}+vb#BagoX$t*O zHmTb-nq+y`+n%A1L~$aIi(zh8q&M+Vi!KP%rnI}lFUf2LuAJ#gQsA=b_Ij;WK%2&{ zmug$wA$kl)rCgS_AGKIfdS<(H8j?okIKEYr2L^i-?b^J53Gu40y|pL)u*cQPRM{aj z7gU8HL1QWFDw?1CVmPQ+yMYqvLzZCq5XB|fUB7aR4(Gj0hY}eM%zlN}6p;c`bizlF zi*ka2%&zvEeRlxZt2&Ikx^tL;-n9Ge%i12M`?$_&&UkvPVbMgyXYA$J-86_pBiy!i?4 z*LUjuY`5EH-}dL@XX+jr4216vr`3 z8XHc=;*+mkb7MruAa_S5@j~Y^$r{p1irpM}LaAsIH%~5aoBgKMi4%;M{J~+ig$~GH zLJU2U6>yD}@*tIAx%Iz9Y_@zx17z=ksb^8GNw*QPDFF^%DMz9VOd zpvm;TPJUhsW55gw0E6ZIa@(JjyR{@382gha!&~*@W@cp98F>J@&dq|fLiXNw14V3E zv$?;J)kewb#6zl;!b>NQ6hbPW+0bCCmWgi{z$1Jww!+u{qqyA>*J zkiC)SIg3W{H^o3Jw)a5G_Y)8+xzL@3%kU2rW92boqgpv}kV*S2;TCU*_nUALO7`ze`%izFIDsceG&wC=d2 zo|n2LfVVy`7wyijd>66dxNkR@*>$PYyu<6AI zO>Q(IruaH01Pp2?+ze;V#({{%W3p~_V+00op`@9o;)w^(#+xZ(Z*woxtlzo%CM1j0 zo86c@8B4$Y(602fzlAU2-0ZjRcngTq#-fkDo(uI_y! zR?ttO5_vM1 zK7U!CcgvGqC@8CuE@EbU)Tw~sv6*OG&+>%U4T7oXr|$=Uxa~@h-c5 z=SU2EUVMM-wcxntXF1_fSBq#ix_-qVFL+5kMWH6Qf+I7gD09tzHSsC33v~1Q5m0Kyw+2&B50jP=YligmcMSYJlfxNoE*9jWxRur1nppdYyof(#Q2`V^3!Z z4bA{X)JaP^mS?tnT&?_rKoE3U_c60Jp|l-^Q*J}L4!3W@e3j()1-dK%tF|A0M^-G~ zT#)I~o!e#*#st(RU!Qmj!L*Ltd{co6__H;(Ih8eUGg(*T4F!p%Wg2e}t;_Co9-+76_Eg`Vc3U8bf($CB^i9|24J+eeYK@+r zCf4a8p$;WHK(CS@R(|!%A&n`+Y51DCU#5S<%h+p)T36qzY zneU3GiB^1NJ6h=Bvs~NHbbv{;bHETjNudcFcJp5>f3omSsh94gB8lyNJv6&cd9|z5 zGc(Ron}kk?Bcyu}u3T0L5a+`IAh!K^ zzv2*E+~~h)wteS1Wx)+P04^POClxb_MW^KR`+Culb-Ki(7S0o)54IK!SqR&^ zh+p~}|H>PFlb}DNzjFOP=9Rulfe;HNY!XvJFZNCJTJvd3GiwwJj{Qi}rX_uH{eeN-arbTR;j+4OEN?)@(E}H!S25%$m&C zAq0{C^pU0SegeGPPihsSIgI&e#GmBwj%-zq$Xmy#!%sws!+4hZqJ6ao{*+&yE6?EO z4P^3^cMjE58T|Al*6UH9K9xRw{w6|71=3pEIr__wPvDKbDLVA2c0;E2u?j!md*A2+ zK*(r4jhiTVy?v$zMhnZ$EE7+$Yh<69x9$7d zYx1ByQtIGM!POIXsFkB+l7k_YPXj*iK zcYtvIHTdo`z&G0G55a%13UNKROQ5nw1I}UqOgH%P)F9ea)Zm?Jh?>c1GJOVB+(QLr zw-a#DfZO0yw>lVrEXT$tay5(0m8AzB9pxP=dXA0gS3qjYhTFIOZ~}H3iyOPB0nQ-( zWXy!X*n&D8CnIV^@F5;wKvkrPSy*-+ywFfx|w^8uL0zeTu#N@ zoIG_+nL^7-ta|+K0ziIU~s=jc=GII=2|c@8IFwRf-^0e(EO^9DhP)NPmIZ z+2VN?WoAgXd?cvL8wuR}nKz=|?EAVw{NGF|bWXLI=!^9i9|ovSm@-Xag+ zo~O>!A?E7*-|A)WKq2WYc_J?gg3dr6OcDAU(6lMK#qg9N(PR})~1xrpv&rjvHCs(mi{s zBR!SWTZB|CV{_;!_Sz{&c zdKFS5RgB@HIH2N`WA;w<+dICkbKlZFe{iUG@^s@DL_ogd?KdcN98K~g`11epA1=SB zZlLnu)&Guo?iwUseg0hiUq}q953RQje>vJL6{Vc+5%mtsN2v!+gF;b}W%NQ8kbXtu z3h6QT=y~)gt6=!+v+fpZ0a-4)X)X#oE$635Wh}Que$($P+0b#9UVR-ikx&kj4EZ0{ z@+_RXN+LzHUMa+HW-(7|{BtzAxl7_Ge)W*QCB1kdvb<*QB4u4pUC1pNR=I1cCzxo* za5`WUJzFKS#AzBAHk>iz`m%4=>jE)X&b3;k?V2STMk8l;Mp3tweuM!R z5~!BTx!SC3zh(r#Qv?DMHYy?$kju0AE2^%bA-tO1CO?vJV^_;w6GyV;{9EidSi%<- zTVLGGMtNqK&p^gOATt1Ls4EM^p-0`lBFD-ncxQFL%CSAK`Z~a(W#&Di3dGMbn0v&b zx3LAJk;+^tRUtJel-bmV*6$2h%Yo@dk)6v3l%i1pQ(rQU4M~?v<DjuK2yf4REh>9ux$TO|*M=1)-plCI@d`JwPLYfYILij=O%Zn z65j8ROAS9p1s@{S=A>3IyQF8TkK1lxQQljK-IUjPuN;{L55lIV8XQ;9!_<=n>sg0u z)vg=mf!0gvc=7Dh+{~A3UPyjfh-Kfai@o2RZb!1-mdE*1TtqqbKzDZP_Gcg)uu)r$ z?M=CHA<|36EDUbT9X<&EG0cjZ5RB; zkFc;X4WOlxq$1I;?t&U}9lc0#Q{+2Bfq5LaNE1~QhOecP+$z9uZau?;x1liJj96!7 z5-Yr4dWVOKTTowi)r>BU8+gC6@P0vP+`5rvys|3;eo1u_-ht@O0rRy-90M^WcFRu~*9FvTaTUQMDD2kKi4yy+-cQr2qWn1hjBbG#MX)#4g}*kloC0Pat_ zZw9uBRzkJJh2mwHV9II_?7?mKP#@#l#7rz6-%!qekcYrK9W*urRLq3GVwPMS#El1j zBX@g2VC`)^?;fiTxE&d~2=~Z>a&})adWcj#Rm#ElA^9|;HRBOA=>cwazy$DUvx!93 z&L9UPGb~Q7Y)^4&LQqY33#aZycG#(0M@xVdGk)#MZrF>HCY>ogm*JdAHdj)93Pc4D z)bn2wuSRY1D78P36#^>+;k7~mQS3^g|NQ9IiLWV#0m%w6-;Th`cwyt>@=dU|M1+8X z)y6<;ytT%D{E=H}3QLbM=#H?;Lh-BRyQm(^-3c@_h8Jz|S%gYGdzq%Kf*_(7ZtRj|!Vqmsh5F)7sFd%v3teLBBjLLm)s!}!mEjjxhT*B03L z8YAxgOcqlNg+=K5p{j|;wz(@o->iSe8m}La_Qz0;AVWKZZw02e-;VYiF?T*L@t#*5 z?(ya0Z*96l#`Yy@N5jj-A>;1ZTdd`=5&4t)&%^V$2{q6hTBX%Fl{#+dqk~q!0e)r6 z>a*(B&CxtW?dm3XLd*vgwd8We{B)zi*IW3iS*Eg4hrsds2n$KHnIaoW85T#bc>fU}M^4&e;&Q9k$v2{oZN;c%a~r#t;wCgM{)idA{o0RO&wvw?Mm{B-v7F-Uxb zdl|$L4Ts-VyV2YU?w%q=n-HZS$x`A?6OM$n2g1O8wR*U?SOA=a5#gTQBrM6Juo@y2 z)L{HP_P~&O@HeC#Zkjbox%68Nc66pbAgtTb)fN2DWxuHyGZVhqPK_*&83P>!YsZxj{Fz{Z)oH zs-r%P(7!q4`PK;<>LZA4nBJ@!_dYY}xaZ|mGCXS|&y7}-9JWETxQ)>=clQ-s(H0Fc z-ZCM^xAuPu*rMc~R6gge`0D%&?uvis!jR?@+T}q_DYMCO5yjh#h+^nH1)Y^w>DZYH zK-+sVuVtc<;Z^dOdpcAKK zu?5O(XK`*AcAKv1Js&u%rQCNwvHm+QcdK3VwyOT#b!gK$*zxmy+#06 zGY;SBudbj#F)`q*302AHqNi#5qGzN9?c8c@7#PJcx7Qk_hErlN6S5z?fO9+ zJl1gT2!;?$+Us(SZL#PKiDJ34i)VKEn!Trp6|c2T(=+Y|KkKa*;_mXD4}Ur;nrqFI zsW%Ef)3$V?o<%XnSNQ31-zz0jEr&V(Ta$UdmrmGcp(lqoC7+KXkQSW`V)82tLQT*! zqfd5N*GI9DNS|m^+T71FIk!X$gRo|JI=bIbZ*!F?Sk=rCiGeJ}U%#uHNb&{qj)nvfHZXM6rU8IL@`u=h8hi zjHAwAgFxvChElu>3Z6?~-= zRsw5!5RZjwKoA{t6L(T+pG|78W{X%!pXQg5pzC5RvJ1`opD*fzn1=bK|1~UMWQm`q$q?8Hf)qA52pe7*&&aRC1xS5Zch z%8mv_Jm|j0TTd+fx2;cZM#jpFl{$Obs&;9vEztlXhk*Lq$)U`vx z_VCrWv0f+Fs#qt<#aS0w=Gv^Vk(&I#ui!cIL@^=h$x~?AU9}VI)+==^Kee!phSnvz z4B1cm^im3kauE3d$=q0lf1eTB@hONx0H!=#?48KSk|70Tmk%Yh7%5>fV3Bl#LXfo- z4nb}*&T97{*$BkR#h!#Sv}~CB3Qo}m`Qfp${Qoqk!@VSqEKg}4L_2rH9nY~!j;hj~ z^1R5Xg1mNDIfYOI-w!h#OOzH4He5ucu~Y&0OcbhNmD%kEv5qRrRf%&X@KLwby*n5v zn5~#aa4H@={ODTlqq-bGQk+qX-qmKgppp>+TQI2PbiiVqN1IAP4SKXTEP;n-Oh>@* zgF`jM*S+B2M2Ng@r4O0;=TuZKLGFzlOCeKKwc9Gfk2}-^xi`{8UpmUfF+#BDzJeEl zb>f9bz2VpyeHckg-y4IU}?fG~nKL*o5bg*oLf6vZ)C&baD*D+F>IfG7?{{ zs;6F&7uk*HK-c5ZWn;Wyxv_Yr?JPS~TerL|RHB8=7F>zer_+89y)WyXV@72YY?i`# zXr}NFglmY~`FvbOK=vh5AKPbUaDf=Pd!@W$Fz*mWR4~fP9%(apaDV)BDET0J<}# zQUBB$_Lax{8n7+-GeHv-1Nvf2E&WLEmXC4jA~t549G)zho^2yJME{-1-XNE*Cntze;gdU@c1+&d#;eCLYaB_rXkb;fv)HW#^ErWW*1_4A$CVVis@F9pb&x!+VnBx} zhOcgn_+__|v<2TrfjL~+mTcTMK!XE?BqYun%MiIjm5E+}A+u-|LJo>U6Ad-B0*}jC zVIz8+IWu|`%pTK+;n9o*oz<)03rG=hvrgTWfYRMpa)Nh_nCV_erz%XvO&6is)Lqqe z)ox|E0M;0fn-eCZ2K)$_8h1g=3>{K(<5X?6UkRV1ubyHM#~<4A_`v%E>V~&h_0B!BNW22J-&$%g5o_5=-=f)f~Y2n~srpR7LZSuQ*c zY6Fq?@E|ypV_+yy4IsP<*r`SZq#n?Xu*Lb70g~d|E)Yi}P8>G}ybSV_k>_lbA#!{) zpIaT_8|2F&swase>$L>80jMkhFQL*1$##-Z6TkQEy{5G zAH5Za9#MtRBME4}3;}|xGzUmnNXD_A1jY)V=Y%*WQ8;WySP$(azPSh{mW%dns_o9F zAbanftY+r>>2{5pL#yX|?z}WLwa-LreK5_maIoC5t?C|rbK*z;Qq?;h%`xwfewv%L zGxd&MOZKHwtN7J=->9Kx!3u5jnHIpPGs`kBS)Z7=*6?e#EzW$$#@#wuUK|NeQ^0!n z|LnjR)%WtP!`fkO>SLe#Tcx6!dz&Q`KY!a*W`K;99b&B%F$N#4{?S|imPQGU&z1ck zbjZu;iuB0u4a0)QzUs^e&6^Sdg{nvwOri$qL(o-8CNlrEl`?$nvL{9S(EY($hb?Ga z1uQOaPW5hc)ekTrCl@cqP7%-^_pMlFTyiXywH2SgR|l{p*dXYSIp)!366s;rP!e@u z#CZ(kcrvd#lWLIgF7XY=)3AAbgTj@SFauPFJCpYzv{>ZRKY)t~BZ--#Q)VWy=Fdx$ z87Bf13*^T=$%#~!{KwZ<4<+K5^OjMq_ zG$*M)^|G9Pdc=Wk!fjWsRbOx3K|~NqU1)sP%{#Xt!~gXaH}4`bL%lePZCGd1y{3ab zSi694Zr-5~VW@0j!ByfqX18{q+B?NZerQqn#P!x3$`qP4H7Z9IPsXfA$0(MNQZz(Z zYF8;KeJJZpf^EQR+O-#Sm;DO9K|V>)HE$j*ClZz9H8M-kp<*iIH9}sJu3EsHI^3Bu z2zFzhQce)q%&96k+OR%hca@2Gw%VGRv=jY%zG;`#Pn0^NS>Kk2PiEbnS&@TG6?{3) zu{nsJSKikLLcL;Mv#MH|qyt4wNP!QoDdc+S5*hz_SS%zTuOnIxv!xwqW6AhjsO8{D zq6Z}&^dS@8SdL7^3&|M;y~xQ1k^PWg_B}zPZQb{ff-@n9tk5>VU?m({yp6Uw4j;jz z{s07Vj0_{m@*r-(bi&9P2ognE<%bj-OGZM4Amy@G?jX5>fKX9NjN(DhgbVx0N1UFUv z0eBXMXaa7zz_JnNXCJ3WRHukPc+po}UZ7kcM@8YxU2rqWt)L&x-b;w-%?c&GL;d@W z3d?ui@%%d(Sa1pb;UEM~{<96k%4U5(`@3IlIL!x=^b~dQ=Ub?7ZxFp-R zKIZoRZN%tY*haj*~42 zMpYmZXj?;*CDP*PK&Q8e=HUSWNPk_%GKgxAn=?%<;E%n^~}!e2U!#@Mm-DU zBN-@iwUR6y0Bk4R&3au>4@evt0rT-Xxn~)$gtcr8%i76gV`MEbPeUI74GiS9-I1z? z7IyEDDPmC(lvpc8ju1)*zNe8 -References · Oscar.jl

    diff --git a/previews/PR4245/search_index.js b/previews/PR4245/search_index.js deleted file mode 100644 index 01608ffaa376..000000000000 --- a/previews/PR4245/search_index.js +++ /dev/null @@ -1,3 +0,0 @@ -var documenterSearchIndex = {"docs": -[{"location":"Groups/subgroups/","page":"Subgroups","title":"Subgroups","text":"CurrentModule = Oscar\nDocTestSetup = Oscar.doctestsetup()","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::GAPGroup, G::GAPGroup)\nis_subgroup(H::GAPGroup, G::GAPGroup)\nembedding(H::GAPGroup, G::GAPGroup)\nindex(G::GAPGroup, H::GAPGroup)\nis_maximal_subgroup(H::GAPGroup, G::GAPGroup; check::Bool = true)\nis_normalized_by(H::GAPGroup , G::GAPGroup)\nis_normal_subgroup(H::GAPGroup, G::GAPGroup)\nis_characteristic_subgroup(H::GAPGroup, G::GAPGroup; check::Bool = true)","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-Tuple{Oscar.GAPGroup, Oscar.GAPGroup}","page":"Subgroups","title":"is_subset","text":"is_subset(H::GAPGroup, G::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-Tuple{Oscar.GAPGroup, Oscar.GAPGroup}","page":"Subgroups","title":"is_subgroup","text":"is_subgroup(H::GAPGroup, G::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::GAPGroup, G::GAPGroup).\n\n\n\n\n\n","category":"method"},{"location":"Groups/subgroups/#embedding-Tuple{Oscar.GAPGroup, Oscar.GAPGroup}","page":"Subgroups","title":"embedding","text":"embedding(H::GAPGroup, G::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-Tuple{Oscar.GAPGroup, Oscar.GAPGroup}","page":"Subgroups","title":"index","text":"index(::Type{I} = ZZRingElem, G::GAPGroup, H::GAPGroup) where I <: IntegerUnion\nindex(::Type{I} = ZZRingElem, G::FinGenAbGroup, H::FinGenAbGroup) where I <: IntegerUnion\n\nReturn the index of H in G, as an instance of type I.\n\nExamples\n\njulia> G = symmetric_group(5); H, _ = derived_subgroup(G);\n\njulia> index(G,H)\n2\n\n\n\n\n\n","category":"method"},{"location":"Groups/subgroups/#is_maximal_subgroup-Tuple{Oscar.GAPGroup, Oscar.GAPGroup}","page":"Subgroups","title":"is_maximal_subgroup","text":"is_maximal_subgroup(H::GAPGroup, G::GAPGroup; check::Bool = true)\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-Tuple{Oscar.GAPGroup, Oscar.GAPGroup}","page":"Subgroups","title":"is_normalized_by","text":"is_normalized_by(H::GAPGroup, G::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-Tuple{Oscar.GAPGroup, Oscar.GAPGroup}","page":"Subgroups","title":"is_normal_subgroup","text":"is_normal_subgroup(H::GAPGroup, G::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-Tuple{Oscar.GAPGroup, Oscar.GAPGroup}","page":"Subgroups","title":"is_characteristic_subgroup","text":"is_characteristic_subgroup(H::GAPGroup, G::GAPGroup; check::Bool = true)\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(::T, 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\nExamples\n\njulia> trivial_subgroup(symmetric_group(5))\n(Permutation group of degree 5 and order 1, Hom: permutation group -> Sym(5))\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\nExamples\n\njulia> center(symmetric_group(3))\n(Permutation group of degree 3 and order 1, Hom: permutation group -> Sym(3))\n\njulia> center(quaternion_group(8))\n(Sub-pc group of order 2, Hom: sub-pc group -> pc group)\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 G' of G, i.e., the subgroup generated by all commutators of G, together with an embedding G' into G.\n\nExamples\n\njulia> derived_subgroup(symmetric_group(5))\n(Alt(5), Hom: Alt(5) -> Sym(5))\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{T}, Tuple{T, Vararg{T}}} where T<:Oscar.GAPGroup","page":"Subgroups","title":"intersect","text":"intersect(V::T...) where T <: Group\nintersect(V::AbstractVector{<:GAPGroup})\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":"normal_subgroups\nmaximal_normal_subgroups\nminimal_normal_subgroups\ncharacteristic_subgroups\nderived_series\nsylow_system\nhall_system\ncomplement_system\nchief_series\ncomposition_series\njennings_series\np_central_series\nlower_central_series\nupper_central_series","category":"page"},{"location":"Groups/subgroups/#normal_subgroups","page":"Subgroups","title":"normal_subgroups","text":"normal_subgroups(G::Group)\n\nReturn all normal subgroups of G (see is_normal).\n\nExamples\n\njulia> normal_subgroups(symmetric_group(5))\n3-element Vector{PermGroup}:\n Sym(5)\n Alt(5)\n Permutation group of degree 5 and order 1\n\njulia> normal_subgroups(quaternion_group(8))\n6-element Vector{SubPcGroup}:\n Sub-pc group of order 8\n Sub-pc group of order 4\n Sub-pc group of order 4\n Sub-pc group of order 4\n Sub-pc group of order 2\n Sub-pc group of order 1\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 all maximal normal subgroups of G, i.e., those proper normal subgroups of G that are maximal among the proper normal subgroups.\n\nExamples\n\njulia> maximal_normal_subgroups(symmetric_group(4))\n1-element Vector{PermGroup}:\n Alt(4)\n\njulia> maximal_normal_subgroups(quaternion_group(8))\n3-element Vector{SubPcGroup}:\n Sub-pc group of order 4\n Sub-pc group of order 4\n Sub-pc group of order 4\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 all minimal normal subgroups of G, i.e., of those nontrivial normal subgroups of G that are minimal among the nontrivial normal subgroups.\n\nExamples\n\njulia> minimal_normal_subgroups(symmetric_group(4))\n1-element Vector{PermGroup}:\n Permutation group of degree 4 and order 4\n\njulia> minimal_normal_subgroups(quaternion_group(8))\n1-element Vector{SubPcGroup}:\n Sub-pc group of order 2\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\nExamples\n\njulia> characteristic_subgroups(symmetric_group(3))\n3-element Vector{PermGroup}:\n Sym(3)\n Permutation group of degree 3 and order 3\n Permutation group of degree 3 and order 1\n\njulia> characteristic_subgroups(quaternion_group(8))\n3-element Vector{SubPcGroup}:\n Sub-pc group of order 8\n Sub-pc group of order 2\n Sub-pc group of order 1\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). See also derived_length.\n\nExamples\n\njulia> G = derived_series(symmetric_group(4))\n4-element Vector{PermGroup}:\n Sym(4)\n Alt(4)\n Permutation group of degree 4 and order 4\n Permutation group of degree 4 and order 1\n\njulia> derived_series(symmetric_group(5))\n2-element Vector{PermGroup}:\n Sym(5)\n Alt(5)\n\njulia> derived_series(dihedral_group(8))\n3-element Vector{SubPcGroup}:\n Sub-pc group of order 8\n Sub-pc group of order 2\n Sub-pc group of order 1\n\n\n\n\n\nderived_series(L::LieAlgebra) -> Vector{LieAlgebraIdeal}\n\nReturn the derived series of L, i.e. the sequence of ideals L^(0) = L, L^(i + 1) = L^(i) L^(i).\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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_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_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/#chief_series","page":"Subgroups","title":"chief_series","text":"chief_series(G::GAPGroup)\n\nReturn a vector G_1 G_2 ldots of normal subgroups of G such that G_i G_i+1 and there is no normal subgroup N of G such that G_i > N > G_{i+1}.\n\nNote that in general there is more than one chief series, this function returns an arbitrary one.\n\nExamples\n\njulia> chief_series(alternating_group(4))\n3-element Vector{PermGroup}:\n Alt(4)\n Permutation group of degree 4 and order 4\n Permutation group of degree 4 and order 1\n\njulia> chief_series(quaternion_group(8))\n4-element Vector{SubPcGroup}:\n Sub-pc group of order 8\n Sub-pc group of order 4\n Sub-pc group of order 2\n Sub-pc group of order 1\n\n\n\n\n\n","category":"function"},{"location":"Groups/subgroups/#composition_series","page":"Subgroups","title":"composition_series","text":"composition_series(M::ModAlgAss) -> Vector{MatElem}\n\nGiven a Fq[G]-module M, it returns a composition series for M, i.e. a sequence of submodules such that the quotient of two consecutive elements is irreducible.\n\n\n\n\n\ncomposition_series(G::GAPGroup)\n\nReturn a vector G_1 G_2 ldots of subgroups forming a subnormal series which cannot be refined, i.e., G_i+1 is normal in G_i and the quotient G_iG_i+1 is simple.\n\nNote that in general there is more than one composition series, this function returns an arbitrary one.\n\nExamples\n\njulia> composition_series(alternating_group(4))\n4-element Vector{PermGroup}:\n Permutation group of degree 4 and order 12\n Permutation group of degree 4 and order 4\n Permutation group of degree 4 and order 2\n Permutation group of degree 4 and order 1\n\njulia> composition_series(quaternion_group(8))\n4-element Vector{SubPcGroup}:\n Sub-pc group of order 8\n Sub-pc group of order 4\n Sub-pc group of order 2\n Sub-pc group of order 1\n\n\n\n\n\n","category":"function"},{"location":"Groups/subgroups/#jennings_series","page":"Subgroups","title":"jennings_series","text":"jennings_series(G::GAPGroup)\n\nReturn for a p-group G the vector G_1 G_2 ldots where G_1 = G and beyond that G_i+1 = G_iG G_j^p where j is the smallest integer ip.\n\nAn exception is thrown if G is not a p-group.\n\nExamples\n\njulia> jennings_series(dihedral_group(16))\n5-element Vector{SubPcGroup}:\n Sub-pc group of order 16\n Sub-pc group of order 4\n Sub-pc group of order 2\n Sub-pc group of order 2\n Sub-pc group of order 1\n\njulia> jennings_series(dihedral_group(10))\nERROR: ArgumentError: group must be a p-group\n\n\n\n\n\n","category":"function"},{"location":"Groups/subgroups/#p_central_series","page":"Subgroups","title":"p_central_series","text":"p_central_series(G::GAPGroup, p::IntegerUnion)\n\nReturn the vector G_1 G_2 ldots where G_1 = G and beyond that G_i+1 = G G_i G_i^p.\n\nAn exception is thrown if p is not a prime.\n\nExamples\n\njulia> p_central_series(alternating_group(4), 2)\n1-element Vector{PermGroup}:\n Alt(4)\n\njulia> p_central_series(alternating_group(4), 3)\n2-element Vector{PermGroup}:\n Alt(4)\n Permutation group of degree 4 and order 4\n\njulia> p_central_series(alternating_group(4), 4)\nERROR: ArgumentError: p must be a prime\n\n\n\n\n\n","category":"function"},{"location":"Groups/subgroups/#lower_central_series","page":"Subgroups","title":"lower_central_series","text":"lower_central_series(G::GAPGroup)\n\nReturn the vector G_1 G_2 ldots where G_1 = G and beyond that G_i+1 = G G_i. The series ends as soon as it is repeating (e.g. when the trivial subgroup is reached, which happens if and only if G is nilpotent).\n\nIt is a central series of normal (and even characteristic) subgroups of G. The name derives from the fact that G_i is contained in the i-th step subgroup of any central series.\n\nSee also upper_central_series and nilpotency_class.\n\nExamples\n\njulia> lower_central_series(dihedral_group(8))\n3-element Vector{SubPcGroup}:\n Sub-pc group of order 8\n Sub-pc group of order 2\n Sub-pc group of order 1\n\njulia> lower_central_series(dihedral_group(12))\n2-element Vector{SubPcGroup}:\n Sub-pc group of order 12\n Sub-pc group of order 3\n\njulia> lower_central_series(symmetric_group(4))\n2-element Vector{PermGroup}:\n Sym(4)\n Alt(4)\n\n\n\n\n\nlower_central_series(L::LieAlgebra) -> Vector{LieAlgebraIdeal}\n\nReturn the lower central series of L, i.e. the sequence of ideals L^(0) = L, L^(i + 1) = L L^(i).\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"function"},{"location":"Groups/subgroups/#upper_central_series","page":"Subgroups","title":"upper_central_series","text":"upper_central_series(G::GAPGroup)\n\nReturn the vector G_1 G_2 ldots where the last entry is the trivial group, and G_i is defined as the overgroup of G_i+1 satisfying G_i G_i+1 = Z(GG_i+1). The series ends as soon as it is repeating (e.g. when the whole group G is reached, which happens if and only if G is nilpotent).\n\nIt is a central series of normal subgroups. The name derives from the fact that G_i contains every i-th step subgroup of a central series.\n\nSee also lower_central_series and nilpotency_class.\n\nExamples\n\njulia> upper_central_series(dihedral_group(8))\n3-element Vector{SubPcGroup}:\n Sub-pc group of order 8\n Sub-pc group of order 2\n Sub-pc group of order 1\n\njulia> upper_central_series(dihedral_group(12))\n2-element Vector{SubPcGroup}:\n Sub-pc group of order 2\n Sub-pc group of order 1\n\njulia> upper_central_series(symmetric_group(4))\n1-element Vector{PermGroup}:\n Permutation group of degree 4 and order 1\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(H, G).","category":"page"},{"location":"Groups/subgroups/","page":"Subgroups","title":"Subgroups","text":"The following functions return an iterator of subgroups. Usually it is more efficient to work with (representatives of) the underlying conjugacy classes of subgroups instead.","category":"page"},{"location":"Groups/subgroups/","page":"Subgroups","title":"Subgroups","text":"complements(G::GAPGroup, N::GAPGroup)\nhall_subgroups\nlow_index_subgroups\nmaximal_subgroups\nsubgroups(G::GAPGroup)","category":"page"},{"location":"Groups/subgroups/#complements-Tuple{Oscar.GAPGroup, Oscar.GAPGroup}","page":"Subgroups","title":"complements","text":"complements(G::GAPGroup, N::GAPGroup)\n\nReturn an iterator over the complements of the normal subgroup N in G. Very likely it is better to use complement_classes instead.\n\nExamples\n\njulia> G = symmetric_group(3);\n\njulia> describe(first(complements(G, derived_subgroup(G)[1])))\n\"C2\"\n\n\n\n\n\n","category":"method"},{"location":"Groups/subgroups/#hall_subgroups","page":"Subgroups","title":"hall_subgroups","text":"hall_subgroups(G::Group, P::AbstractVector{<:IntegerUnion})\n\nReturn an iterator over the Hall P-subgroups in G. Very likely it is better to use hall_subgroup_classes instead.\n\nExamples\n\njulia> g = GL(3, 2);\n\njulia> describe(first(hall_subgroups(g, [2, 3])))\n\"S4\"\n\n\n\n\n\n","category":"function"},{"location":"Groups/subgroups/#low_index_subgroups","page":"Subgroups","title":"low_index_subgroups","text":"low_index_subgroups(G::Group, n::Int)\n\nReturn an iterator over the subgroups of index at most n in G. Very likely it is better to use low_index_subgroup_classes instead.\n\nExamples\n\njulia> G = alternating_group(6);\n\njulia> length(collect(low_index_subgroups(G, 6)))\n13\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 an iterator over the maximal subgroups in G. Very likely it is better to use maximal_subgroup_classes instead.\n\nExamples\n\njulia> println([order(H) for H in maximal_subgroups(symmetric_group(3))])\nZZRingElem[3, 2, 2, 2]\n\njulia> println([order(H) for H in maximal_subgroups(quaternion_group(8))])\nZZRingElem[4, 4, 4]\n\n\n\n\n\n","category":"function"},{"location":"Groups/subgroups/#subgroups-Tuple{Oscar.GAPGroup}","page":"Subgroups","title":"subgroups","text":"subgroups(G::GAPGroup)\n\nReturn an iterator over all subgroups in G. Very likely it is better to use subgroup_classes instead.\n\nExamples\n\njulia> println([order(H) for H in subgroups(symmetric_group(3))])\nZZRingElem[1, 2, 2, 2, 3, 6]\n\njulia> println([order(H) for H in subgroups(quaternion_group(8))])\nZZRingElem[1, 2, 4, 4, 4, 8]\n\n\n\n\n\n","category":"method"},{"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::GAPGroup, H::GAPGroup)\nnormalizer(G::GAPGroup, x::GAPGroupElem)\nnormalizer(G::GAPGroup, H::GAPGroup)\ncore(G::GAPGroup, H::GAPGroup)\nnormal_closure(G::GAPGroup, H::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 inv(z)*x*z equals y. To also return the element z, use is_conjugate_with_data(G::GAPGroup, x::GAPGroupElem, y::GAPGroupElem).\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, i.e., whether there exists an element z in G such that the conjugate group H^z, which is defined as z^-1 h z h in H , equals K. To also return the element z, use is_conjugate_with_data(G::GAPGroup, H::GAPGroup, K::GAPGroup).\n\nExamples\n\njulia> G = symmetric_group(4);\n\njulia> H = sub(G, [G([2, 1, 3, 4])])[1]\nPermutation group of degree 4\n\njulia> K = sub(G, [G([1, 2, 4, 3])])[1]\nPermutation group of degree 4\n\njulia> is_conjugate(G, H, K)\ntrue\n\njulia> K = sub(G, [G([2, 1, 4, 3])])[1]\nPermutation group of degree 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 inv(z)*x*z == y holds; otherwise, return (false, nothing). If the conjugating element z is not needed, use is_conjugate(G::GAPGroup, x::GAPGroupElem, y::GAPGroupElem).\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). The conjugate group H^z is defined as z^-1 h z h in H . If the conjugating element z is not needed, use is_conjugate(G::GAPGroup, H::GAPGroup, K::GAPGroup).\n\nExamples\n\njulia> G = symmetric_group(4);\n\njulia> H = sub(G, [G([2, 1, 3, 4])])[1]\nPermutation group of degree 4\n\njulia> K = sub(G, [G([1, 2, 4, 3])])[1]\nPermutation group of degree 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]\nPermutation group of degree 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-Tuple{Oscar.GAPGroup, 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-Tuple{Oscar.GAPGroup, 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-Tuple{Oscar.GAPGroup, 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-Tuple{Oscar.GAPGroup, 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_of_conjugacy_classes(G::GAPGroup)\nconjugacy_class(G::GAPGroup, g::GAPGroupElem)\nconjugacy_class(G::GAPGroup, H::GAPGroup)\nconjugacy_classes(G::GAPGroup)\ncomplement_classes\nhall_subgroup_classes\nlow_index_subgroup_classes\nmaximal_subgroup_classes(G::GAPGroup)\nsubgroup_classes(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.\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]))\nConjugacy class of\n (1,2) in\n Sym(4)\n\njulia> representative(C)\n(1,2)\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]))\nConjugacy class of\n (1,2) in\n Sym(4)\n\njulia> acting_group(C) === G\ntrue\n\n\n\n\n\n","category":"method"},{"location":"Groups/subgroups/#number_of_conjugacy_classes-Tuple{Oscar.GAPGroup}","page":"Subgroups","title":"number_of_conjugacy_classes","text":"number_of_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]))\nConjugacy class of\n (1,2) in\n Sym(4)\n\n\n\n\n\n","category":"method"},{"location":"Groups/subgroups/#conjugacy_class-Tuple{Oscar.GAPGroup, Oscar.GAPGroup}","page":"Subgroups","title":"conjugacy_class","text":"conjugacy_class(G::Group, H::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 a 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/#complement_classes","page":"Subgroups","title":"complement_classes","text":"complement_classes(G::GAPGroup, N::GAPGroup)\n\nReturn a vector 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_classes(G, derived_subgroup(G)[1])\n1-element Vector{GAPGroupConjClass{PermGroup, PermGroup}}:\n Conjugacy class of permutation group in G\n\njulia> G = dihedral_group(8)\nPc group of order 8\n\njulia> complement_classes(G, center(G)[1])\nGAPGroupConjClass{PcGroup, SubPcGroup}[]\n\n\n\n\n\n","category":"function"},{"location":"Groups/subgroups/#hall_subgroup_classes","page":"Subgroups","title":"hall_subgroup_classes","text":"hall_subgroup_classes(G::Group, P::AbstractVector{<:IntegerUnion})\n\nReturn a vector that contains the 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_classes(g, [2, 3]);\n\njulia> (length(h), order(representative(h[1])))\n(1, 6)\n\njulia> g = GL(3, 2)\nGL(3,2)\n\njulia> h = hall_subgroup_classes(g, [2, 3]);\n\njulia> (length(h), order(representative(h[1])))\n(2, 24)\n\njulia> h = hall_subgroup_classes(g, [2, 7]); length(h)\n0\n\n\n\n\n\n","category":"function"},{"location":"Groups/subgroups/#low_index_subgroup_classes","page":"Subgroups","title":"low_index_subgroup_classes","text":"low_index_subgroup_classes(G::GAPGroup, n::Int)\n\nReturn a vector of conjugacy classes of subgroups of index at most n in G.\n\nExamples\n\njulia> G = symmetric_group(5);\n\njulia> low_index_subgroup_classes(G, 5)\n3-element Vector{GAPGroupConjClass{PermGroup, PermGroup}}:\n Conjugacy class of Sym(5) in G\n Conjugacy class of permutation group in G\n Conjugacy class of Alt(5) in G\n\n\n\n\n\n","category":"function"},{"location":"Groups/subgroups/#maximal_subgroup_classes-Tuple{Oscar.GAPGroup}","page":"Subgroups","title":"maximal_subgroup_classes","text":"maximal_subgroup_classes(G::Group)\n\nReturn a vector of all conjugacy classes of maximal subgroups of G.\n\nExamples\n\njulia> G = symmetric_group(3);\n\njulia> maximal_subgroup_classes(G)\n2-element Vector{GAPGroupConjClass{PermGroup, PermGroup}}:\n Conjugacy class of permutation group in G\n Conjugacy class of permutation group in G\n\n\n\n\n\n","category":"method"},{"location":"Groups/subgroups/#subgroup_classes-Tuple{Oscar.GAPGroup}","page":"Subgroups","title":"subgroup_classes","text":"subgroup_classes(G::GAPGroup; order::T = ZZRingElem(-1)) where T <: IntegerUnion\n\nReturn a vector of all conjugacy classes of subgroups of G or, if order is positive, the classes of subgroups of this order.\n\nExamples\n\njulia> G = symmetric_group(3)\nSym(3)\n\njulia> subgroup_classes(G)\n4-element Vector{GAPGroupConjClass{PermGroup, PermGroup}}:\n Conjugacy class of permutation group in G\n Conjugacy class of permutation group in G\n Conjugacy class of permutation group in G\n Conjugacy class of permutation group in G\n\njulia> subgroup_classes(G, order = ZZRingElem(2))\n1-element Vector{GAPGroupConjClass{PermGroup, PermGroup}}:\n Conjugacy class of permutation group in G\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::GAPGroup, H::GAPGroup; check::Bool=true)\nleft_cosets(G::GAPGroup, H::GAPGroup; check::Bool=true)\nright_transversal(G::T1, H::T2; check::Bool=true) where T1 <: GAPGroup where T2 <: GAPGroup\nleft_transversal(G::T1, H::T2; check::Bool=true) where T1 <: GAPGroup where T2 <: GAPGroup\nGroupDoubleCoset{T <: GAPGroup, S <: GAPGroupElem}\ndouble_coset(G::GAPGroup, g::GAPGroupElem, H::GAPGroup)\ndouble_cosets(G::T, H::GAPGroup, K::GAPGroup; check::Bool=true) 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{<: GAPGroup, GroupCoset, GroupDoubleCoset}})","category":"page"},{"location":"Groups/subgroups/#GroupCoset","page":"Subgroups","title":"GroupCoset","text":"GroupCoset{T<: Group, S <: GAPGroupElem}\n\nType of group cosets. 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(5)\n\njulia> g = perm(G,[3,4,1,5,2])\n(1,3)(2,4,5)\n\njulia> H = symmetric_group(3)\nSym(3)\n\njulia> right_coset(H, g)\nRight coset of Sym(3)\n with representative (1,3)(2,4,5)\n in Sym(5)\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(3)\n\njulia> gH = left_coset(H, g)\nLeft coset of Sym(3)\n with representative (1,3)(2,4,5)\n in Sym(5)\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(5)\n\njulia> H = symmetric_group(4)\nSym(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 of Sym(4)\n with representative (1,3)(2,4,5)\n in Sym(5)\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 of Sym(4)\n with representative (1,2)(3,4)\n in Sym(5)\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(5)\n\njulia> g = perm(G,[3,4,1,5,2])\n(1,3)(2,4,5)\n\njulia> H = symmetric_group(3)\nSym(3)\n\njulia> gH = left_coset(H,g)\nLeft coset of Sym(3)\n with representative (1,3)(2,4,5)\n in Sym(5)\n\njulia> acting_domain(gH)\nSym(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(5)\n\njulia> g = perm(G,[3,4,1,5,2])\n(1,3)(2,4,5)\n\njulia> H = symmetric_group(3)\nSym(3)\n\njulia> gH = left_coset(H, g)\nLeft coset of Sym(3)\n with representative (1,3)(2,4,5)\n in Sym(5)\n\njulia> representative(gH)\n(1,3)(2,4,5)\n\n\n\n\n\n","category":"method"},{"location":"Groups/subgroups/#right_cosets-Tuple{Oscar.GAPGroup, Oscar.GAPGroup}","page":"Subgroups","title":"right_cosets","text":"right_cosets(G::GAPGroup, H::GAPGroup; check::Bool=true)\n\nReturn the G-set that describes 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(4)\n\njulia> H = symmetric_group(3)\nSym(3)\n\njulia> rc = right_cosets(G, H)\nRight cosets of\n Sym(3) in\n Sym(4)\n\njulia> collect(rc)\n4-element Vector{GroupCoset{PermGroup, PermGroupElem}}:\n Right coset of H with representative ()\n Right coset of H with representative (1,4)\n Right coset of H with representative (1,4,2)\n Right coset of H with representative (1,4,3)\n\n\n\n\n\n","category":"method"},{"location":"Groups/subgroups/#left_cosets-Tuple{Oscar.GAPGroup, Oscar.GAPGroup}","page":"Subgroups","title":"left_cosets","text":"left_cosets(G::GAPGroup, H::GAPGroup; check::Bool=true)\n\nReturn the G-set that describes 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(4)\n\njulia> H = symmetric_group(3)\nSym(3)\n\njulia> left_cosets(G, H)\nLeft cosets of\n Sym(3) in\n Sym(4)\n\n\n\n\n\n","category":"method"},{"location":"Groups/subgroups/#right_transversal-Union{Tuple{T1}, Tuple{T2}, Tuple{T1, T2}} where {T2<:Oscar.GAPGroup, T1<:Oscar.GAPGroup}","page":"Subgroups","title":"right_transversal","text":"right_transversal(G::GAPGroup, H::GAPGroup; check::Bool=true)\n\nReturn a vector containing a complete set of representatives for the right cosets of H in G. This vector is not mutable, and it does not store its entries explicitly, they are created anew with each access to the transversal.\n\nIf check == false, do not check whether H is a subgroup of G.\n\nExamples\n\njulia> G = symmetric_group(4)\nSym(4)\n\njulia> H = symmetric_group(3)\nSym(3)\n\njulia> T = right_transversal(G, H)\nRight transversal of length 4 of\n Sym(3) in\n Sym(4)\n\njulia> collect(T)\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{T1}, Tuple{T2}, Tuple{T1, T2}} where {T2<:Oscar.GAPGroup, T1<:Oscar.GAPGroup}","page":"Subgroups","title":"left_transversal","text":"left_transversal(G::GAPGroup, H::GAPGroup; check::Bool=true)\n\nReturn a vector containing a complete set of representatives for the left cosets for H in G. This vector is not mutable, and it does not store its entries explicitly, they are created anew with each access to the transversal.\n\nIf check == false, do not check whether H is a subgroup of G.\n\nExamples\n\njulia> G = symmetric_group(4)\nSym(4)\n\njulia> H = symmetric_group(3)\nSym(3)\n\njulia> T = left_transversal(G, H)\nLeft transversal of length 4 of\n Sym(3) in\n Sym(4)\n\njulia> collect(T)\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. 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-Tuple{Oscar.GAPGroup, GAPGroupElem, 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(5)\n\njulia> g = perm(G,[3,4,5,1,2])\n(1,3,5,2,4)\n\njulia> H = symmetric_group(3)\nSym(3)\n\njulia> K = symmetric_group(2)\nSym(2)\n\njulia> double_coset(H,g,K)\nDouble coset of Sym(3)\n and Sym(2)\n with representative (1,3,5,2,4)\n in Sym(5)\n\n\n\n\n\n","category":"method"},{"location":"Groups/subgroups/#double_cosets-Union{Tuple{T}, Tuple{T, Oscar.GAPGroup, Oscar.GAPGroup}} where T<:Oscar.GAPGroup","page":"Subgroups","title":"double_cosets","text":"double_cosets(G::GAPGroup, H::GAPGroup, K::GAPGroup; check::Bool=true)\n\nReturn a 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(4)\n\njulia> H = symmetric_group(3)\nSym(3)\n\njulia> K = symmetric_group(2)\nSym(2)\n\njulia> double_cosets(G,H,K)\n3-element Vector{GroupDoubleCoset{PermGroup, PermGroupElem}}:\n Double coset of H and K with representative ()\n Double coset of H and K with representative (1,4)\n Double coset of H and K with representative (1,4,3)\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(::Type{T} = ZZRingElem, C::Union{GroupCoset,GroupDoubleCoset})\n\nReturn the cardinality of the (double) coset C, as an instance of the type T.\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-Tuple{AbstractVector{Union{Oscar.GAPGroup, GroupCoset, GroupDoubleCoset}}}","page":"Subgroups","title":"intersect","text":"intersect(V::AbstractVector{Union{<: GAPGroup, GroupCoset, GroupDoubleCoset}})\n\nReturn a vector containing all elements belonging to all groups and cosets in V.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/orders/ideals/#NfOrdIdlLink2","page":"Ideals","title":"Ideals","text":"","category":"section"},{"location":"Hecke/manual/orders/ideals/","page":"Ideals","title":"Ideals","text":"CurrentModule = Hecke","category":"page"},{"location":"Hecke/manual/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/manual/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/manual/orders/ideals/","page":"Ideals","title":"Ideals","text":"For efficiency, we will choose the 1st generator to be an integer.","category":"page"},{"location":"Hecke/manual/orders/ideals/","page":"Ideals","title":"Ideals","text":"Ideals here are of type AbsNumFieldOrderIdeal, which is, similar to the elements above, also indexed by the type of the field and their elements: AbsNumFieldOrderIdeal{AbsSimpleNumField,AbsSimpleNumFieldElem} for ideals in simple absolute fields.","category":"page"},{"location":"Hecke/manual/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 AbsNumFieldOrderIdealSet.","category":"page"},{"location":"Hecke/manual/orders/ideals/#Creation","page":"Ideals","title":"Creation","text":"","category":"section"},{"location":"Hecke/manual/orders/ideals/","page":"Ideals","title":"Ideals","text":"ideal(::AbsSimpleNumFieldOrder, ::ZZRingElem)\nideal(::AbsSimpleNumFieldOrder, ::ZZMatrix)\nideal(::AbsSimpleNumFieldOrder, ::AbsSimpleNumFieldOrderElem)\nideal(::AbsSimpleNumFieldOrder, ::ZZRingElem, ::AbsSimpleNumFieldOrderElem)\nideal(::AbsNumFieldOrder, ::ZZRingElem, ::AbsNumFieldOrderElem)\nideal(::AbsNumFieldOrder, ::ZZRingElem)\nideal(::AbsNumFieldOrder, ::AbsNumFieldOrderElem)\n\n*(::AbsSimpleNumFieldOrder, ::AbsSimpleNumFieldOrderElem)\nfactor(::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem})\nfactor(::AbsNumFieldOrderIdealSet{AbsSimpleNumField, AbsSimpleNumFieldElem}, ::AbsSimpleNumFieldElem)\ncoprime_base(::Vector{AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}})","category":"page"},{"location":"Hecke/manual/orders/ideals/#ideal-Tuple{AbsSimpleNumFieldOrder, ZZRingElem}","page":"Ideals","title":"ideal","text":"ideal(O::AbsSimpleNumFieldOrder, a::ZZRingElem) -> AbsNumFieldOrderIdeal\nideal(O::AbsSimpleNumFieldOrder, a::Integer) -> AbsNumFieldOrderIdeal\n\nReturns the ideal of mathcal O which is generated by a.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/orders/ideals/#ideal-Tuple{AbsSimpleNumFieldOrder, ZZMatrix}","page":"Ideals","title":"ideal","text":"ideal(O::AbsSimpleNumFieldOrder, M::ZZMatrix; check::Bool = false, M_in_hnf::Bool = false) -> AbsNumFieldOrderIdeal\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/manual/orders/ideals/#ideal-Tuple{AbsSimpleNumFieldOrder, AbsSimpleNumFieldOrderElem}","page":"Ideals","title":"ideal","text":"ideal(O::AbsSimpleNumFieldOrder, x::AbsSimpleNumFieldOrderElem) -> AbsNumFieldOrderIdeal\n\nCreates the principal ideal (x) of mathcal O.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/orders/ideals/#ideal-Tuple{AbsSimpleNumFieldOrder, ZZRingElem, AbsSimpleNumFieldOrderElem}","page":"Ideals","title":"ideal","text":"ideal(O::AbsSimpleNumFieldOrder, x::ZZRingElem, y::AbsSimpleNumFieldOrderElem) -> AbsNumFieldOrderIdeal\nideal(O::AbsSimpleNumFieldOrder, x::Integer, y::AbsSimpleNumFieldOrderElem) -> AbsNumFieldOrderIdeal\n\nCreates the ideal (x y) of mathcal O.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/orders/ideals/#ideal-Tuple{AbsNumFieldOrder, ZZRingElem, AbsNumFieldOrderElem}","page":"Ideals","title":"ideal","text":"ideal(O::AbsSimpleNumFieldOrder, x::ZZRingElem, y::AbsSimpleNumFieldOrderElem) -> AbsNumFieldOrderIdeal\nideal(O::AbsSimpleNumFieldOrder, x::Integer, y::AbsSimpleNumFieldOrderElem) -> AbsNumFieldOrderIdeal\n\nCreates the ideal (x y) of mathcal O.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/orders/ideals/#ideal-Tuple{AbsNumFieldOrder, ZZRingElem}","page":"Ideals","title":"ideal","text":"ideal(O::AbsSimpleNumFieldOrder, a::ZZRingElem) -> AbsNumFieldOrderIdeal\nideal(O::AbsSimpleNumFieldOrder, a::Integer) -> AbsNumFieldOrderIdeal\n\nReturns the ideal of mathcal O which is generated by a.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/orders/ideals/#ideal-Tuple{AbsNumFieldOrder, AbsNumFieldOrderElem}","page":"Ideals","title":"ideal","text":"ideal(O::AbsSimpleNumFieldOrder, x::AbsSimpleNumFieldOrderElem) -> AbsNumFieldOrderIdeal\n\nCreates the principal ideal (x) of mathcal O.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/orders/ideals/#*-Tuple{AbsSimpleNumFieldOrder, AbsSimpleNumFieldOrderElem}","page":"Ideals","title":"*","text":"*(O::AbsSimpleNumFieldOrder, x::AbsSimpleNumFieldOrderElem) -> AbsNumFieldOrderIdeal\n*(x::AbsNumFieldOrderElem, O::AbsNumFieldOrder) -> AbsNumFieldOrderIdeal\n\nReturns the principal ideal (x) of mathcal O.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/orders/ideals/#factor-Tuple{AbsSimpleNumFieldOrderIdeal}","page":"Ideals","title":"factor","text":"factor(a::T) where T <: RingElement -> Fac{T}\n\nReturn a factorization of a into irreducible elements, as a Fac{T}. The irreducible elements in the factorization are pairwise coprime.\n\n\n\n\n\nfactor(A::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}) -> Dict{AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}, 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/manual/orders/ideals/#factor-Tuple{Hecke.AbsNumFieldOrderIdealSet{AbsSimpleNumField, AbsSimpleNumFieldElem}, AbsSimpleNumFieldElem}","page":"Ideals","title":"factor","text":"factor(I::AbsNumFieldOrderIdealSet{AbsSimpleNumField, AbsSimpleNumFieldElem}, a::AbsSimpleNumFieldElem) -> Dict{AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}, ZZRingElem}\n\nFactors the principal ideal generated by a.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/orders/ideals/#coprime_base-Tuple{Vector{AbsSimpleNumFieldOrderIdeal}}","page":"Ideals","title":"coprime_base","text":"coprime_base(A::Vector{AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}}) -> Vector{AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}}\ncoprime_base(A::Vector{AbsSimpleNumFieldOrderElem}) -> Vector{AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}}\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/manual/orders/ideals/#Arithmetic","page":"Ideals","title":"Arithmetic","text":"","category":"section"},{"location":"Hecke/manual/orders/ideals/","page":"Ideals","title":"Ideals","text":"All the usual operations are supported:","category":"page"},{"location":"Hecke/manual/orders/ideals/","page":"Ideals","title":"Ideals","text":"==, +, *\ndivexact, divides\nlcm, gcd\nin","category":"page"},{"location":"Hecke/manual/orders/ideals/","page":"Ideals","title":"Ideals","text":"intersect(::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}, ::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem})\ncolon(::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}, ::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem})\nin(::AbsSimpleNumFieldOrderElem, ::AbsNumFieldOrderIdeal)\nis_power(::AbsNumFieldOrderIdeal, ::Int)\nis_power(::AbsNumFieldOrderIdeal)\nis_invertible(::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem})\nisone(::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem})","category":"page"},{"location":"Hecke/manual/orders/ideals/#intersect-Tuple{AbsSimpleNumFieldOrderIdeal, AbsSimpleNumFieldOrderIdeal}","page":"Ideals","title":"intersect","text":"intersect(x::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}, y::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}) -> AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}\n\nReturns x cap y.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/orders/ideals/#colon-Tuple{AbsSimpleNumFieldOrderIdeal, AbsSimpleNumFieldOrderIdeal}","page":"Ideals","title":"colon","text":"colon(a::AbsNumFieldOrderIdeal, b::AbsNumFieldOrderIdeal) -> AbsSimpleNumFieldOrderFractionalIdeal\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/manual/orders/ideals/#in-Tuple{AbsSimpleNumFieldOrderElem, AbsNumFieldOrderIdeal}","page":"Ideals","title":"in","text":"in(x::NumFieldOrderElem, y::NumFieldOrderIdeal)\nin(x::NumFieldElem, y::NumFieldOrderIdeal)\nin(x::ZZRingElem, y::NumFieldOrderIdeal)\n\nReturns whether x is contained in y.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/orders/ideals/#is_power-Tuple{AbsNumFieldOrderIdeal, Int64}","page":"Ideals","title":"is_power","text":"is_power(A::AbsNumFieldOrderIdeal, n::Int) -> Bool, AbsNumFieldOrderIdeal\nis_power(A::AbsSimpleNumFieldOrderFractionalIdeal, n::Int) -> Bool, AbsSimpleNumFieldOrderFractionalIdeal\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/manual/orders/ideals/#is_power-Tuple{AbsNumFieldOrderIdeal}","page":"Ideals","title":"is_power","text":"is_power(I::AbsNumFieldOrderIdeal) -> Int, AbsNumFieldOrderIdeal\nis_power(a::AbsSimpleNumFieldOrderFractionalIdeal) -> Int, AbsSimpleNumFieldOrderFractionalIdeal\n\nWrites a = r^e with e maximal. Note: 1 = 1^0.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/orders/ideals/#is_invertible-Tuple{AbsSimpleNumFieldOrderIdeal}","page":"Ideals","title":"is_invertible","text":"is_invertible(A::AbsNumFieldOrderIdeal) -> Bool, AbsSimpleNumFieldOrderFractionalIdeal\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/manual/orders/ideals/#isone-Tuple{AbsSimpleNumFieldOrderIdeal}","page":"Ideals","title":"isone","text":"isone(A::AbsNumFieldOrderIdeal) -> Bool\nis_unit(A::AbsNumFieldOrderIdeal) -> Bool\n\nTests if A is the trivial ideal generated by 1.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/orders/ideals/#Class-Group","page":"Ideals","title":"Class Group","text":"","category":"section"},{"location":"Hecke/manual/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/manual/orders/ideals/","page":"Ideals","title":"Ideals","text":"class_group(::AbsSimpleNumFieldOrder)\nnarrow_class_group(::AbsSimpleNumFieldOrder)\npicard_group(::AbsSimpleNumFieldOrder)\nring_class_group(::AbsNumFieldOrder)","category":"page"},{"location":"Hecke/manual/orders/ideals/#class_group-Tuple{AbsSimpleNumFieldOrder}","page":"Ideals","title":"class_group","text":"class_group(O::AbsSimpleNumFieldOrder; bound = -1,\n redo = false,\n GRH = true) -> FinGenAbGroup, 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.\n\nBy default, the correctness is guarenteed only assuming the Generalized Riemann Hypothesis (GRH).\n\nKeyword arguments:\n\nredo: Trigger a recomputation, thus avoiding the cache.\nbound: When specified, this is used for the bound for the factor base.\nGRH: If false, the correctness of the result does not depend on GRH.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/orders/ideals/#narrow_class_group-Tuple{AbsSimpleNumFieldOrder}","page":"Ideals","title":"narrow_class_group","text":"narrow_class_group(O::AbsSimpleNumFieldOrder) -> FinGenAbGroup, 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/manual/orders/ideals/#picard_group-Tuple{AbsSimpleNumFieldOrder}","page":"Ideals","title":"picard_group","text":"picard_group(O::AbsSimpleNumFieldOrder) -> FinGenAbGroup, 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/manual/orders/ideals/#ring_class_group-Tuple{AbsNumFieldOrder}","page":"Ideals","title":"ring_class_group","text":"ring_class_group(O::AbsNumFieldOrder)\n\nThe ring class group (Picard group) of O.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/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/manual/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/manual/orders/ideals/","page":"Ideals","title":"Ideals","text":"is_principal(::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem})\nis_principal_with_data(::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem})\nis_principal_fac_elem(::AbsNumFieldOrderIdeal{AbsSimpleNumField,AbsSimpleNumFieldElem})\npower_class(::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem},::ZZRingElem)\npower_product_class(::Vector{AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}}, ::Vector{ZZRingElem})\npower_reduce(::AbsNumFieldOrderIdeal{AbsSimpleNumField,AbsSimpleNumFieldElem},::ZZRingElem)\nclass_group_ideal_relation(::AbsNumFieldOrderIdeal{AbsSimpleNumField,AbsSimpleNumFieldElem}, ::Hecke.ClassGrpCtx)\nfactor_base_bound_grh(::AbsSimpleNumFieldOrder)\nfactor_base_bound_bach(::AbsSimpleNumFieldOrder)\nprime_ideals_up_to","category":"page"},{"location":"Hecke/manual/orders/ideals/#is_principal-Tuple{AbsSimpleNumFieldOrderIdeal}","page":"Ideals","title":"is_principal","text":"is_principal(A::AbsSimpleNumFieldOrderIdeal) -> Bool\nis_principal(A::AbsSimpleNumFieldOrderFractionalIdeal) -> Bool\n\nTests if A is principal.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/orders/ideals/#is_principal_with_data-Tuple{AbsSimpleNumFieldOrderIdeal}","page":"Ideals","title":"is_principal_with_data","text":"is_principal_with_data(A::AbsSimpleNumFieldOrderIdeal) -> Bool, AbsSimpleNumFieldOrderElem\nis_principal_with_data(A::AbsSimpleNumFieldOrderFractionalIdeal) -> Bool, AbsSimpleNumFieldElem\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/manual/orders/ideals/#is_principal_fac_elem-Tuple{AbsSimpleNumFieldOrderIdeal}","page":"Ideals","title":"is_principal_fac_elem","text":"is_principal_fac_elem(A::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}) -> Bool, FacElem{AbsSimpleNumFieldElem, 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/manual/orders/ideals/#power_class-Tuple{AbsSimpleNumFieldOrderIdeal, ZZRingElem}","page":"Ideals","title":"power_class","text":"power_class(A::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}, e::ZZRingElem) -> AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}\n\nComputes a (small) ideal in the same class as A^e.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/orders/ideals/#power_product_class-Tuple{Vector{AbsSimpleNumFieldOrderIdeal}, Vector{ZZRingElem}}","page":"Ideals","title":"power_product_class","text":"power_product_class(A::Vector{AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}}, e::Vector{ZZRingElem}) -> AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}\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/manual/orders/ideals/#power_reduce-Tuple{AbsSimpleNumFieldOrderIdeal, ZZRingElem}","page":"Ideals","title":"power_reduce","text":"power_reduce(A::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}, e::ZZRingElem) -> AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}, FacElem{AbsSimpleNumFieldElem}\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/manual/orders/ideals/#class_group_ideal_relation-Tuple{AbsSimpleNumFieldOrderIdeal, Hecke.ClassGrpCtx}","page":"Ideals","title":"class_group_ideal_relation","text":"class_group_ideal_relation(I::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}, c::ClassGrpCtx) -> AbsSimpleNumFieldElem, 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/manual/orders/ideals/#factor_base_bound_grh-Tuple{AbsSimpleNumFieldOrder}","page":"Ideals","title":"factor_base_bound_grh","text":"factor_base_bound_grh(O::AbsSimpleNumFieldOrder) -> 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/manual/orders/ideals/#factor_base_bound_bach-Tuple{AbsSimpleNumFieldOrder}","page":"Ideals","title":"factor_base_bound_bach","text":"factor_base_bound_bach(O::AbsSimpleNumFieldOrder) -> 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/manual/orders/ideals/#prime_ideals_up_to","page":"Ideals","title":"prime_ideals_up_to","text":"prime_ideals_up_to(O::AbsSimpleNumFieldOrder,\n B::Int;\n degree_limit::Int = 0, index_divisors::Bool = true) -> Vector{AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}}\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::AbsSimpleNumFieldOrder,\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/manual/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/manual/orders/ideals/","page":"Ideals","title":"Ideals","text":"The computation of S-units is also tied to the class group:","category":"page"},{"location":"Hecke/manual/orders/ideals/","page":"Ideals","title":"Ideals","text":"torsion_units(::AbsSimpleNumFieldOrder)\ntorsion_unit_group(::AbsSimpleNumFieldOrder)\ntorsion_units_generator(::AbsSimpleNumFieldOrder)\nHecke.torsion_units_gen_order(::AbsSimpleNumFieldOrder)\nunit_group(::AbsSimpleNumFieldOrder)\nunit_group_fac_elem(::AbsSimpleNumFieldOrder)\nsunit_group(::Vector{AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}})\nsunit_group_fac_elem(::Vector{AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}})\nsunit_mod_units_group_fac_elem(::Vector{AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}})","category":"page"},{"location":"Hecke/manual/orders/ideals/#torsion_units-Tuple{AbsSimpleNumFieldOrder}","page":"Ideals","title":"torsion_units","text":"torsion_units(O::AbsSimpleNumFieldOrder) -> Vector{AbsSimpleNumFieldOrderElem}\n\nGiven an order O, compute the torsion units of O.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/orders/ideals/#torsion_unit_group-Tuple{AbsSimpleNumFieldOrder}","page":"Ideals","title":"torsion_unit_group","text":"torsion_unit_group(O::AbsSimpleNumFieldOrder) -> 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/manual/orders/ideals/#torsion_units_generator-Tuple{AbsSimpleNumFieldOrder}","page":"Ideals","title":"torsion_units_generator","text":"torsion_units_generator(O::AbsSimpleNumFieldOrder) -> AbsSimpleNumFieldOrderElem\n\nGiven an order O, compute a generator of the torsion units of O.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/orders/ideals/#torsion_units_gen_order-Tuple{AbsSimpleNumFieldOrder}","page":"Ideals","title":"torsion_units_gen_order","text":"torsion_units_gen_order(O::AbsSimpleNumFieldOrder) -> AbsSimpleNumFieldOrderElem\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/manual/orders/ideals/#unit_group-Tuple{AbsSimpleNumFieldOrder}","page":"Ideals","title":"unit_group","text":"unit_group(O::AbsSimpleNumFieldOrder) -> FinGenAbGroup, 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/manual/orders/ideals/#unit_group_fac_elem-Tuple{AbsSimpleNumFieldOrder}","page":"Ideals","title":"unit_group_fac_elem","text":"unit_group_fac_elem(O::AbsSimpleNumFieldOrder) -> FinGenAbGroup, 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/manual/orders/ideals/#sunit_group-Tuple{Vector{AbsSimpleNumFieldOrderIdeal}}","page":"Ideals","title":"sunit_group","text":"sunit_group(I::Vector{AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}}) -> 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/manual/orders/ideals/#sunit_group_fac_elem-Tuple{Vector{AbsSimpleNumFieldOrderIdeal}}","page":"Ideals","title":"sunit_group_fac_elem","text":"sunit_group_fac_elem(I::Vector{AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}}) -> 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/manual/orders/ideals/#sunit_mod_units_group_fac_elem-Tuple{Vector{AbsSimpleNumFieldOrderIdeal}}","page":"Ideals","title":"sunit_mod_units_group_fac_elem","text":"sunit_mod_units_group_fac_elem(I::Vector{AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}}) -> 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/manual/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/manual/orders/ideals/#Miscaellenous","page":"Ideals","title":"Miscaellenous","text":"","category":"section"},{"location":"Hecke/manual/orders/ideals/","page":"Ideals","title":"Ideals","text":"order(::AbsNumFieldOrderIdeal)\norder(::AbsNumFieldOrderFractionalIdeal)\norder(::RelNumFieldOrderIdeal)\norder(::RelNumFieldOrderFractionalIdeal)\nnf(::AbsNumFieldOrderIdeal)\nbasis(::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem})\nHecke.lll_basis(::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem})\nbasis_matrix(::AbsNumFieldOrderIdeal)\nbasis_mat_inv(::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem})\nHecke.has_princ_gen_special(::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem})\nHecke.principal_generator(::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem})\nHecke.principal_generator_fac_elem(::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem})\nminimum(::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem})\nminimum(::RelNumFieldOrderIdeal)\nminimum(::AbsNumFieldOrderIdeal)\nhas_minimum(::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem})\nnorm(::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem})\nHecke.has_norm(::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem})\nidempotents(::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}, ::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem})\nis_prime(::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem})\nHecke.is_prime_known(::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem})\nis_ramified(::AbsSimpleNumFieldOrder, ::Union{Int, ZZRingElem})\nramification_index(::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem})\ndegree(::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem})\nvaluation(::AbsSimpleNumFieldElem, ::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem})\nvaluation(::AbsSimpleNumFieldOrderElem, ::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem})\nvaluation(::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}, ::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem})\nvaluation(::Integer, ::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem})\nvaluation(::ZZRingElem, ::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem})\nvaluation(::AbsSimpleNumFieldOrderFractionalIdeal, ::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem})\nidempotents(::AbsNumFieldOrderIdeal, ::AbsNumFieldOrderIdeal)","category":"page"},{"location":"Hecke/manual/orders/ideals/#order-Tuple{AbsNumFieldOrderIdeal}","page":"Ideals","title":"order","text":"order(::Type{T} = BigInt, G::Group) where T\n\nReturn the order of G as an instance of T. If G is of infinite order, an InfiniteOrderError exception will be thrown. Use is_finite(G) to avoid this kind of exception. If the order does not fit into type T, an InexactError exception will be thrown.\n\n\n\n\n\norder(::Type{T} = BigInt, g::GroupElem) where T\n\nReturn the order of g as an instance of T. If g is of infinite order, an InfiniteOrderError exception will be thrown. Use is_finite_order(G) to avoid this kind of exception. If the order does not fit into type T, an InexactError exception will be thrown.\n\n\n\n\n\norder(I::NumFieldOrderIdeal) -> AbsSimpleNumFieldOrder\n\nReturns the order of I.\n\n\n\n\n\norder(::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(::Type{T}, W::WeylGroup) where {T} -> T\n\nReturns the order of W.\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/orders/ideals/#order-Tuple{Hecke.AbsNumFieldOrderFractionalIdeal}","page":"Ideals","title":"order","text":"order(a::AbsNumFieldOrderFractionalIdeal) -> AbsNumFieldOrder\n\nThe order that was used to define the ideal a.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/orders/ideals/#order-Tuple{Hecke.RelNumFieldOrderIdeal}","page":"Ideals","title":"order","text":"order(::Type{T} = BigInt, G::Group) where T\n\nReturn the order of G as an instance of T. If G is of infinite order, an InfiniteOrderError exception will be thrown. Use is_finite(G) to avoid this kind of exception. If the order does not fit into type T, an InexactError exception will be thrown.\n\n\n\n\n\norder(::Type{T} = BigInt, g::GroupElem) where T\n\nReturn the order of g as an instance of T. If g is of infinite order, an InfiniteOrderError exception will be thrown. Use is_finite_order(G) to avoid this kind of exception. If the order does not fit into type T, an InexactError exception will be thrown.\n\n\n\n\n\norder(I::NumFieldOrderIdeal) -> AbsSimpleNumFieldOrder\n\nReturns the order of I.\n\n\n\n\n\norder(::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(::Type{T}, W::WeylGroup) where {T} -> T\n\nReturns the order of W.\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/orders/ideals/#order-Tuple{Hecke.RelNumFieldOrderFractionalIdeal}","page":"Ideals","title":"order","text":"order(a::RelNumFieldOrderFractionalIdeal) -> RelNumFieldOrder\n\nReturns the order of a.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/orders/ideals/#nf-Tuple{AbsNumFieldOrderIdeal}","page":"Ideals","title":"nf","text":"nf(x::NumFieldOrderIdeal) -> AbsSimpleNumField\n\nReturns the number field, of which x is an integral ideal.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/orders/ideals/#basis-Tuple{AbsSimpleNumFieldOrderIdeal}","page":"Ideals","title":"basis","text":"basis(A::AbsNumFieldOrderIdeal) -> Vector{AbsSimpleNumFieldOrderElem}\n\nReturns the basis of A.\n\n\n\n\n\nbasis(I::AbsNumFieldOrderFractionalIdeal) -> Vector{AbsSimpleNumFieldElem}\n\nReturns the mathbf Z-basis of I.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/orders/ideals/#lll_basis-Tuple{AbsSimpleNumFieldOrderIdeal}","page":"Ideals","title":"lll_basis","text":"lll_basis(I::NumFieldOrderIdeal) -> 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/manual/orders/ideals/#basis_matrix-Tuple{AbsNumFieldOrderIdeal}","page":"Ideals","title":"basis_matrix","text":"basis_matrix(A::AbsNumFieldOrderIdeal) -> ZZMatrix\n\nReturns the basis matrix of A.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/orders/ideals/#basis_mat_inv-Tuple{AbsSimpleNumFieldOrderIdeal}","page":"Ideals","title":"basis_mat_inv","text":"basis_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/manual/orders/ideals/#has_princ_gen_special-Tuple{AbsSimpleNumFieldOrderIdeal}","page":"Ideals","title":"has_princ_gen_special","text":"has_princ_gen_special(A::AbsNumFieldOrderIdeal) -> Bool\n\nReturns whether A knows if it is generated by a rational integer.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/orders/ideals/#principal_generator-Tuple{AbsSimpleNumFieldOrderIdeal}","page":"Ideals","title":"principal_generator","text":"principal_generator(A::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}) -> AbsSimpleNumFieldOrderElem\n\nFor a principal ideal A, find a generator.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/orders/ideals/#principal_generator_fac_elem-Tuple{AbsSimpleNumFieldOrderIdeal}","page":"Ideals","title":"principal_generator_fac_elem","text":"principal_generator_fac_elem(A::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}) -> FacElem{AbsSimpleNumFieldElem, number_field}\n\nFor a principal ideal A, find a generator in factored form.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/orders/ideals/#minimum-Tuple{AbsSimpleNumFieldOrderIdeal}","page":"Ideals","title":"minimum","text":"minimum(A::AbsNumFieldOrderIdeal) -> ZZRingElem\n\nReturns the smallest non-negative element in A cap mathbf Z.\n\n\n\n\n\n minimum(A::RelNumFieldOrderIdeal) -> AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}\n minimum(A::RelNumFieldOrderIdeal) -> RelNumFieldOrderIdeal\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/manual/orders/ideals/#minimum-Tuple{Hecke.RelNumFieldOrderIdeal}","page":"Ideals","title":"minimum","text":" minimum(A::RelNumFieldOrderIdeal) -> AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}\n minimum(A::RelNumFieldOrderIdeal) -> RelNumFieldOrderIdeal\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/manual/orders/ideals/#minimum-Tuple{AbsNumFieldOrderIdeal}","page":"Ideals","title":"minimum","text":"minimum(A::AbsNumFieldOrderIdeal) -> ZZRingElem\n\nReturns the smallest non-negative element in A cap mathbf Z.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/orders/ideals/#has_minimum-Tuple{AbsSimpleNumFieldOrderIdeal}","page":"Ideals","title":"has_minimum","text":"has_minimum(A::AbsNumFieldOrderIdeal) -> Bool\n\nReturns whether A knows its minimum.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/orders/ideals/#norm-Tuple{AbsSimpleNumFieldOrderIdeal}","page":"Ideals","title":"norm","text":"norm(A::AbsNumFieldOrderIdeal) -> 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::RelNumFieldOrderIdeal) -> AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}\n\nReturns the norm of a.\n\n\n\n\n\nnorm(a::RelNumFieldOrderFractionalIdeal{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/manual/orders/ideals/#has_norm-Tuple{AbsSimpleNumFieldOrderIdeal}","page":"Ideals","title":"has_norm","text":"has_norm(A::AbsNumFieldOrderIdeal) -> Bool\n\nReturns whether A knows its norm.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/orders/ideals/#idempotents-Tuple{AbsSimpleNumFieldOrderIdeal, AbsSimpleNumFieldOrderIdeal}","page":"Ideals","title":"idempotents","text":"idempotents(x::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}, y::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}) -> AbsSimpleNumFieldOrderElem, AbsSimpleNumFieldOrderElem\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/manual/orders/ideals/#is_prime-Tuple{AbsSimpleNumFieldOrderIdeal}","page":"Ideals","title":"is_prime","text":"is_prime(A::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}) -> Bool\n\nReturns whether A is a prime ideal.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/orders/ideals/#is_prime_known-Tuple{AbsSimpleNumFieldOrderIdeal}","page":"Ideals","title":"is_prime_known","text":"is_prime_known(A::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}) -> Bool\n\nReturns whether A knows if it is prime.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/orders/ideals/#is_ramified-Tuple{AbsSimpleNumFieldOrder, Union{Int64, ZZRingElem}}","page":"Ideals","title":"is_ramified","text":"is_ramified(O::AbsSimpleNumFieldOrder, 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/manual/orders/ideals/#ramification_index-Tuple{AbsSimpleNumFieldOrderIdeal}","page":"Ideals","title":"ramification_index","text":"ramification_index(P::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}) -> Int\n\nThe ramification index of the prime-ideal P.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/orders/ideals/#degree-Tuple{AbsSimpleNumFieldOrderIdeal}","page":"Ideals","title":"degree","text":"degree(P::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}) -> Int\n\nThe inertia degree of the prime-ideal P.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/orders/ideals/#valuation-Tuple{AbsSimpleNumFieldElem, AbsSimpleNumFieldOrderIdeal}","page":"Ideals","title":"valuation","text":"valuation(a::NumFieldElem, p::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}) -> 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/manual/orders/ideals/#valuation-Tuple{AbsSimpleNumFieldOrderElem, AbsSimpleNumFieldOrderIdeal}","page":"Ideals","title":"valuation","text":"valuation(a::AbsSimpleNumFieldElem, p::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}) -> ZZRingElem\nvaluation(a::AbsSimpleNumFieldOrderElem, p::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}) -> ZZRingElem\nvaluation(a::ZZRingElem, p::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}) -> 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/manual/orders/ideals/#valuation-Tuple{AbsSimpleNumFieldOrderIdeal, AbsSimpleNumFieldOrderIdeal}","page":"Ideals","title":"valuation","text":"valuation(A::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}, p::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}) -> 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/manual/orders/ideals/#valuation-Tuple{Integer, AbsSimpleNumFieldOrderIdeal}","page":"Ideals","title":"valuation","text":"valuation(a::Integer, p::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}) -> 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/manual/orders/ideals/#valuation-Tuple{ZZRingElem, AbsSimpleNumFieldOrderIdeal}","page":"Ideals","title":"valuation","text":"valuation(a::AbsSimpleNumFieldElem, p::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}) -> ZZRingElem\nvaluation(a::AbsSimpleNumFieldOrderElem, p::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}) -> ZZRingElem\nvaluation(a::ZZRingElem, p::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}) -> 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/manual/orders/ideals/#valuation-Tuple{AbsSimpleNumFieldOrderFractionalIdeal, AbsSimpleNumFieldOrderIdeal}","page":"Ideals","title":"valuation","text":"valuation(A::AbsNumFieldOrderFractionalIdeal, p::AbsNumFieldOrderIdeal)\n\nThe valuation of A at p.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/orders/ideals/#idempotents-Tuple{AbsNumFieldOrderIdeal, AbsNumFieldOrderIdeal}","page":"Ideals","title":"idempotents","text":"idempotents(x::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}, y::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}) -> AbsSimpleNumFieldOrderElem, AbsSimpleNumFieldOrderElem\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/manual/orders/ideals/#Quotient-Rings","page":"Ideals","title":"Quotient Rings","text":"","category":"section"},{"location":"Hecke/manual/orders/ideals/","page":"Ideals","title":"Ideals","text":"quo(::Union{AbsNumFieldOrder, AlgAssAbsOrd}, ::Union{AbsNumFieldOrderIdeal, AlgAssAbsOrdIdl})\nresidue_ring(::AbsSimpleNumFieldOrder, ::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem})\nresidue_field(::AbsSimpleNumFieldOrder, ::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}, ::Bool)\nmod(::AbsSimpleNumFieldOrderElem, ::AbsNumFieldOrderIdeal)\ncrt(::AbsSimpleNumFieldOrderElem, ::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}, ::AbsSimpleNumFieldOrderElem, ::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem})\neuler_phi(::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem})\nHecke.multiplicative_group(::AbsSimpleNumFieldOrderQuoRing)\nHecke.multiplicative_group_generators(::AbsSimpleNumFieldOrderQuoRing)","category":"page"},{"location":"Hecke/manual/orders/ideals/#quo-Tuple{Union{AbsNumFieldOrder, Hecke.AlgAssAbsOrd}, Union{AbsNumFieldOrderIdeal, Hecke.AlgAssAbsOrdIdl}}","page":"Ideals","title":"quo","text":"quo(O::AbsSimpleNumFieldOrder, I::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}) -> AbsSimpleNumFieldOrderQuoRing, 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/manual/orders/ideals/#residue_ring-Tuple{AbsSimpleNumFieldOrder, AbsSimpleNumFieldOrderIdeal}","page":"Ideals","title":"residue_ring","text":"residue_ring(O::AbsSimpleNumFieldOrder, I::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}) -> AbsSimpleNumFieldOrderQuoRing\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/manual/orders/ideals/#residue_field-Tuple{AbsSimpleNumFieldOrder, AbsSimpleNumFieldOrderIdeal, Bool}","page":"Ideals","title":"residue_field","text":"residue_field(O::AbsSimpleNumFieldOrder, P::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}, 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/manual/orders/ideals/#mod-Tuple{AbsSimpleNumFieldOrderElem, AbsNumFieldOrderIdeal}","page":"Ideals","title":"mod","text":"mod(x::AbsSimpleNumFieldOrderElem, I::AbsNumFieldOrderIdeal)\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/manual/orders/ideals/#crt-Tuple{AbsSimpleNumFieldOrderElem, AbsSimpleNumFieldOrderIdeal, AbsSimpleNumFieldOrderElem, AbsSimpleNumFieldOrderIdeal}","page":"Ideals","title":"crt","text":"crt(r1::AbsSimpleNumFieldOrderElem, i1::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}, r2::AbsSimpleNumFieldOrderElem, i2::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}) -> AbsSimpleNumFieldOrderElem\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/manual/orders/ideals/#euler_phi-Tuple{AbsSimpleNumFieldOrderIdeal}","page":"Ideals","title":"euler_phi","text":"euler_phi(A::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}) -> 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/manual/orders/ideals/#multiplicative_group-Tuple{AbsSimpleNumFieldOrderQuoRing}","page":"Ideals","title":"multiplicative_group","text":"multiplicative_group(Q::AbsSimpleNumFieldOrderQuoRing) -> FinGenAbGroup, Map{FinGenAbGroup, AbsSimpleNumFieldOrderQuoRing}\nunit_group(Q::AbsSimpleNumFieldOrderQuoRing) -> FinGenAbGroup, Map{FinGenAbGroup, AbsSimpleNumFieldOrderQuoRing}\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/manual/orders/ideals/#multiplicative_group_generators-Tuple{AbsSimpleNumFieldOrderQuoRing}","page":"Ideals","title":"multiplicative_group_generators","text":"multiplicative_group_generators(Q::AbsSimpleNumFieldOrderQuoRing) -> Vector{AbsSimpleNumFieldOrderQuoRingElem}\n\nReturn a set of generators for Q^times.\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/ideals_quorings_as_modules/","page":"Ideals and Quotient Rings as Modules","title":"Ideals and Quotient Rings as Modules","text":"CurrentModule = Oscar","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/ideals_quorings_as_modules/#Ideals-and-Quotient-Rings-as-Modules","page":"Ideals and Quotient Rings as Modules","title":"Ideals and Quotient Rings as Modules","text":"","category":"section"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/ideals_quorings_as_modules/#Ideals-as-Modules","page":"Ideals and Quotient Rings as Modules","title":"Ideals as Modules","text":"","category":"section"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/ideals_quorings_as_modules/","page":"Ideals and Quotient Rings as Modules","title":"Ideals and Quotient Rings as Modules","text":"ideal_as_module(I::Union{MPolyIdeal, MPolyQuoIdeal, MPolyLocalizedIdeal, MPolyQuoLocalizedIdeal})","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/ideals_quorings_as_modules/#ideal_as_module-Tuple{Union{MPolyIdeal, Oscar.MPolyLocalizedIdeal, MPolyQuoIdeal, Oscar.MPolyQuoLocalizedIdeal}}","page":"Ideals and Quotient Rings as Modules","title":"ideal_as_module","text":"ideal_as_module(I::Union{MPolyIdeal, MPolyQuoIdeal, MPolyLocalizedIdeal, MPolyQuoLocalizedIdeal})\n\nReturn I considered as an object of type SubquoModule.\n\nExamples\n\njulia> R, (x, y) = polynomial_ring(QQ, [:x, :y]);\n\njulia> I = ideal(R, [x^2, y^3])\nIdeal generated by\n x^2\n y^3\n\njulia> ideal_as_module(I)\nSubmodule with 2 generators\n1 -> x^2*e[1]\n2 -> y^3*e[1]\nrepresented as subquotient with no relations.\n\njulia> S, (x, y) = graded_polynomial_ring(QQ, [:x, :y]);\n\njulia> I = ideal(S, [x^2, y^3])\nIdeal generated by\n x^2\n y^3\n\njulia> ideal_as_module(I)\nGraded submodule of S^1\n1 -> x^2*e[1]\n2 -> y^3*e[1]\nrepresented as subquotient with no relations\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/ideals_quorings_as_modules/#Quotient-Rings-as-Modules","page":"Ideals and Quotient Rings as Modules","title":"Quotient Rings as Modules","text":"","category":"section"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/ideals_quorings_as_modules/","page":"Ideals and Quotient Rings as Modules","title":"Ideals and Quotient Rings as Modules","text":"quotient_ring_as_module(A::MPolyQuoRing)","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/ideals_quorings_as_modules/#quotient_ring_as_module-Tuple{MPolyQuoRing}","page":"Ideals and Quotient Rings as Modules","title":"quotient_ring_as_module","text":"quotient_ring_as_module(A::MPolyQuoRing)\n\nReturn A considered as an object of type SubquoModule.\n\nquotient_ring_as_module(I::Union{MPolyIdeal, MPolyQuoIdeal, MPolyLocalizedIdeal, MPolyQuoLocalizedIdeal})\n\nAs above, where A is the quotient of base_ring(I) modulo I.\n\nExamples\n\njulia> R, (x, y) = polynomial_ring(QQ, [:x, :y]);\n\njulia> IR = ideal(R, [x^2, y^3]);\n\njulia> quotient_ring_as_module(IR)\nSubquotient of Submodule with 1 generator\n1 -> e[1]\nby Submodule with 2 generators\n1 -> x^2*e[1]\n2 -> y^3*e[1]\n\njulia> base_ring(ans)\nMultivariate polynomial ring in 2 variables x, y\n over rational field\n\njulia> A, _ = quo(R, ideal(R,[x*y]));\n\njulia> AI = ideal(A, [x^2, y^3]);\n\njulia> quotient_ring_as_module(AI)\nSubquotient of Submodule with 1 generator\n1 -> e[1]\nby Submodule with 2 generators\n1 -> x^2*e[1]\n2 -> y^3*e[1]\n\njulia> base_ring(ans)\nQuotient\n of multivariate polynomial ring in 2 variables x, y\n over rational field\n by ideal (x*y)\n\n\njulia> S, (x, y) = graded_polynomial_ring(QQ, [:x, :y]);\n\njulia> I = ideal(S, [x^2, y^3])\nIdeal generated by\n x^2\n y^3\n\njulia> quotient_ring_as_module(I)\nGraded subquotient of submodule of S^1 generated by\n1 -> e[1]\nby submodule of S^1 generated by\n1 -> x^2*e[1]\n2 -> y^3*e[1]\n\n\n\n\n\n\n","category":"method"},{"location":"NoncommutativeAlgebra/PBWAlgebras/ideals/","page":"Ideals in PBW-algebras","title":"Ideals in PBW-algebras","text":"CurrentModule = Oscar\nDocTestSetup = Oscar.doctestsetup()","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,\nnumber_of_generators(I) / ngens(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> number_of_generators(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(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\nintersect(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 generated by\n x^3*y - x*y - y^3\n x^4 - x^2 - x*y^2\n\njulia> intersect([I, J])\nIdeal generated by\n x^3*y - x*y - y^3\n 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 generated by\n y^2\n\njulia> b = ideal(A, [x])\nIdeal generated by\n x\n\njulia> intersect(a,b)\nIdeal generated by\n x*y\n\njulia> intersect([a,b])\nIdeal generated by\n 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 R\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], 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\njulia> Rg, (x, y, z) = graded_polynomial_ring(QQ, [:x, :y, :z]);\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":"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::NormalToricVarietyType, class::FinGenAbGroupElem)\ntoric_divisor_class(v::NormalToricVarietyType, coeffs::Vector{T}) where {T <: IntegerUnion}\ntoric_divisor_class(td::ToricDivisor)","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/ToricDivisorClasses/#toric_divisor_class-Tuple{Union{AffineNormalToricVariety, CyclicQuotientSingularity, NormalToricVariety}, FinGenAbGroupElem}","page":"Toric Divisor Classes","title":"toric_divisor_class","text":"toric_divisor_class(v::NormalToricVarietyType, class::FinGenAbGroupElem)\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 toric variety\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{Union{AffineNormalToricVariety, CyclicQuotientSingularity, NormalToricVariety}, Vector{T}}} where T<:Union{Integer, ZZRingElem}","page":"Toric Divisor Classes","title":"toric_divisor_class","text":"toric_divisor_class(v::NormalToricVarietyType, 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 toric variety\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 toric variety\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::NormalToricVarietyType)\nanticanonical_divisor_class(v::NormalToricVarietyType)\ncanonical_divisor_class(v::NormalToricVarietyType)","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/ToricDivisorClasses/#trivial_divisor_class-Tuple{Union{AffineNormalToricVariety, CyclicQuotientSingularity, NormalToricVariety}}","page":"Toric Divisor Classes","title":"trivial_divisor_class","text":"trivial_divisor_class(v::NormalToricVarietyType)\n\nConstruct the trivial divisor class of a normal toric variety.\n\nExamples\n\njulia> v = projective_space(NormalToricVariety, 2)\nNormal toric variety\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{Union{AffineNormalToricVariety, CyclicQuotientSingularity, NormalToricVariety}}","page":"Toric Divisor Classes","title":"anticanonical_divisor_class","text":"anticanonical_divisor_class(v::NormalToricVarietyType)\n\nConstruct the anticanonical divisor class of a normal toric variety.\n\nExamples\n\njulia> v = projective_space(NormalToricVariety, 2)\nNormal toric variety\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{Union{AffineNormalToricVariety, CyclicQuotientSingularity, NormalToricVariety}}","page":"Toric Divisor Classes","title":"canonical_divisor_class","text":"canonical_divisor_class(v::NormalToricVarietyType)\n\nConstruct the canonical divisor class of a normal toric variety.\n\nExamples\n\njulia> v = projective_space(NormalToricVariety, 2)\nNormal toric variety\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 toric variety\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 toric variety\n\njulia> tdc = toric_divisor_class(P2, class_group(P2)([1]))\nDivisor class on a normal toric variety\n\njulia> divisor_class(tdc)\nAbelian group element [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 toric variety\n\njulia> tdc = toric_divisor_class(P2, class_group(P2)([1]))\nDivisor class on a normal toric variety\n\njulia> toric_variety(tdc)\nNormal toric variety\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 toric variety\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/OrthogonalDiscriminants/misc/","page":"Miscellaneous functions","title":"Miscellaneous functions","text":"CurrentModule = Oscar.OrthogonalDiscriminants\nDocTestSetup = Oscar.doctestsetup()","category":"page"},{"location":"Experimental/OrthogonalDiscriminants/misc/#Miscellaneous-functions","page":"Miscellaneous functions","title":"Miscellaneous functions","text":"","category":"section"},{"location":"Experimental/OrthogonalDiscriminants/misc/#Utilities","page":"Miscellaneous functions","title":"Utilities","text":"","category":"section"},{"location":"Experimental/OrthogonalDiscriminants/misc/","page":"Miscellaneous functions","title":"Miscellaneous functions","text":"is_orthogonally_stable\nshow_with_ODs\nshow_OD_info","category":"page"},{"location":"Experimental/OrthogonalDiscriminants/misc/#is_orthogonally_stable","page":"Miscellaneous functions","title":"is_orthogonally_stable","text":"is_orthogonally_stable(chi::GAPGroupClassFunction; check::Bool = true)\n\nReturn nothing if the indicator of some irreducible constituent of chi is not known; this can happen only if chi has characteristic 2.\n\nOtherwise return true if chi is orthogonally stable, and false otherwise.\n\nA character is called orthogonally stable if\n\nchi is orthogonal, that is, chi is real, and all its absolutely irreducible constituents of indicator - have even multiplicity and\nall its absolutely irreducible constituents of indicator + have even degree.\n\nIf we know that chi is orthogonal then we can set check to false; in this case, some nothing results can be avoided.\n\nExamples\n\njulia> t = character_table(\"A6\");\n\njulia> println(map(is_orthogonally_stable, t))\nBool[0, 0, 0, 1, 1, 0, 1]\n\njulia> println(map(is_orthogonally_stable, mod(t, 3)))\nBool[0, 0, 0, 1, 0]\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"function"},{"location":"Experimental/OrthogonalDiscriminants/misc/#show_with_ODs","page":"Miscellaneous functions","title":"show_with_ODs","text":"show_with_ODs(tbl::Oscar.GAPGroupCharacterTable)\n\nShow tbl with 2nd indicators, known ODs, and degrees of character fields. (See Base.show(io::IO, ::MIME\"text/plain\", tbl::Oscar.GAPGroupCharacterTable) for ways to modify what is shown.)\n\nExamples\n\njulia> t = character_table(\"A5\");\n\njulia> Oscar.OrthogonalDiscriminants.show_with_ODs(t)\nA5\n\n 2 2 2 . . .\n 3 1 . 1 . .\n 5 1 . . 1 1\n \n 1a 2a 3a 5a 5b\n 2P 1a 1a 3a 5b 5a\n 3P 1a 2a 1a 5b 5a\n 5P 1a 2a 3a 1a 1a\n d OD 2 \nX_1 1 + 1 1 1 1 1\nX_2 2 + 3 -1 . A A*\nX_3 2 + 3 -1 . A* A\nX_4 1 5 + 4 . 1 -1 -1\nX_5 1 + 5 1 -1 . .\n\nA = z_5^3 + z_5^2 + 1\nA* = -z_5^3 - z_5^2\n\n\n\n\n\n","category":"function"},{"location":"Experimental/OrthogonalDiscriminants/misc/#show_OD_info","page":"Miscellaneous functions","title":"show_OD_info","text":"show_OD_info(tbl::Oscar.GAPGroupCharacterTable)\nshow_OD_info(name::String)\n\nShow an overview of known information about the ordinary and modular orthogonal discriminants for tbl or for the character table with identifier name.\n\nExamples\n\njulia> show_OD_info(\"A5\")\nA5: 2^2*3*5\n------------\n\ni|chi|K|disc| 2| 3| 5\n-+---+-+----+--+--+--------\n4| 4a|Q| 5|4a|4a|(def. 1)\n | | | |O-|O-| \n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"function"},{"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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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(path::AbstractString; new::Bool = true, timed::Bool=false, ignore=[])\n\nRun the Oscar tests in path:\n\nif path is relative then it will be set to /test/\nif path is a directory, run all test files in that directory and below\nif path or path.jl is a file, run this file\n\nIf a directory contains a runtests.jl file only this file will be executed, otherwise all files will be included independently.\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\nWith the optional parameter timed the function will return a dict mapping file names to a named tuple with compilation times and allocations. This only works for new=false.\n\nThe parameter ignore can be used to pass a list of String or Regex patterns. Test files or folders matching these will be skipped. Strings will be compared as suffixes. This only works for new=false.\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/","page":"Introduction for new developers","title":"Introduction for new developers","text":"If a test folder contains a file called setup_tests.jl it is included automatically before each file (directly) in this directory. This can be used to define helper functions that are used in multiple test files, for example test_save_load_roundtrip for serialization.","category":"page"},{"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":"Experimental/IntersectionTheory/AbstractBundles/","page":"Abstract Bundles","title":"Abstract Bundles","text":"CurrentModule = Oscar","category":"page"},{"location":"Experimental/IntersectionTheory/AbstractBundles/#Abstract-Bundles","page":"Abstract Bundles","title":"Abstract Bundles","text":"","category":"section"},{"location":"Experimental/IntersectionTheory/AbstractBundles/#Constructors","page":"Abstract Bundles","title":"Constructors","text":"","category":"section"},{"location":"Experimental/IntersectionTheory/AbstractBundles/","page":"Abstract Bundles","title":"Abstract Bundles","text":"abstract_bundle(X::AbstractVariety, ch::Union{MPolyDecRingElem, MPolyQuoRingElem})","category":"page"},{"location":"Experimental/IntersectionTheory/AbstractBundles/#abstract_bundle-Tuple{AbstractVariety, Union{MPolyDecRingElem, MPolyQuoRingElem}}","page":"Abstract Bundles","title":"abstract_bundle","text":"abstract_bundle(X::AbstractVariety, ch::Union{MPolyDecRingElem, MPolyQuoRingElem})\nabstract_bundle(X::AbstractVariety, r::RingElement, c::Union{MPolyDecRingElem, MPolyQuoRingElem})\n\nReturn an abstract vector bundle on X by specifying its Chern character. Equivalently, specify its rank and total Chern class.\n\nExamples\n\nWe show two ways of constructing the Horrocks-Mumford bundle F [HM73]. First, we create F as the cohomology bundle of its Beilinson monad\n\n0 rightarrow mathcal O_mathbb P^4 ^5(2)rightarrow Lambda^2 T^*_mathbb P^4(5)\nrightarrow mathcal O_mathbb P^4^5(3)rightarrow 0\n\nThen, we show the constructor above at work.\n\njulia> P4 = abstract_projective_space(4)\nAbstractVariety of dim 4\n\njulia> A = 5*OO(P4, 2)\nAbstractBundle of rank 5 on AbstractVariety of dim 4\n\njulia> B = 2*exterior_power(cotangent_bundle(P4), 2)*OO(P4, 5)\nAbstractBundle of rank 12 on AbstractVariety of dim 4\n\njulia> C = 5*OO(P4, 3)\nAbstractBundle of rank 5 on AbstractVariety of dim 4\n\njulia> F = B-A-C\nAbstractBundle of rank 2 on AbstractVariety of dim 4\n\njulia> total_chern_class(F)\n10*h^2 + 5*h + 1\n\njulia> h = gens(P4)[1]\nh\n\njulia> F == abstract_bundle(P4, 2, 10*h^2 + 5*h + 1)\ntrue\n\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/IntersectionTheory/AbstractBundles/#Underlying-Data-of-an-Abstract-Bundle","page":"Abstract Bundles","title":"Underlying Data of an Abstract Bundle","text":"","category":"section"},{"location":"Experimental/IntersectionTheory/AbstractBundles/","page":"Abstract Bundles","title":"Abstract Bundles","text":"parent(F::AbstractBundle)","category":"page"},{"location":"Experimental/IntersectionTheory/AbstractBundles/#parent-Tuple{AbstractBundle}","page":"Abstract Bundles","title":"parent","text":" parent(F::AbstractBundle)\n\nReturn the underlying abstract variety of F.\n\nExamples\n\njulia> G = abstract_grassmannian(3,5)\nAbstractVariety of dim 6\n\njulia> Q = tautological_bundles(G)[2]\nAbstractBundle of rank 2 on AbstractVariety of dim 6\n\njulia> parent(Q) == G\ntrue\n\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/IntersectionTheory/AbstractBundles/","page":"Abstract Bundles","title":"Abstract Bundles","text":"rank(F::AbstractBundle)","category":"page"},{"location":"Experimental/IntersectionTheory/AbstractBundles/#rank-Tuple{AbstractBundle}","page":"Abstract Bundles","title":"rank","text":" rank(F::AbstractBundle)\n\nReturn the rank of F.\n\nExamples\n\njulia> G = abstract_grassmannian(3,5)\nAbstractVariety of dim 6\n\njulia> Q = tautological_bundles(G)[2]\nAbstractBundle of rank 2 on AbstractVariety of dim 6\n\njulia> rank(symmetric_power(Q,3))\n4\n\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/IntersectionTheory/AbstractBundles/","page":"Abstract Bundles","title":"Abstract Bundles","text":"chern_character(F::AbstractBundle)","category":"page"},{"location":"Experimental/IntersectionTheory/AbstractBundles/#chern_character-Tuple{AbstractBundle}","page":"Abstract Bundles","title":"chern_character","text":"chern_character(F::AbstractBundle)\n\nReturn the Chern character of F.\n\nExamples\n\njulia> G = abstract_grassmannian(3,5)\nAbstractVariety of dim 6\n\njulia> Q = tautological_bundles(G)[2]\nAbstractBundle of rank 2 on AbstractVariety of dim 6\n\njulia> chern_character(Q)\n-1//2*c[1]^2 + 1//6*c[1]*c[2] - 1//24*c[1]*c[3] - c[1] + c[2] - 1//3*c[3] + 2\n\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/IntersectionTheory/AbstractBundles/","page":"Abstract Bundles","title":"Abstract Bundles","text":"total_chern_class(F::AbstractBundle)","category":"page"},{"location":"Experimental/IntersectionTheory/AbstractBundles/#total_chern_class-Tuple{AbstractBundle}","page":"Abstract Bundles","title":"total_chern_class","text":"total_chern_class(F::AbstractBundle)\n\nReturn the total Chern class of F.\n\nExamples\n\njulia> G = abstract_grassmannian(3,5)\nAbstractVariety of dim 6\n\njulia> Q = tautological_bundles(G)[2]\nAbstractBundle of rank 2 on AbstractVariety of dim 6\n\njulia> total_chern_class(Q)\nc[1]^2 - c[1] - c[2] + 1\n\njulia> chern_class(Q, 1)\n-c[1]\n\njulia> chern_class(Q, 2)\nc[1]^2 - c[2]\n\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/IntersectionTheory/AbstractBundles/#Further-Data-Associated-to-an-Abstract-Bundle","page":"Abstract Bundles","title":"Further Data Associated to an Abstract Bundle","text":"","category":"section"},{"location":"Experimental/IntersectionTheory/AbstractBundles/","page":"Abstract Bundles","title":"Abstract Bundles","text":"chern_class(F::AbstractBundle, k::Int)","category":"page"},{"location":"Experimental/IntersectionTheory/AbstractBundles/#chern_class-Tuple{AbstractBundle, Int64}","page":"Abstract Bundles","title":"chern_class","text":"chern_class(F::AbstractBundle, k::Int)\n\nReturn the k-th Chern class of F.\n\nExamples\n\njulia> T, (d,) = polynomial_ring(QQ, [:d])\n(Multivariate polynomial ring in 1 variable over QQ, QQMPolyRingElem[d])\n\njulia> QT = fraction_field(T)\nFraction field\n of multivariate polynomial ring in 1 variable over QQ\n\njulia> P4 = abstract_projective_space(4, base = QT)\nAbstractVariety of dim 4\n\njulia> h = gens(P4)[1]\nh\n\njulia> F = abstract_bundle(P4, 2, 10*h^2 + 5*h + 1) # Horrocks-Mumford bundle\nAbstractBundle of rank 2 on AbstractVariety of dim 4\n\njulia> chern_class(F*OO(P4, d), 1)\n(2*d + 5)*h\n\njulia> chern_class(F*OO(P4, d), 2)\n(d^2 + 5*d + 10)*h^2\n\njulia> chern_class(F*OO(P4, -3), 1)\n-h\n\njulia> chern_class(F*OO(P4, -3), 2)\n4*h^2\n\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/IntersectionTheory/AbstractBundles/","page":"Abstract Bundles","title":"Abstract Bundles","text":"top_chern_class(F::AbstractBundle)","category":"page"},{"location":"Experimental/IntersectionTheory/AbstractBundles/#top_chern_class-Tuple{AbstractBundle}","page":"Abstract Bundles","title":"top_chern_class","text":"top_chern_class(F::AbstractBundle)\n\nReturn the top Chern class of F.\n\nExamples\n\njulia> P4 = abstract_projective_space(4)\nAbstractVariety of dim 4\n\njulia> h = gens(P4)[1]\nh\n\njulia> F = abstract_bundle(P4, 2, 10*h^2 + 5*h + 1)\nAbstractBundle of rank 2 on AbstractVariety of dim 4\n\njulia> top_chern_class(F)\n10*h^2\n\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/IntersectionTheory/AbstractBundles/","page":"Abstract Bundles","title":"Abstract Bundles","text":"total_segre_class(F::AbstractBundle)","category":"page"},{"location":"Experimental/IntersectionTheory/AbstractBundles/#total_segre_class-Tuple{AbstractBundle}","page":"Abstract Bundles","title":"total_segre_class","text":"total_segre_class(F::AbstractBundle)\n\nReturn the total Segre class of F.\n\nExamples\n\njulia> G = abstract_grassmannian(3,5)\nAbstractVariety of dim 6\n\njulia> Q = tautological_bundles(G)[2]\nAbstractBundle of rank 2 on AbstractVariety of dim 6\n\njulia> C = total_chern_class(Q)\nc[1]^2 - c[1] - c[2] + 1\n\njulia> S = total_segre_class(Q)\nc[1] + c[2] + c[3] + 1\n\njulia> C*S\n1\n\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/IntersectionTheory/AbstractBundles/","page":"Abstract Bundles","title":"Abstract Bundles","text":"segre_class(F::AbstractBundle, k::Int)","category":"page"},{"location":"Experimental/IntersectionTheory/AbstractBundles/#segre_class-Tuple{AbstractBundle, Int64}","page":"Abstract Bundles","title":"segre_class","text":"segre_class(F::AbstractBundle, k::Int)\n\nReturn the k-th Segre class of F.\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/IntersectionTheory/AbstractBundles/","page":"Abstract Bundles","title":"Abstract Bundles","text":" todd_class(F::AbstractBundle)","category":"page"},{"location":"Experimental/IntersectionTheory/AbstractBundles/#todd_class-Tuple{AbstractBundle}","page":"Abstract Bundles","title":"todd_class","text":"todd_class(F::AbstractBundle)\n\nReturn the Todd class of F.\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/IntersectionTheory/AbstractBundles/","page":"Abstract Bundles","title":"Abstract Bundles","text":"total_pontryagin_class(F::AbstractBundle)","category":"page"},{"location":"Experimental/IntersectionTheory/AbstractBundles/#total_pontryagin_class-Tuple{AbstractBundle}","page":"Abstract Bundles","title":"total_pontryagin_class","text":"total_pontryagin_class(F::AbstractBundle)\n\nReturn the total Pontryagin class of F.\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/IntersectionTheory/AbstractBundles/","page":"Abstract Bundles","title":"Abstract Bundles","text":"pontryagin_class(F::AbstractBundle, k::Int)","category":"page"},{"location":"Experimental/IntersectionTheory/AbstractBundles/#pontryagin_class-Tuple{AbstractBundle, Int64}","page":"Abstract Bundles","title":"pontryagin_class","text":"pontryagin_class(F::AbstractBundle, k::Int)\n\nReturn the k-th Pontryagin class of F.\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/IntersectionTheory/AbstractBundles/","page":"Abstract Bundles","title":"Abstract Bundles","text":"euler_characteristic(F::AbstractBundle)","category":"page"},{"location":"Experimental/IntersectionTheory/AbstractBundles/#euler_characteristic-Tuple{AbstractBundle}","page":"Abstract Bundles","title":"euler_characteristic","text":"euler_characteristic(F::AbstractBundle)\neuler_pairing(F::AbstractBundle, G::AbstractBundle)\n\nReturn the holomorphic Euler characteristic chi(F) and the Euler pairing chi(FG), respectively.\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/IntersectionTheory/AbstractBundles/","page":"Abstract Bundles","title":"Abstract Bundles","text":"hilbert_polynomial(F::AbstractBundle)","category":"page"},{"location":"Experimental/IntersectionTheory/AbstractBundles/#hilbert_polynomial-Tuple{AbstractBundle}","page":"Abstract Bundles","title":"hilbert_polynomial","text":"hilbert_polynomial(F::AbstractBundle)\n\nIf an abstract vector bundle F on an abstract variety with a specified hyperplane class is given, return the corresponding Hilbert polynomial of F.\n\nExamples\n\njulia> P2 = abstract_projective_space(2)\nAbstractVariety of dim 2\n\njulia> hilbert_polynomial(OO(P2))\n1//2*t^2 + 3//2*t + 1\n\njulia> euler_characteristic(OO(P2))\n1\n\njulia> euler_characteristic(OO(P2, 1))\n3\n\njulia> euler_characteristic(OO(P2, 2))\n6\n\njulia> euler_characteristic(OO(P2, 3))\n10\n\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/IntersectionTheory/AbstractBundles/#Operations-on-Abstract-Bundles","page":"Abstract Bundles","title":"Operations on Abstract Bundles","text":"","category":"section"},{"location":"Experimental/IntersectionTheory/AbstractBundles/","page":"Abstract Bundles","title":"Abstract Bundles","text":"-(F::AbstractBundle)","category":"page"},{"location":"Experimental/IntersectionTheory/AbstractBundles/#--Tuple{AbstractBundle}","page":"Abstract Bundles","title":"-","text":"-(F::AbstractBundle)\n*(n::RingElement, F::AbstractBundle)\n+(F::AbstractBundle, G::AbstractBundle)\n-(F::AbstractBundle, G::AbstractBundle)\n*(F::AbstractBundle, G::AbstractBundle)\n\nReturn -F, the sum F + dots + F of n copies of F, F + G, F - G, and the tensor product of F and G, respectively.\n\nExamples\n\njulia> P3 = abstract_projective_space(3)\nAbstractVariety of dim 3\n\njulia> 4*OO(P3, 1) - OO(P3) == tangent_bundle(P3) # Euler sequence\ntrue\n\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/IntersectionTheory/AbstractBundles/","page":"Abstract Bundles","title":"Abstract Bundles","text":"dual(F::AbstractBundle)","category":"page"},{"location":"Experimental/IntersectionTheory/AbstractBundles/#dual-Tuple{AbstractBundle}","page":"Abstract Bundles","title":"dual","text":"dual(F::AbstractBundle)\n\nReturn the dual bundle of F.\n\nExamples\n\njulia> P4 = abstract_projective_space(4)\nAbstractVariety of dim 4\n\njulia> h = gens(P4)[1]\nh\n\njulia> F = abstract_bundle(P4, 2, 10*h^2 + 5*h + 1) # Horrocks-Mumford bundle\nAbstractBundle of rank 2 on AbstractVariety of dim 4\n\njulia> c1 = chern_class(F, 1)\n5*h\n\njulia> Fd = dual(F)\nAbstractBundle of rank 2 on AbstractVariety of dim 4\n\njulia> chern_class(Fd, 1)\n-5*h\n\njulia> F == Fd*OO(P4, 5) # self-duality up to twist\ntrue\n\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/IntersectionTheory/AbstractBundles/","page":"Abstract Bundles","title":"Abstract Bundles","text":"det(F::AbstractBundle)","category":"page"},{"location":"Experimental/IntersectionTheory/AbstractBundles/#det-Tuple{AbstractBundle}","page":"Abstract Bundles","title":"det","text":"det(F::AbstractBundle)\n\nReturn the determinant bundle of F.\n\nExamples\n\njulia> P3 = abstract_projective_space(3)\nAbstractVariety of dim 3\n\njulia> T = tangent_bundle(P3)\nAbstractBundle of rank 3 on AbstractVariety of dim 3\n\njulia> chern_class(T, 1)\n4*h\n\njulia> det(T) == OO(P3, 4)\ntrue\n\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/IntersectionTheory/AbstractBundles/","page":"Abstract Bundles","title":"Abstract Bundles","text":"exterior_power(F::AbstractBundle, k::Int)","category":"page"},{"location":"Experimental/IntersectionTheory/AbstractBundles/#exterior_power-Tuple{AbstractBundle, Int64}","page":"Abstract Bundles","title":"exterior_power","text":"exterior_power(F::AbstractBundle, k::Int)\n\nReturn the k-th exterior power of F.\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/IntersectionTheory/AbstractBundles/","page":"Abstract Bundles","title":"Abstract Bundles","text":"symmetric_power(F::AbstractBundle, k::Int)","category":"page"},{"location":"Experimental/IntersectionTheory/AbstractBundles/#symmetric_power-Tuple{AbstractBundle, Int64}","page":"Abstract Bundles","title":"symmetric_power","text":"symmetric_power(F::AbstractBundle, k::Int)\nsymmetric_power(F::AbstractBundle, k::RingElement)\n\nReturn the k-th symmetric power of F. Here, k can contain parameters.\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"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{Symbol})","category":"page"},{"location":"AbstractAlgebra/mpoly_interface/#polynomial_ring-Tuple{Ring, Vector{Symbol}}-AbstractAlgebra-mpoly_interface","page":"Multivariate Polynomial Ring Interface","title":"polynomial_ring","text":"polynomial_ring(R::Ring, varnames::Vector{Symbol}; cached=true, internal_ordering=:lex)\n\nGiven a coefficient ring R and variable names, say varnames = [:x1, :x2, ...], return a tuple S, [x1, x2, ...] of the polynomial ring S = Rx1 x2 dots and its generators x1 x2 dots.\n\nBy default (cached=true), the output S will be cached, i.e. if polynomial_ring is invoked again with the same arguments, the same (identical) ring is returned. Setting cached to false ensures a distinct new ring is returned, and will also prevent it from being cached.\n\nThe monomial ordering used for the internal storage of polynomials in S can be set with internal_ordering and must be one of :lex, :deglex or :degrevlex.\n\nSee also: polynomial_ring(::Ring, ::Vararg), @polynomial_ring.\n\nExample\n\njulia> S, generators = polynomial_ring(ZZ, [:x, :y, :z])\n(Multivariate polynomial ring in 3 variables over integers, AbstractAlgebra.Generic.MPoly{BigInt}[x, y, z])\n\n\n\n\n\n","category":"method"},{"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":"number_of_variables(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":"internal_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":"AlgebraicGeometry/FrameWorks/ArchitectureOfAffineSchemes/","page":"Architecture of affine schemes","title":"Architecture of affine schemes","text":"CurrentModule = Oscar","category":"page"},{"location":"AlgebraicGeometry/FrameWorks/ArchitectureOfAffineSchemes/#Architecture-of-affine-schemes","page":"Architecture of affine schemes","title":"Architecture of affine schemes","text":"","category":"section"},{"location":"AlgebraicGeometry/FrameWorks/ArchitectureOfAffineSchemes/#Requirements-on-rings-and-ideals","page":"Architecture of affine schemes","title":"Requirements on rings and ideals","text":"","category":"section"},{"location":"AlgebraicGeometry/FrameWorks/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/FrameWorks/ArchitectureOfAffineSchemes/","page":"Architecture of affine schemes","title":"Architecture of affine schemes","text":"# constructor of ideals in R\nideal(R::RingType, g::Vector{<:RingElem})::Ideal\n\n# constructor for quotient rings\nquo(R::RingType, I::IdealType)::Tuple{<:Ring, <:Map}\n\n# ideal membership test\nin(f::RingElem, I::IdealType)::Bool\n\n# a (fixed) set of generators\ngens(I::IdealType)::Vector{<:RingElem}\n\n# writing an element as linear combination of the generators\ncoordinates(f::RingElem, I::IdealType)::Vector{<:RingElem}","category":"page"},{"location":"AlgebraicGeometry/FrameWorks/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 AbsAffineScheme interface.","category":"page"},{"location":"AlgebraicGeometry/FrameWorks/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/FrameWorks/ArchitectureOfAffineSchemes/","page":"Architecture of affine schemes","title":"Architecture of affine schemes","text":"saturated_ideal(I::IdealType)::MPolyIdeal","category":"page"},{"location":"AlgebraicGeometry/FrameWorks/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/FrameWorks/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/FrameWorks/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/FrameWorks/ArchitectureOfAffineSchemes/","page":"Architecture of affine schemes","title":"Architecture of affine schemes","text":"lifted_numerator(a::RingElemType)\nlifted_denominator(a::RingElemType)","category":"page"},{"location":"AlgebraicGeometry/FrameWorks/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/FrameWorks/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/FrameWorks/ArchitectureOfAffineSchemes/","page":"Architecture of affine schemes","title":"Architecture of affine schemes","text":"hom(R::RingType, S::Ring, a::Vector{<:RingElem})","category":"page"},{"location":"AlgebraicGeometry/FrameWorks/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/FrameWorks/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/FrameWorks/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/FrameWorks/ArchitectureOfAffineSchemes/","page":"Architecture of affine schemes","title":"Architecture of affine schemes","text":"The abstract type for affine schemes is","category":"page"},{"location":"AlgebraicGeometry/FrameWorks/ArchitectureOfAffineSchemes/","page":"Architecture of affine schemes","title":"Architecture of affine schemes","text":"AbsAffineScheme{BaseRingType, RingType<:Ring}","category":"page"},{"location":"AlgebraicGeometry/FrameWorks/ArchitectureOfAffineSchemes/#AbsAffineScheme","page":"Architecture of affine schemes","title":"AbsAffineScheme","text":"AbsAffineScheme{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/FrameWorks/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/FrameWorks/ArchitectureOfAffineSchemes/","page":"Architecture of affine schemes","title":"Architecture of affine schemes","text":"base_ring(X::AbsAffineScheme),\nOO(X::AbsAffineScheme).","category":"page"},{"location":"AlgebraicGeometry/FrameWorks/ArchitectureOfAffineSchemes/","page":"Architecture of affine schemes","title":"Architecture of affine schemes","text":"A concrete instance of this type is","category":"page"},{"location":"AlgebraicGeometry/FrameWorks/ArchitectureOfAffineSchemes/","page":"Architecture of affine schemes","title":"Architecture of affine schemes","text":"AffineScheme{BaseRingType, RingType}","category":"page"},{"location":"AlgebraicGeometry/FrameWorks/ArchitectureOfAffineSchemes/#AffineScheme","page":"Architecture of affine schemes","title":"AffineScheme","text":"AffineScheme{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/FrameWorks/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 MyAffineScheme<:AbsAffineScheme 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 AffineScheme in MyAffineScheme and implement the methods","category":"page"},{"location":"AlgebraicGeometry/FrameWorks/ArchitectureOfAffineSchemes/","page":"Architecture of affine schemes","title":"Architecture of affine schemes","text":"underlying_scheme(X::MyAffineScheme)::AffineScheme # return Y as above","category":"page"},{"location":"AlgebraicGeometry/FrameWorks/ArchitectureOfAffineSchemes/","page":"Architecture of affine schemes","title":"Architecture of affine schemes","text":"Then all methods implemented for AffineScheme are automatically forwarded to any instance of MyAffineScheme.","category":"page"},{"location":"AlgebraicGeometry/FrameWorks/ArchitectureOfAffineSchemes/","page":"Architecture of affine schemes","title":"Architecture of affine schemes","text":"Note: The above method necessarily returns an instance of AffineScheme! Of course, it can be overwritten for any higher type MyAffineScheme<:AbsAffineScheme as needed.","category":"page"},{"location":"AlgebraicGeometry/FrameWorks/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/FrameWorks/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/FrameWorks/ArchitectureOfAffineSchemes/","page":"Architecture of affine schemes","title":"Architecture of affine schemes","text":"AbsAffineSchemeMor{DomainType<:AbsAffineScheme,\n CodomainType<:AbsAffineScheme,\n PullbackType<:Map,\n MorphismType,\n BaseMorType\n }","category":"page"},{"location":"AlgebraicGeometry/FrameWorks/ArchitectureOfAffineSchemes/#AbsAffineSchemeMor","page":"Architecture of affine schemes","title":"AbsAffineSchemeMor","text":"AbsAffineSchemeMor{DomainType<:AbsAffineScheme,\n CodomainType<:AbsAffineScheme,\n PullbackType<: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/FrameWorks/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 AffineSchemeMor:","category":"page"},{"location":"AlgebraicGeometry/FrameWorks/ArchitectureOfAffineSchemes/","page":"Architecture of affine schemes","title":"Architecture of affine schemes","text":"AffineSchemeMor{DomainType<:AbsAffineScheme,\n CodomainType<:AbsAffineScheme,\n PullbackType<:Map\n }","category":"page"},{"location":"AlgebraicGeometry/FrameWorks/ArchitectureOfAffineSchemes/#AffineSchemeMor","page":"Architecture of affine schemes","title":"AffineSchemeMor","text":"AffineSchemeMor{DomainType<:AbsAffineScheme,\n CodomainType<:AbsAffineScheme,\n PullbackType<: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/FrameWorks/ArchitectureOfAffineSchemes/","page":"Architecture of affine schemes","title":"Architecture of affine schemes","text":"This basic functionality consists of","category":"page"},{"location":"AlgebraicGeometry/FrameWorks/ArchitectureOfAffineSchemes/","page":"Architecture of affine schemes","title":"Architecture of affine schemes","text":"compose(f::AbsAffineSchemeMor, g::AbsAffineSchemeMor),\nidentity_map(X::AbsAffineScheme),\nrestrict(f::AbsAffineSchemeMor, X::AbsAffineScheme, Y::AbsAffineScheme; check::Bool=true),\n==(f::AbsAffineSchemeMor, g::AbsAffineSchemeMor),\npreimage(f::AbsAffineSchemeMor, Z::AbsAffineScheme).","category":"page"},{"location":"AlgebraicGeometry/FrameWorks/ArchitectureOfAffineSchemes/","page":"Architecture of affine schemes","title":"Architecture of affine schemes","text":"In particular, for every concrete instance of a type MyAffineScheme<:AbsAffineScheme that implements underlying_scheme, this basic functionality of AffineSchemeMor should run naturally.","category":"page"},{"location":"AlgebraicGeometry/FrameWorks/ArchitectureOfAffineSchemes/","page":"Architecture of affine schemes","title":"Architecture of affine schemes","text":"We may derive higher types of morphisms of affine schemes MyAffineSchemeMor<:AbsAffineSchemeMor by storing an instance g of AffineSchemeMor inside an instance f of MyAffineSchemeMor and implementing","category":"page"},{"location":"AlgebraicGeometry/FrameWorks/ArchitectureOfAffineSchemes/","page":"Architecture of affine schemes","title":"Architecture of affine schemes","text":"underlying_morphism(f::MyAffineSchemeMor)::AffineSchemeMor # return g","category":"page"},{"location":"AlgebraicGeometry/FrameWorks/ArchitectureOfAffineSchemes/","page":"Architecture of affine schemes","title":"Architecture of affine schemes","text":"For example, this allows us to define closed embeddings.","category":"page"},{"location":"PolyhedralGeometry/Polyhedra/polymake/","page":"Polyhedron and polymake's Polytope","title":"Polyhedron and polymake's Polytope","text":"CurrentModule = Oscar\nDocTestSetup = Oscar.doctestsetup()","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 ([GJ00], polymake.org) is open source software for research in polyhedral geometry and is attached to Julia via Polymake.jl ([KLT20], 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)\nPolytope 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/manual/quad_forms/basics/#Spaces2","page":"Spaces","title":"Spaces","text":"","category":"section"},{"location":"Hecke/manual/quad_forms/basics/","page":"Spaces","title":"Spaces","text":"CurrentModule = Hecke\nDocTestSetup = quote\n using Hecke\nend","category":"page"},{"location":"Hecke/manual/quad_forms/basics/#Creation-of-spaces","page":"Spaces","title":"Creation of spaces","text":"","category":"section"},{"location":"Hecke/manual/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/manual/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/manual/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/manual/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/manual/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/manual/quad_forms/basics/#Examples","page":"Spaces","title":"Examples","text":"","category":"section"},{"location":"Hecke/manual/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/manual/quad_forms/basics/","page":"Spaces","title":"Spaces","text":"using Hecke # hide\nK, a = cyclotomic_real_subfield(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/manual/quad_forms/basics/","page":"Spaces","title":"Spaces","text":"","category":"page"},{"location":"Hecke/manual/quad_forms/basics/#Attributes","page":"Spaces","title":"Attributes","text":"","category":"section"},{"location":"Hecke/manual/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/manual/quad_forms/basics/","page":"Spaces","title":"Spaces","text":"While dealing with lattices, one always works with regular ambient spaces.","category":"page"},{"location":"Hecke/manual/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/manual/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/manual/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/manual/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/manual/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/manual/quad_forms/basics/#involution-Tuple{AbstractSpace}","page":"Spaces","title":"involution","text":"involution(V::AbstractSpace) -> NumFieldHom\n\nReturn the involution of the space V.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/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/manual/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/manual/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/manual/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/manual/quad_forms/basics/#Examples-2","page":"Spaces","title":"Examples","text":"","category":"section"},{"location":"Hecke/manual/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/manual/quad_forms/basics/","page":"Spaces","title":"Spaces","text":"using Hecke # hide\nK, a = cyclotomic_real_subfield(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/manual/quad_forms/basics/","page":"Spaces","title":"Spaces","text":"","category":"page"},{"location":"Hecke/manual/quad_forms/basics/#Predicates","page":"Spaces","title":"Predicates","text":"","category":"section"},{"location":"Hecke/manual/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/manual/quad_forms/basics/","page":"Spaces","title":"Spaces","text":"is_regular(::AbstractSpace)\nis_quadratic(::AbstractSpace)\nis_hermitian(::AbstractSpace)\nis_positive_definite(::AbstractSpace)\nis_negative_definite(::AbstractSpace)\nis_definite(::AbstractSpace)","category":"page"},{"location":"Hecke/manual/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/manual/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/manual/quad_forms/basics/#is_hermitian-Tuple{AbstractSpace}","page":"Spaces","title":"is_hermitian","text":"is_hermitian(V::AbstractSpace) -> Bool\n\nReturn whether the space V is hermitian.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/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/manual/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/manual/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/manual/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/manual/quad_forms/basics/#Examples-3","page":"Spaces","title":"Examples","text":"","category":"section"},{"location":"Hecke/manual/quad_forms/basics/","page":"Spaces","title":"Spaces","text":"using Hecke # hide\nK, a = cyclotomic_real_subfield(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), is_hermitian(H)\nis_definite(Q), is_positive_definite(H)","category":"page"},{"location":"Hecke/manual/quad_forms/basics/","page":"Spaces","title":"Spaces","text":"","category":"page"},{"location":"Hecke/manual/quad_forms/basics/#Inner-products-and-diagonalization","page":"Spaces","title":"Inner products and diagonalization","text":"","category":"section"},{"location":"Hecke/manual/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)\ndiagonal_with_transform(::AbstractSpace)\nrestrict_scalars(::AbstractSpace, ::QQField, ::FieldElem)","category":"page"},{"location":"Hecke/manual/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/manual/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/manual/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/manual/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/manual/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/manual/quad_forms/basics/#diagonal_with_transform-Tuple{AbstractSpace}","page":"Spaces","title":"diagonal_with_transform","text":"diagonal_with_transform(V::AbstractSpace) -> Vector{FieldElem},\n MatElem{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. The second output is a matrix U whose rows span an orthogonal basis of V for which the Gram matrix is given by the diagonal matrix of the a_i's.\n\nThe elements are contained in the fixed field of V.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/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/manual/quad_forms/basics/#Examples-4","page":"Spaces","title":"Examples","text":"","category":"section"},{"location":"Hecke/manual/quad_forms/basics/","page":"Spaces","title":"Spaces","text":"using Hecke # hide\nK, a = cyclotomic_real_subfield(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/manual/quad_forms/basics/","page":"Spaces","title":"Spaces","text":"","category":"page"},{"location":"Hecke/manual/quad_forms/basics/#Equivalence","page":"Spaces","title":"Equivalence","text":"","category":"section"},{"location":"Hecke/manual/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/manual/quad_forms/basics/","page":"Spaces","title":"Spaces","text":" Phi(f(x) f(y)) = Phi(xy)","category":"page"},{"location":"Hecke/manual/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/manual/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/manual/quad_forms/basics/#hasse_invariant-Tuple{Hecke.QuadSpace, Any}","page":"Spaces","title":"hasse_invariant","text":"hasse_invariant(V::QuadSpace, p::Union{InfPlc, AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}}) -> 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/manual/quad_forms/basics/#witt_invariant-Tuple{Hecke.QuadSpace, Any}","page":"Spaces","title":"witt_invariant","text":"witt_invariant(V::QuadSpace, p::Union{InfPlc, AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}}) -> 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/manual/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/manual/quad_forms/basics/#is_isometric-Tuple{AbstractSpace, AbstractSpace, Any}","page":"Spaces","title":"is_isometric","text":"is_isometric(L::AbstractSpace, M::AbstractSpace, p::Union{InfPlc, AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}}) -> 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/manual/quad_forms/basics/#invariants-Tuple{Hecke.QuadSpace}","page":"Spaces","title":"invariants","text":"invariants(M::QuadSpace)\n -> FieldElem, Dict{AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}, 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/manual/quad_forms/basics/#Examples-5","page":"Spaces","title":"Examples","text":"","category":"section"},{"location":"Hecke/manual/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/manual/quad_forms/basics/","page":"Spaces","title":"Spaces","text":"using Hecke # hide\nK, a = cyclotomic_real_subfield(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/manual/quad_forms/basics/","page":"Spaces","title":"Spaces","text":"","category":"page"},{"location":"Hecke/manual/quad_forms/basics/#Embeddings","page":"Spaces","title":"Embeddings","text":"","category":"section"},{"location":"Hecke/manual/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/manual/quad_forms/basics/","page":"Spaces","title":"Spaces","text":" Phi(sigma(x) sigma(x)) = Phi(xx)","category":"page"},{"location":"Hecke/manual/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/manual/quad_forms/basics/","page":"Spaces","title":"Spaces","text":"is_locally_represented_by(::AbstractSpace, ::AbstractSpace, p)\nis_represented_by(::AbstractSpace, ::AbstractSpace)","category":"page"},{"location":"Hecke/manual/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::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}) 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/manual/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/manual/quad_forms/basics/#Examples-6","page":"Spaces","title":"Examples","text":"","category":"section"},{"location":"Hecke/manual/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/manual/quad_forms/basics/","page":"Spaces","title":"Spaces","text":"using Hecke # hide\nK, a = cyclotomic_real_subfield(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/manual/quad_forms/basics/","page":"Spaces","title":"Spaces","text":"","category":"page"},{"location":"Hecke/manual/quad_forms/basics/#Categorical-constructions","page":"Spaces","title":"Categorical constructions","text":"","category":"section"},{"location":"Hecke/manual/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/manual/quad_forms/basics/","page":"Spaces","title":"Spaces","text":"direct_sum(::Vector{AbstractSpace})\ndirect_product(::Vector{AbstractSpace})\nbiproduct(::Vector{AbstractSpace})","category":"page"},{"location":"Hecke/manual/quad_forms/basics/#direct_sum-Tuple{Vector{AbstractSpace}}","page":"Spaces","title":"direct_sum","text":"direct_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\ndirect_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":"Hecke/manual/quad_forms/basics/#direct_product-Tuple{Vector{AbstractSpace}}","page":"Spaces","title":"direct_product","text":"direct_product(algebras::StructureConstantAlgebra...; task::Symbol = :sum)\n -> StructureConstantAlgebra, Vector{AbsAlgAssMor}, Vector{AbsAlgAssMor}\ndirect_product(algebras::Vector{StructureConstantAlgebra}; task::Symbol = :sum)\n -> StructureConstantAlgebra, 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\ndirect_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\n","category":"method"},{"location":"Hecke/manual/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/manual/quad_forms/basics/#Example","page":"Spaces","title":"Example","text":"","category":"section"},{"location":"Hecke/manual/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/manual/quad_forms/basics/#Orthogonality-operations","page":"Spaces","title":"Orthogonality operations","text":"","category":"section"},{"location":"Hecke/manual/quad_forms/basics/","page":"Spaces","title":"Spaces","text":"orthogonal_complement(::AbstractSpace, ::MatElem)\northogonal_projection(::AbstractSpace, ::MatElem)","category":"page"},{"location":"Hecke/manual/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/manual/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/manual/quad_forms/basics/#Example-2","page":"Spaces","title":"Example","text":"","category":"section"},{"location":"Hecke/manual/quad_forms/basics/","page":"Spaces","title":"Spaces","text":"using Hecke # hide\nK, a = cyclotomic_real_subfield(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/manual/quad_forms/basics/","page":"Spaces","title":"Spaces","text":"","category":"page"},{"location":"Hecke/manual/quad_forms/basics/#Isotropic-spaces","page":"Spaces","title":"Isotropic spaces","text":"","category":"section"},{"location":"Hecke/manual/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/manual/quad_forms/basics/","page":"Spaces","title":"Spaces","text":"is_isotropic(::AbstractSpace, p)","category":"page"},{"location":"Hecke/manual/quad_forms/basics/#is_isotropic-Tuple{AbstractSpace, Any}","page":"Spaces","title":"is_isotropic","text":"is_isotropic(V::AbstractSpace, p::Union{AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}, 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/manual/quad_forms/basics/#Example-3","page":"Spaces","title":"Example","text":"","category":"section"},{"location":"Hecke/manual/quad_forms/basics/","page":"Spaces","title":"Spaces","text":"using Hecke # hide\nK, a = cyclotomic_real_subfield(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/manual/quad_forms/basics/","page":"Spaces","title":"Spaces","text":"","category":"page"},{"location":"Hecke/manual/quad_forms/basics/#Hyperbolic-spaces","page":"Spaces","title":"Hyperbolic spaces","text":"","category":"section"},{"location":"Hecke/manual/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/manual/quad_forms/basics/","page":"Spaces","title":"Spaces","text":"is_locally_hyperbolic(::HermSpace, ::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem})","category":"page"},{"location":"Hecke/manual/quad_forms/basics/#is_locally_hyperbolic-Tuple{Hecke.HermSpace, AbsSimpleNumFieldOrderIdeal}","page":"Spaces","title":"is_locally_hyperbolic","text":"is_locally_hyperbolic(V::Hermspace, p::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}) -> 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/manual/quad_forms/basics/#Example-4","page":"Spaces","title":"Example","text":"","category":"section"},{"location":"Hecke/manual/quad_forms/basics/","page":"Spaces","title":"Spaces","text":"using Hecke # hide\nK, a = cyclotomic_real_subfield(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":"Experimental/OrthogonalDiscriminants/compute/","page":"Criteria for computing orthogonal discriminants","title":"Criteria for computing orthogonal discriminants","text":"CurrentModule = Oscar.OrthogonalDiscriminants\nDocTestSetup = Oscar.doctestsetup()","category":"page"},{"location":"Experimental/OrthogonalDiscriminants/compute/#Criteria-for-computing-orthogonal-discriminants","page":"Criteria for computing orthogonal discriminants","title":"Criteria for computing orthogonal discriminants","text":"","category":"section"},{"location":"Experimental/OrthogonalDiscriminants/compute/#Direct-methods","page":"Criteria for computing orthogonal discriminants","title":"Direct methods","text":"","category":"section"},{"location":"Experimental/OrthogonalDiscriminants/compute/","page":"Criteria for computing orthogonal discriminants","title":"Criteria for computing orthogonal discriminants","text":"od_from_atlas_group","category":"page"},{"location":"Experimental/OrthogonalDiscriminants/compute/#od_from_atlas_group","page":"Criteria for computing orthogonal discriminants","title":"od_from_atlas_group","text":"od_from_atlas_group(chi::GAPGroupClassFunction)\n\nReturn (flag, val) where flag is true if the function can compute the orthogonal discriminant of chi. In this case, val is a string that describes the orthogonal discriminant of chi.\n\nOtherwise flag is false and val is \"\".\n\nThe former case happens if chi is absolutely irreducible, has even degree and indicator +, and the Atlas of Group Representations contains a representation affording chi, over the character field of chi or (in odd characteristic) a suitable extension field.\n\nIf the characteristic of chi is 2 then we know no better method than calling orthogonal_sign. Otherwise we try to find an invertible skew-symmetric endomorphism w.r.t. the invariant bilinear form of the representation, with random methods.\n\njulia> t = character_table(\"A6\");\n\njulia> Oscar.OrthogonalDiscriminants.od_from_atlas_group(t[7])\n(true, \"-1\")\n\njulia> Oscar.OrthogonalDiscriminants.od_from_atlas_group(mod(t, 3)[4])\n(true, \"O-\")\n\njulia> t = character_table(\"L2(27)\");\n\njulia> Oscar.OrthogonalDiscriminants.od_from_atlas_group(t[4])\n(false, \"\")\n\n\n\n\n\n","category":"function"},{"location":"Experimental/OrthogonalDiscriminants/compute/#Character-theoretical-criteria","page":"Criteria for computing orthogonal discriminants","title":"Character-theoretical criteria","text":"","category":"section"},{"location":"Experimental/OrthogonalDiscriminants/compute/","page":"Criteria for computing orthogonal discriminants","title":"Criteria for computing orthogonal discriminants","text":"od_from_order\nod_from_eigenvalues\nod_for_specht_module\nod_from_p_subgroup(chi::GAPGroupClassFunction, p::Int)","category":"page"},{"location":"Experimental/OrthogonalDiscriminants/compute/#od_from_order","page":"Criteria for computing orthogonal discriminants","title":"od_from_order","text":"od_from_order(chi::GAPGroupClassFunction)\n\nReturn (flag, val) where flag is true if the order of the group of chi divides only one of the orders of the two orthogonal groups omega_group(+/-1, d, q), where d is the degree of chi and q is the order of the field of definition of chi.\n\nIn this case, val is \"O+\" or \"O-\".\n\njulia> t = character_table(\"L3(2)\");\n\njulia> Oscar.OrthogonalDiscriminants.od_from_order(mod(t, 3)[4])\n(true, \"O-\")\n\njulia> Oscar.OrthogonalDiscriminants.od_from_order(mod(t, 2)[4])\n(false, \"\")\n\n\n\n\n\n","category":"function"},{"location":"Experimental/OrthogonalDiscriminants/compute/#od_from_eigenvalues","page":"Criteria for computing orthogonal discriminants","title":"od_from_eigenvalues","text":"od_from_eigenvalues(chi::GAPGroupClassFunction)\n\nReturn (flag, val) where flag is true if there is a conjugacy class on which representing matrices for chi have no eigenvalue pm 1. In this case, if chi is orthogonally stable (this is not checked here) then val is a string that describes the orthogonal discriminant of chi.\n\nIf flag is false then val is equal to \"\".\n\nThis criterion works only if the characteristic of chi is not 2, (false, \"\") is returned if the characteristic is 2.\n\nExamples\n\njulia> t = character_table(\"A5\");\n\njulia> Oscar.OrthogonalDiscriminants.od_from_eigenvalues(t[4])\n(true, \"5\")\n\njulia> Oscar.OrthogonalDiscriminants.od_from_eigenvalues(mod(t, 3)[4])\n(true, \"O-\")\n\njulia> Oscar.OrthogonalDiscriminants.od_from_eigenvalues(mod(t, 2)[4])\n(false, \"\")\n\n\n\n\n\n","category":"function"},{"location":"Experimental/OrthogonalDiscriminants/compute/#od_for_specht_module","page":"Criteria for computing orthogonal discriminants","title":"od_for_specht_module","text":"od_for_specht_module(chi::GAPGroupClassFunction)\n\nReturn (flag, val) where flag is true if chi is an ordinary irreducible character of a symmetric group or of an alternating group such that chi extends to the corresponding symmetric group. In this case, if chi is orthogonally stable (this is not checked here) then val is a string that describes the orthogonal discriminant of chi; the discriminant is computed using the Jantzen-Schaper formula, via gram_determinant_specht_module.\n\n(false, \"\") is returned in all cases where this criterion is not applicable.\n\nExamples\n\njulia> t = character_table(\"A5\");\n\njulia> Oscar.OrthogonalDiscriminants.od_for_specht_module(t[4])\n(true, \"5\")\n\njulia> Oscar.OrthogonalDiscriminants.od_for_specht_module(mod(t, 3)[4])\n(false, \"\")\n\n\n\n\n\n","category":"function"},{"location":"Experimental/OrthogonalDiscriminants/compute/#od_from_p_subgroup-Tuple{Oscar.GAPGroupClassFunction, Int64}","page":"Criteria for computing orthogonal discriminants","title":"od_from_p_subgroup","text":"od_from_p_subgroup(chi::GAPGroupClassFunction, p::Int[, pi::GAPGroupClassFunction])\n\nLet chi be an irreducible (ordinary or Brauer) character of the group G, and p be an odd prime integer.\n\nReturn (flag, val) where flag is true if and only if enough information can be computed to prove that the restriction of chi to a Sylow p-subgroup P is orthogonally stable. In this case, val is a string that describes the orthogonal discriminant of chi.\n\nIf flag is false then val is equal to \"\".\n\nIf a character is given as the optional argument pi then it is assumed that pi is the permutation character of G induced from P. Otherwise the function tries to compute the possible permutation characters.\n\nExamples\n\njulia> t = character_table(\"A5\");\n\njulia> Oscar.OrthogonalDiscriminants.od_from_p_subgroup(t[4], 5)\n(true, \"5\")\n\njulia> Oscar.OrthogonalDiscriminants.od_from_p_subgroup(mod(t, 3)[4], 5)\n(true, \"O-\")\n\njulia> Oscar.OrthogonalDiscriminants.od_from_p_subgroup(mod(t, 2)[4], 5)\n(true, \"O-\")\n\n\n\n\n\n","category":"method"},{"location":"Experimental/AlgebraicStatistics/introduction/","page":"Introduction","title":"Introduction","text":"CurrentModule = Oscar\nDocTestSetup = Oscar.doctestsetup()","category":"page"},{"location":"Experimental/AlgebraicStatistics/introduction/#Introduction","page":"Introduction","title":"Introduction","text":"","category":"section"},{"location":"Experimental/AlgebraicStatistics/introduction/","page":"Introduction","title":"Introduction","text":"Algebraic Statistics uses tools from algebra, geometry, and combinatorics to solve problems in statistics. In particular, since many parametric statistical models are parametrized by rational functions of their parameters, they can be viewed as algebraic varieties. This part of OSCAR provides functionality for working with the following commonly used models:","category":"page"},{"location":"Experimental/AlgebraicStatistics/introduction/","page":"Introduction","title":"Introduction","text":"undirected and directed Gaussian graphical models\nundirected and directed discrete graphical models\nphylogenetic Markov models on trees and networks \ndiscrete and Gaussian conditional independence models","category":"page"},{"location":"Experimental/AlgebraicStatistics/introduction/","page":"Introduction","title":"Introduction","text":"Most of the above models are graphical models which are parametric statistical models mathcalM_G associated to a graph G. In all of the cases described above, the model mathcalM_G = phi_G where phi_G is a rational map. Key features include:","category":"page"},{"location":"Experimental/AlgebraicStatistics/introduction/","page":"Introduction","title":"Introduction","text":"Constructing and working with the parametrizations phi_G\nComputing a (partial) generating set of textker(phi_G)\nDetermining the local and global conditional independence statements implied by G\nConstructing critical ideals and computing maximum likelihood and euclidean distance degrees","category":"page"},{"location":"Experimental/AlgebraicStatistics/introduction/","page":"Introduction","title":"Introduction","text":"General textbooks offering details on theory and algorithms include:","category":"page"},{"location":"Experimental/AlgebraicStatistics/introduction/","page":"Introduction","title":"Introduction","text":"[Sul18]\n[DSS09]","category":"page"},{"location":"Experimental/AlgebraicStatistics/introduction/#Contact","page":"Introduction","title":"Contact","text":"","category":"section"},{"location":"Experimental/AlgebraicStatistics/introduction/","page":"Introduction","title":"Introduction","text":"Please direct questions about this part of OSCAR to the following people:","category":"page"},{"location":"Experimental/AlgebraicStatistics/introduction/","page":"Introduction","title":"Introduction","text":"Benjamin Hollering\nMarina Garrote López\nTobias Boege","category":"page"},{"location":"Nemo/constructors/","page":"Constructing mathematical objects in Nemo","title":"Constructing mathematical objects in Nemo","text":"CurrentModule = Nemo\nDocTestSetup = quote\n using Nemo\nend","category":"page"},{"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":"julia> BigInt(1234567898765434567898765434567876543456787654567890)\n1234567898765434567898765434567876543456787654567890","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":"julia> m = BigInt(123)\n123","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":"julia> n = ZZ(12345678765456787654567890987654567898765678909876567890)\n12345678765456787654567890987654567898765678909876567890","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":"julia> R, x = polynomial_ring(ZZ, \"x\")\n(Univariate polynomial ring in x over ZZ, x)\n\njulia> f = x^3 + 3x + 1\nx^3 + 3*x + 1\n\njulia> g = R(12)\n12","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 = finite_field(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 S = RealField()\nS = mathbbC S = ComplexField()","category":"page"},{"location":"Experimental/GroebnerWalk/special-ideals/","page":"Special ideals used for benchmarking","title":"Special ideals used for benchmarking","text":"CurrentModule = Oscar","category":"page"},{"location":"Experimental/GroebnerWalk/special-ideals/#Special-ideals-used-for-benchmarking","page":"Special ideals used for benchmarking","title":"Special ideals used for benchmarking","text":"","category":"section"},{"location":"Experimental/GroebnerWalk/special-ideals/","page":"Special ideals used for benchmarking","title":"Special ideals used for benchmarking","text":"We bundle a couple of special ideals useful for benchmarking of the Gröbner walk.","category":"page"},{"location":"Experimental/GroebnerWalk/special-ideals/","page":"Special ideals used for benchmarking","title":"Special ideals used for benchmarking","text":" newell_patch(k::Union{QQField, QQBarFieldElem}, n::Int=1)\n newell_patch(k::Field, n::Int=1)","category":"page"},{"location":"Experimental/GroebnerWalk/special-ideals/#newell_patch","page":"Special ideals used for benchmarking","title":"newell_patch","text":"newell_patch(k::Union{QQField, QQBarFieldElem}, n::Int=1)\n\nLet n be an integer between 1 and 32. Returns the ideal corresponding to the implicitization of the n-th bi-cubic patch describing the Newell's teapot as a parametric surface.\n\nThe specific generators for each patch have been taken from [Tra04].\n\n\n\n\n\n","category":"function"},{"location":"Experimental/GroebnerWalk/special-ideals/#newell_patch-2","page":"Special ideals used for benchmarking","title":"newell_patch","text":"newell_patch(k::Field, n::Int=1)\n\nLet n be an integer between 1 and 32. Returns the ideal corresponding to the implicitization of the n-th bi-cubic patch describing the Newell's teapot as a parametric surface.\n\nThe specific generators for each patch have been taken from [Tra04].\n\nFor fields kneqmathbbQbarmathbbQ, this gives a variant of the ideal with integer coefficients.\n\n\n\n\n\n","category":"function"},{"location":"Experimental/GroebnerWalk/special-ideals/","page":"Special ideals used for benchmarking","title":"Special ideals used for benchmarking","text":" newell_patch_with_orderings(k::Field, n::Int=1)","category":"page"},{"location":"Experimental/GroebnerWalk/special-ideals/#newell_patch_with_orderings","page":"Special ideals used for benchmarking","title":"newell_patch_with_orderings","text":"newell_patch_with_orderings(k::Field, n::Int=1)\n\nLet n be an integer between 1 and 32. Returns the ideal corresponding to the implicitization of the n-th bi-cubic patch describing the Newell's teapot as a parametric surface. Additionally returns suitable start and target orderings, e.g. for use with the Gröbner walk.\n\nThe specific generators for each patch have been taken from [Tra04].\n\nFor fields kneqmathbbQbarmathbbQ, this gives a variant of the ideal with integer coefficients.\n\n\n\n\n\n","category":"function"},{"location":"Experimental/LieAlgebras/ideals_and_subalgebras/","page":"Ideals and Lie subalgebras","title":"Ideals and Lie subalgebras","text":"CurrentModule = Oscar\nDocTestSetup = Oscar.doctestsetup()","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{C}, ::LieAlgebraIdeal{C}) where {C<:FieldElem}\nbracket(::LieAlgebraIdeal{C,LieT}, ::LieAlgebraIdeal{C,LieT}) where {C<:FieldElem,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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/ideals_and_subalgebras/#in-Union{Tuple{C}, Tuple{LieAlgebraElem{C}, LieAlgebraIdeal{C, LieT} where LieT<:LieAlgebraElem{C}}} where C<:FieldElem","page":"Ideals and Lie subalgebras","title":"in","text":"in(x::LieAlgebraElem{C}, I::LieAlgebraIdeal{C}) -> Bool\n\nReturn true if x is in the ideal I, false otherwise.\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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<:FieldElem, LieT<:LieAlgebraElem{C}}","page":"Ideals and Lie subalgebras","title":"bracket","text":"bracket(I1::LieAlgebraIdeal, I2::LieAlgebraIdeal) -> LieAlgebraIdeal\n\nReturn I_1I_2.\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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{C}, ::LieSubalgebra{C}) where {C<:FieldElem}\nbracket(::LieSubalgebra{C,LieT}, ::LieSubalgebra{C,LieT}) where {C<:FieldElem,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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/ideals_and_subalgebras/#in-Union{Tuple{C}, Tuple{LieAlgebraElem{C}, LieSubalgebra{C, LieT} where LieT<:LieAlgebraElem{C}}} where C<:FieldElem","page":"Ideals and Lie subalgebras","title":"in","text":"in(x::LieAlgebraElem{C}, S::LieSubalgebra{C}) -> Bool\n\nReturn true if x is in the Lie subalgebra S, false otherwise.\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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<:FieldElem, LieT<:LieAlgebraElem{C}}","page":"Ideals and Lie subalgebras","title":"bracket","text":"bracket(S1::LieSubalgebra, S2::LieSubalgebra) -> LieAlgebraIdeal\n\nReturn S_1 S_2.\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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<:FieldElem}\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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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<:FieldElem","page":"Ideals and Lie subalgebras","title":"ideal","text":"ideal(L::LieAlgebra, gen::LieAlgebraElem) -> LieAlgebraIdeal\n\nReturn the smallest ideal of L containing gen.\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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<:FieldElem}\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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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<:FieldElem","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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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<:FieldElem}","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 LS, together with an embedding LS -> L, where L is the Lie algebra where S lives in.\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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 LI, together with an embedding LI -> L, where L is the Lie algebra where I lives in.\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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<:FieldElem","page":"Ideals and Lie subalgebras","title":"sub","text":"sub(L::LieAlgebra, I::LieAlgebraIdeal) -> LieSubalgebra\n\nReturn I as a subalgebra of L.\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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 = incidence_matrix([[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 = incidence_matrix([[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\npolyhedral_complex(polytopes::AbstractVector{Polyhedron{T}}) where T<:scalar_types\n\nAssemble a polyhedral complex from a non-empty list of polyhedra.\n\n\n\n\n\npolyhedral_complex(F::PolyhedralFan)\n\nTurn a polyhedral fan into a polyhedral complex.\n\n\n\n\n\npolyhedral_complex(TropV::TropicalVariety)\n\nReturn the polyhedral complex of a tropical variety.\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)\nis_pure(PC::PolyhedralComplex)\nis_simplicial(PC::PolyhedralComplex)\nlineality_dim(PC::PolyhedralComplex)\nlineality_space(PC::PolyhedralComplex{T}) where T<:scalar_types\nmaximal_polyhedra(PC::PolyhedralComplex{T}) where T<:scalar_types\nminimal_faces(PC::PolyhedralComplex{T}) where T<:scalar_types\nn_maximal_polyhedra(PC::PolyhedralComplex)\nn_polyhedra(PC::PolyhedralComplex)\nn_rays(PC::PolyhedralComplex)\nn_vertices(PC::PolyhedralComplex)\npolyhedra_of_dim\nrays(PC::PolyhedralComplex{T}) where T<:scalar_types\nrays_modulo_lineality(PC::PolyhedralComplex{T}) where T<:scalar_types\nvertices(as::Type{PointVector{T}}, PC::PolyhedralComplex{T}) where {T<:scalar_types}\nvertices_and_rays(PC::PolyhedralComplex{T}) where T<:scalar_types","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 = incidence_matrix([[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 = incidence_matrix([[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 = incidence_matrix([[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 = incidence_matrix([[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 = incidence_matrix([[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/#is_pure-Tuple{PolyhedralComplex}","page":"Polyhedral Complexes","title":"is_pure","text":"is_pure(PC::PolyhedralComplex)\n\nDetermine whether the polyhedral complex is pure.\n\nExamples\n\njulia> IM = incidence_matrix([[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> is_pure(PC)\ntrue\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/polyhedral_complexes/#is_simplicial-Tuple{PolyhedralComplex}","page":"Polyhedral Complexes","title":"is_simplicial","text":"is_simplicial(PC::PolyhedralComplex)\n\nDetermine whether the polyhedral complex is simplicial.\n\nExamples\n\njulia> IM = incidence_matrix([[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> is_simplicial(PC)\ntrue\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/polyhedral_complexes/#lineality_dim-Tuple{PolyhedralComplex}","page":"Polyhedral Complexes","title":"lineality_dim","text":"lineality_dim(PC::PolyhedralComplex)\n\nReturn the lineality dimension of PC.\n\nExamples\n\njulia> VR = [0 0 0; 1 0 0; 0 1 0; -1 0 0];\n\njulia> IM = incidence_matrix([[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":"method"},{"location":"PolyhedralGeometry/polyhedral_complexes/#lineality_space-Union{Tuple{PolyhedralComplex{T}}, Tuple{T}} where T<:Union{Float64, FieldElem}","page":"Polyhedral Complexes","title":"lineality_space","text":"lineality_space(PC::PolyhedralComplex)\n\nReturn the lineality space of PC.\n\nExamples\n\njulia> VR = [0 0 0; 1 0 0; 0 1 0; -1 0 0];\n\njulia> IM = incidence_matrix([[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_space(PC)\n1-element SubObjectIterator{RayVector{QQFieldElem}}:\n [0, 0, 1]\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\nOptionally IncidenceMatrix can be passed as a first argument to return the incidence matrix specifying the maximal polyhedra of PC. The indices returned refer to the output of vertices_and_rays.\n\nExamples\n\njulia> IM = incidence_matrix([[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 Polytope in ambient dimension 2\n\njulia> maximal_polyhedra(IncidenceMatrix, PC)\n2×4 IncidenceMatrix\n[1, 2, 3]\n[1, 3, 4]\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\nSee also vertices and lineality_space.\n\nExamples\n\njulia> VR = [0 0 0; 1 0 0; 0 1 0; -1 0 0];\n\njulia> IM = incidence_matrix([[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 = incidence_matrix([[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/#n_polyhedra-Tuple{PolyhedralComplex}","page":"Polyhedral Complexes","title":"n_polyhedra","text":"n_polyhedra(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 = incidence_matrix([[1,2,4],[1,3,4]]);\n\njulia> far_vertices = [2,3,4];\n\njulia> PC = polyhedral_complex(IM, VR, far_vertices);\n\njulia> n_polyhedra(PC)\n6\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/polyhedral_complexes/#n_rays-Tuple{PolyhedralComplex}","page":"Polyhedral Complexes","title":"n_rays","text":"n_rays(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 = incidence_matrix([[1,2,4],[1,3,4]]);\n\njulia> far_vertices = [2,3,4];\n\njulia> PC = polyhedral_complex(IM, VR, far_vertices);\n\njulia> n_rays(PC)\n3\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/polyhedral_complexes/#n_vertices-Tuple{PolyhedralComplex}","page":"Polyhedral Complexes","title":"n_vertices","text":"n_vertices(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 = incidence_matrix([[1,2,4],[1,3,4]]);\n\njulia> far_vertices = [2,3,4];\n\njulia> PC = polyhedral_complex(IM, VR, far_vertices);\n\njulia> n_vertices(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 = incidence_matrix([[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 Polytope in ambient dimension 2\n Polytope in ambient dimension 2\n Polytope in ambient dimension 2\n Polytope in ambient dimension 2\n Polytope 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([as::Type{T} = RayVector,] PC::PolyhedralComplex)\n\nReturn the rays of PC. The rays are defined to be the far vertices, i.e. the one-dimensional faces of the recession cones of its polyhedra, so if PC has lineality, there are no rays.\n\nSee also rays_modulo_lineality and vertices.\n\nOptional arguments for as include\n\nRayVector.\n\nExamples\n\njulia> IM = incidence_matrix([[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(RayVector, PC))\n[1 0]\n\nThe following complex has no vertices:\n\njulia> IM = incidence_matrix([[1,2,3],[1,3,4]]);\n\njulia> VR = [0 0 0; 1 0 0; 0 1 0; -1 0 0];\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> rays(PC)\n0-element SubObjectIterator{RayVector{QQFieldElem}}\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 fan 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\nSee also rays and lineality_space.\n\nExamples\n\njulia> VR = [0 0 0; 1 0 0; 0 1 0; -1 0 0];\n\njulia> IM = incidence_matrix([[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-Union{Tuple{T}, Tuple{Type{PointVector{T}}, PolyhedralComplex{T}}} where T<:Union{Float64, FieldElem}","page":"Polyhedral Complexes","title":"vertices","text":"vertices([as::Type{T} = PointVector,] PC::PolyhedralComplex)\n\nReturn an iterator over the vertices of PC in the format defined by as. The vertices are defined to be the zero-dimensional faces, so if P has lineality, there are no vertices, only minimal faces.\n\nSee also minimal_faces and rays.\n\nOptional arguments for as include\n\nPointVector.\n\nExamples\n\njulia> IM = incidence_matrix([[1,2,3],[1,3,4]]);\n\njulia> V = [0 0; 1 0; 1 1; 0 1];\n\njulia> PC = polyhedral_complex(IM, V)\nPolyhedral complex in ambient dimension 2\n\njulia> vertices(PC)\n4-element SubObjectIterator{PointVector{QQFieldElem}}:\n [0, 0]\n [1, 0]\n [1, 1]\n [0, 1]\n\njulia> matrix(QQ, vertices(PointVector, PC))\n[0 0]\n[1 0]\n[1 1]\n[0 1]\n\nThe following complex has no vertices:\n\njulia> IM = incidence_matrix([[1,2,3],[1,3,4]]);\n\njulia> VR = [0 0 0; 1 0 0; 0 1 0; -1 0 0];\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> vertices(PC)\n0-element SubObjectIterator{PointVector{QQFieldElem}}\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/polyhedral_complexes/#vertices_and_rays-Union{Tuple{PolyhedralComplex{T}}, Tuple{T}} where T<:Union{Float64, FieldElem}","page":"Polyhedral Complexes","title":"vertices_and_rays","text":"vertices_and_rays(PC::PolyhedralComplex)\n\nReturn the vertices and rays of PC as a combined set, up to lineality. This function is mainly a helper function for maximal_polyhedra.\n\nExamples\n\njulia> IM = incidence_matrix([[1,2,3],[1,3,4]]);\n\njulia> VR = [0 0 0; 1 0 0; 0 1 0; -1 0 0];\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> for vr in vertices_and_rays(PC)\n println(\"$vr : $(typeof(vr))\")\n end\nQQFieldElem[0, 0, 0] : PointVector{QQFieldElem}\nQQFieldElem[1, 0, 0] : RayVector{QQFieldElem}\nQQFieldElem[0, 1, 0] : RayVector{QQFieldElem}\nQQFieldElem[-1, 0, 0] : RayVector{QQFieldElem}\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/algebras/intro/","page":"Introduction","title":"Introduction","text":"CurrentModule = Hecke","category":"page"},{"location":"Hecke/manual/algebras/intro/#Algebras","page":"Introduction","title":"Introduction","text":"","category":"section"},{"location":"Hecke/manual/algebras/intro/","page":"Introduction","title":"Introduction","text":"note: Note\nThe functions described in this section are experimental. While the overall functionality provided will stay the same, names of specific functions or conventions for the return values might change in future versions.","category":"page"},{"location":"Hecke/manual/algebras/intro/","page":"Introduction","title":"Introduction","text":"This section describes the functionality for finite-dimensional associative algebras (or just algebras for short). Since different applications have different requirements, the following types of algebras are implemented:","category":"page"},{"location":"Hecke/manual/algebras/intro/","page":"Introduction","title":"Introduction","text":"structure constant algebras,\nmatrix algebras,\ngroup algebras,\nquaternion algebras.","category":"page"},{"location":"Hecke/manual/algebras/intro/","page":"Introduction","title":"Introduction","text":"These share a common interface encompassing a wide range of functions, which is indicated by the use of the type AbstractAssociativeAlgebra in the signature.","category":"page"},{"location":"CommutativeAlgebra/affine_algebras/","page":"Affine Algebras and Their Ideals","title":"Affine Algebras and Their Ideals","text":"CurrentModule = Oscar\nDocTestSetup = Oscar.doctestsetup()","category":"page"},{"location":"CommutativeAlgebra/affine_algebras/#affine_algebras","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\nWe emphasize: 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 monomial ordering entered by the user when creating the quotient; if no ordering is entered, OSCAR will use 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.\n\nquo(R::MPolyRing, V::Vector{MPolyRingElem}; ordering::MonomialOrdering = default_ordering(R)) -> MPolyQuoRing, Map\n\nAs above, where I is the ideal of R generated by the polynomials in V.\n\nnote: Note\nOnce R/I is created, all computations within R/I relying on division with remainder and/or Gröbner bases are done with respect to ordering.\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 x, y\n over rational field\n by ideal (x^2 - y^3, x - y)\n\njulia> typeof(A)\nMPolyQuoRing{QQMPolyRingElem}\n\njulia> typeof(x)\nQQMPolyRingElem\n\njulia> p\nMap defined by a julia-function with inverse\n from multivariate polynomial ring in 2 variables over QQ\n to quotient of multivariate polynomial ring by ideal (x^2 - y^3, x - y)\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 (x^2*z - y^3, x - y), Map: S -> B)\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,\nnumber_of_generators(A) / ngens(A) to the number of these generators,\ngen(A, i) as well as A[i] to the i-th such generator, and\nordering(A) to the monomial ordering used in the construction of A.","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 generated by\n -x^2 + y\n -x^3 + z\n\njulia> gens(A)\n3-element Vector{MPolyQuoRingElem{QQMPolyRingElem}}:\n x\n y\n z\n\njulia> number_of_generators(A)\n3\n\njulia> gen(A, 2)\ny\n\njulia> ordering(A)\ndegrevlex([x, y, z])\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)\nZ\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::FinGenAbGroupElem)","category":"page"},{"location":"CommutativeAlgebra/affine_algebras/#monomial_basis-Tuple{MPolyQuoRing, FinGenAbGroupElem}","page":"Affine Algebras and Their Ideals","title":"monomial_basis","text":"monomial_basis(A::MPolyQuoRing, g::FinGenAbGroupElem)\n\nGiven an affine algebra A over a field which is graded by a free group of type FinGenAbGroup, 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 generated by\n x^2\n\njulia> A, _ = quo(R, I)\n(Quotient of multivariate polynomial ring by ideal (x^2), Map: R -> A)\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::FinGenAbGroupElem)","category":"page"},{"location":"CommutativeAlgebra/affine_algebras/#homogeneous_component-Tuple{MPolyQuoRing{<:MPolyDecRingElem}, FinGenAbGroupElem}","page":"Affine Algebras and Their Ideals","title":"homogeneous_component","text":"homogeneous_component(A::MPolyQuoRing{<:MPolyDecRingElem}, g::FinGenAbGroupElem)\n\nGiven a graded quotient A of a multivariate polynomial ring over a field, where the grading group is free of type FinGenAbGroup, 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 defined by a julia-function with inverse\n from R_[2] of dim 10\n to graded multivariate polynomial ring in 4 variables over QQ\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 defined by a julia-function with inverse\n from quotient space over QQ with 7 generators and no relations\n to quotient of multivariate polynomial ring by ideal (-x*z + y^2, -w*z + x*y, -w*y + x^2)\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> G = abelian_group([0, 0])\nZ^2\n\njulia> W = [G[1], G[1], G[2], G[2], G[2]];\n\njulia> S, x, y = graded_polynomial_ring(QQ, :x => 1:2, :y => 1:3; weights = W);\n\njulia> L = homogeneous_component(S, [2,1]);\n\njulia> HC = gens(L[1]);\n\njulia> EMB = L[2]\nMap defined by a julia-function with inverse\n from S_[2 1] of dim 9\n to graded multivariate polynomial ring in 5 variables over QQ\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 defined by a julia-function with inverse\n from quotient space over QQ with 7 generators and no relations\n to quotient of multivariate polynomial ring by ideal (x[1]*y[1] - x[2]*y[2])\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":"is_finite_dimensional_vector_space(A::MPolyQuoRing)\nvector_space_dimension(A::MPolyQuoRing)","category":"page"},{"location":"CommutativeAlgebra/affine_algebras/#is_finite_dimensional_vector_space-Tuple{MPolyQuoRing}","page":"Affine Algebras and Their Ideals","title":"is_finite_dimensional_vector_space","text":"is_finite_dimensional_vector_space(A::MPolyQuoRing)\n\nIf, say, A = R/I, where R is a multivariate polynomial ring over a field K, and I is an ideal of R, return true if A is finite-dimensional as a K-vector space, false otherwise.\n\nnote: Note\nA is finite-dimensional as a K-vector space iff it has Krull dimension zero. This condition is checked by the function.\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> is_finite_dimensional_vector_space(A)\ntrue\n\njulia> A, _ = quo(R, ideal(R, [x]));\n\njulia> is_finite_dimensional_vector_space(A)\nfalse\n\n\n\n\n\n","category":"method"},{"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 an ideal of R, return the dimension of A as a K-vector space.\n\nnote: Note\nIf A is not finite-dimensional as a K-vector space, an error is thrown.\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 generated by\n x^3 + y^3 + z^3 - 1\n x^2 + y^2 + z^2 - 1\n x + y + z - 1\n\njulia> groebner_basis(I, ordering = lex(base_ring(I)))\nGröbner basis with elements\n 1 -> z^3 - z^2\n 2 -> y^2 + y*z - y + z^2 - z\n 3 -> x + y + z - 1\nwith respect to the ordering\n lex([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 an 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\nnote: Note\nIf A is not finite-dimensional as a K-vector space, an error is thrown.\n\nExamples\n\njulia> R, (x, y) = graded_polynomial_ring(QQ, [:x, :y]);\n\njulia> I = ideal(R, [x^2, y^3])\nIdeal generated by\n x^2\n y^3\n\njulia> A, _ = quo(R, I)\n(Quotient of multivariate polynomial ring by ideal (x^2, y^3), Map: R -> A)\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)","category":"page"},{"location":"CommutativeAlgebra/affine_algebras/#simplify-Tuple{MPolyQuoRingElem}","page":"Affine Algebras and Their Ideals","title":"simplify","text":"simplify(f::MPolyQuoRingElem)\n\nIf f is an element of the affine algebra A = R/I, say, replace the internal polynomial representative of f by its normal form mod I with respect to ordering(A).\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":"is_invertible_with_inverse(f::MPolyQuoRingElem)","category":"page"},{"location":"CommutativeAlgebra/affine_algebras/#is_invertible_with_inverse-Tuple{MPolyQuoRingElem}","page":"Affine Algebras and Their Ideals","title":"is_invertible_with_inverse","text":"is_invertible_with_inverse(f::MPolyQuoRingElem)\n\nIf f is invertible with inverse g, say, return (true, g). Otherwise, return (false, f).\n\nExamples\n\njulia> R, c = polynomial_ring(QQ, :c => (1:3));\n\njulia> R, c = grade(R, [1, 2, 3]);\n\njulia> I = ideal(R, [ -c[1]^3 + 2*c[1]*c[2] - c[3], c[1]^4 - 3*c[1]^2*c[2] + 2*c[1]*c[3] + c[2]^2,-c[1]^5 + 4*c[1]^3*c[2] - 3*c[1]^2*c[3] - 3*c[1]*c[2]^2 + 2*c[2]*c[3]]);\n\njulia> A, _ = quo(R, I);\n\njulia> f = A(c[1]^2 - c[1] - c[2] + 1)\nc[1]^2 - c[1] - c[2] + 1\n\njulia> tt, g = is_invertible_with_inverse(f)\n(true, c[1] + c[2] + c[3] + 1)\n\njulia> f*g\n1\n\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{FinGenAbGroupElem, 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::FinGenAbGroupElem)","category":"page"},{"location":"CommutativeAlgebra/affine_algebras/#homogeneous_component-Tuple{MPolyQuoRingElem{<:MPolyDecRingElem}, FinGenAbGroupElem}","page":"Affine Algebras and Their Ideals","title":"homogeneous_component","text":"homogeneous_component(f::MPolyQuoRingElem{<:MPolyDecRingElem}, g::FinGenAbGroupElem)\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 (-x + y, -x^3 + z^3), Map: R -> A)\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))\nFinGenAbGroupElem\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 generated by\n 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 generated by\n 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 affine algebra A = R/I, say, replace the internal polynomial representative of each generator of a by its normal form mod I with respect to ordering(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 generated by\n x^3*y^4 - x + y\n 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 generated by\n x^2*y^3 - x + y\n 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,\nnumber_of_generators(a) / ngens(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 generated by\n x - y\n z^4\n\njulia> base_ring(a)\nQuotient\n of multivariate polynomial ring in 3 variables x, y, z\n over rational field\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> number_of_generators(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 generated by\n 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 generated by\n 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 generated by\n x + y\n\njulia> a^2\nIdeal generated by\n 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 generated by\n x + y\n\njulia> b = ideal(A, [x^2+y^2, x+y])\nIdeal generated by\n x^2 + y^2\n x + y\n\njulia> a+b\nIdeal generated by\n x + y\n 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 generated by\n x + y\n\njulia> b = ideal(A, [x^2+y^2, x+y])\nIdeal generated by\n x^2 + y^2\n x + y\n\njulia> a*b\nIdeal generated by\n x^3 + x^2*y + x*y^2 + y^3\n 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 generated by\n y^2\n\njulia> b = ideal(A, [x])\nIdeal generated by\n x\n\njulia> intersect(a,b)\nIdeal generated by\n x*y\n\njulia> intersect([a,b])\nIdeal generated by\n 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(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\nintersect(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 generated by\n x^3*y - x*y - y^3\n x^4 - x^2 - x*y^2\n\njulia> intersect([I, J])\nIdeal generated by\n x^3*y - x*y - y^3\n 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 generated by\n y^2\n\njulia> b = ideal(A, [x])\nIdeal generated by\n x\n\njulia> intersect(a,b)\nIdeal generated by\n x*y\n\njulia> intersect([a,b])\nIdeal generated by\n 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 R\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], 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\njulia> Rg, (x, y, z) = graded_polynomial_ring(QQ, [:x, :y, :z]);\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/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 generated by\n y^2\n\njulia> b = ideal(A, [x])\nIdeal generated by\n x\n\njulia> a:b\nIdeal generated by\n 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 generated by\n x^2 + y^2\n x + y\n\njulia> is_zero(a)\nfalse\n\njulia> b = ideal(A, [x^2-y])\nIdeal generated by\n 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 generated by\n x^3*y^4 - x + y\n x*y^2 + x*y\n\njulia> b = ideal(A, [x^3*y^3-x+y, x^2*y+y^2*x])\nIdeal generated by\n x^3*y^3 - x + y\n 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 generated by\n x^3*y^4 - x + y\n x*y^2 + x*y\n\njulia> b = ideal(A, [x^3*y^3-x+y, x^2*y+y^2*x])\nIdeal generated by\n x^3*y^3 - x + y\n 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 generated by\n x^3*y^4 - x + y\n 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 base_ring(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])\nRing homomorphism\n from quotient of multivariate polynomial ring by ideal (-x^2 + y, -x^3 + z)\n to multivariate polynomial ring in 2 variables over QQ\ndefined by\n x -> s\n y -> s^2\n z -> s^3\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 : A to S as above, domain(F) and codomain(F) refer to A and S, respectively. Given ring homomorphisms F : A to B and G : B 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::MPolyAnyMap, I::Ideal)\nkernel(F::AffAlgHom)","category":"page"},{"location":"CommutativeAlgebra/affine_algebras/#preimage-Tuple{Oscar.MPolyAnyMap, Ideal}","page":"Affine Algebras and Their Ideals","title":"preimage","text":"preimage(F::MPolyAnyMap, I::Ideal)\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, U1<:MPolyRingElem{T}, U2<:MPolyRingElem{T}, DT<:Union{MPolyRing{T}, MPolyQuoRing{U1}}, CT<:Union{MPolyRing{T}, MPolyQuoRing{U2}}}}","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)\nRing homomorphism\n from graded multivariate polynomial ring in 4 variables over QQ\n to graded multivariate polynomial ring in 2 variables over QQ\ndefined by\n w -> s^3\n x -> s^2*t\n y -> s*t^2\n z -> t^3\n\njulia> twistedCubic = kernel(para)\nIdeal generated by\n -x*z + y^2\n -w*z + x*y\n -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)\nRing homomorphism\n from graded multivariate polynomial ring in 3 variables over QQ\n to quotient of multivariate polynomial ring by ideal (-x*z + y^2, -w*z + x*y, -w*y + x^2)\ndefined by\n a -> w - y\n b -> x\n c -> z\n\njulia> nodalCubic = kernel(proj)\nIdeal generated by\n -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)\nRing homomorphism\n from multivariate polynomial ring in 3 variables over QQ\n to multivariate polynomial ring in 3 variables over QQ\ndefined by\n y[1] -> x[1]*x[2]\n y[2] -> x[1]*x[3]\n y[3] -> x[2]*x[3]\n\njulia> sphere = ideal(C3, [x[1]^3 + x[2]^3 + x[3]^3 - 1])\nIdeal generated by\n x[1]^3 + x[2]^3 + x[3]^3 - 1\n\njulia> steinerRomanSurface = preimage(F3, sphere)\nIdeal generated by\n 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, U1<:MPolyRingElem{T}, U2<:MPolyRingElem{T}, DT<:Union{MPolyRing{T}, MPolyQuoRing{U1}}, CT<:Union{MPolyRing{T}, MPolyQuoRing{U2}}}}","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, U1<:MPolyRingElem{T}, U2<:MPolyRingElem{T}, DT<:Union{MPolyRing{T}, MPolyQuoRing{U1}}, CT<:Union{MPolyRing{T}, MPolyQuoRing{U2}}}}","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, U1<:MPolyRingElem{T}, U2<:MPolyRingElem{T}, DT<:Union{MPolyRing{T}, MPolyQuoRing{U1}}, CT<:Union{MPolyRing{T}, MPolyQuoRing{U2}}}}","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, U1<:MPolyRingElem{T}, U2<:MPolyRingElem{T}, DT<:Union{MPolyRing{T}, MPolyQuoRing{U1}}, CT<:Union{MPolyRing{T}, MPolyQuoRing{U2}}}}","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)\nRing homomorphism\n from multivariate polynomial ring in 3 variables over QQ\n to quotient of multivariate polynomial ring by ideal (-b^3 + c)\ndefined by\n x -> 2*a + c^2\n y -> -a^2 + 7*b\n z -> c^2\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)\nRing homomorphism\n from multivariate polynomial ring in 3 variables over QQ\n to multivariate polynomial ring in 2 variables over QQ\ndefined by\n x -> s*t\n y -> t\n z -> s^2\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, U1<:MPolyRingElem{T}, U2<:MPolyRingElem{T}, DT<:Union{MPolyRing{T}, MPolyQuoRing{U1}}, CT<:Union{MPolyRing{T}, MPolyQuoRing{U2}}}}","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)\nRing homomorphism\n from multivariate polynomial ring in 1 variable over QQ\n to quotient of multivariate polynomial ring by ideal (-x^2 + y, -x^3 + z)\ndefined by\n t -> x\n\njulia> G(t)\nx\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/affine_algebras/#Algebraic-Independence","page":"Affine Algebras and Their Ideals","title":"Algebraic Independence","text":"","category":"section"},{"location":"CommutativeAlgebra/affine_algebras/","page":"Affine Algebras and Their Ideals","title":"Affine Algebras and Their Ideals","text":"is_algebraically_independent(V::Vector{T}) where T <: Union{MPolyRingElem, MPolyQuoRingElem}\nis_algebraically_independent_with_relations(V::Vector{T}) where T <: Union{MPolyRingElem, MPolyQuoRingElem}","category":"page"},{"location":"CommutativeAlgebra/affine_algebras/#is_algebraically_independent-Union{Tuple{Vector{T}}, Tuple{T}} where T<:Union{MPolyRingElem, MPolyQuoRingElem}","page":"Affine Algebras and Their Ideals","title":"is_algebraically_independent","text":"is_algebraically_independent(V::Vector{T}) where T <: Union{MPolyRingElem, MPolyQuoRingElem}\n\nGiven a vector V of elements of a multivariate polynomial ring over a field K, say, or of a quotient of such a ring, return true if the elements of V are algebraically independent over K, and false otherwise.\n\nExamples\n\njulia> R, (x, y) = polynomial_ring(QQ, [:x, :y]);\n\njulia> V = [x, y, x^2+y^3]\n3-element Vector{QQMPolyRingElem}:\n x\n y\n x^2 + y^3\n\njulia> is_algebraically_independent(V)\nfalse\n\njulia> A, p = quo(R, [x*y]);\n\njulia> is_algebraically_independent([p(x), p(y)])\nfalse\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/affine_algebras/#is_algebraically_independent_with_relations-Union{Tuple{Vector{T}}, Tuple{T}} where T<:Union{MPolyRingElem, MPolyQuoRingElem}","page":"Affine Algebras and Their Ideals","title":"is_algebraically_independent_with_relations","text":"is_algebraically_independent_with_relations(V::Vector{T}) where T <: Union{MPolyRingElem, MPolyQuoRingElem}\n\nGiven a vector V of elements of a multivariate polynomial ring over a field K, say, or of a quotient of such a ring, return (true, Ideal (0)) if the elements of V are algebraically independent over K. Otherwise, return false together with the ideal of K-algebra relations.\n\nExamples\n\njulia> R, (x, y) = polynomial_ring(QQ, [:x, :y]);\n\njulia> V = [x, y, x^2+y^3]\n3-element Vector{QQMPolyRingElem}:\n x\n y\n x^2 + y^3\n\njulia> is_algebraically_independent_with_relations(V)\n(false, Ideal (t1^2 + t2^3 - t3))\n\njulia> A, p = quo(R, [x*y]);\n\njulia> is_algebraically_independent_with_relations([p(x), p(y)])\n(false, Ideal (t1*t2))\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 subset of the elements in V of minimal cardinality 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]\nRing homomorphism\n from quotient of multivariate polynomial ring by ideal (x*y, x*z)\n to quotient of multivariate polynomial ring by ideal (2*x^2 + x*y, 10*x^2 + 5*x*y + x*z)\ndefined by\n x -> x\n y -> 2*x + y\n z -> 10*x + 5*y + z\n\njulia> L[3]\nRing homomorphism\n from quotient of multivariate polynomial ring by ideal (2*x^2 + x*y, 10*x^2 + 5*x*y + x*z)\n to quotient of multivariate polynomial ring by ideal (x*y, x*z)\ndefined by\n x -> x\n y -> -2*x + y\n z -> -5*y + z\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. If specified by algorithm = :isPrime, assume that I is prime.\n\nSee [GLS10].\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 T(1), x, y\n over rational field\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]\nRing homomorphism\n from quotient of multivariate polynomial ring by ideal (x^5 - x^3*y^3 + x^3*y^2 - x*y^5)\n to quotient of multivariate polynomial ring by ideal (-T(1)*y + x, -T(1)*x + y^2, T(1)^2 - y, -x^2 + y^3)\ndefined by\n x -> x\n y -> y\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\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 [BDLPSS13]. Alternatively, if specified by algorithm = :normal_global, the global normalization algorithm in [GLS10] is used. If K = mathbb Q, it is recommended to apply the algorithm in [BDLP19], 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; check::Bool=true) -> Bool\n\nGiven an affine algebra A over a perfect field, return true if A is normal, and false otherwise.\n\nnote: Note\nThis function performs the first step of the normalization algorithm of Greuel, Laplagne, and Seelisch [GLS10] and may, thus, be more efficient than computing the full normalization of A.\n\nwarning: Warning\nIf check is true, the function checks whether A is indeed reduced. This may take some time.\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 mathbbN 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 [MS05] 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 [MS05] 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 [Eis95]). 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 [KR05]). 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) mathbbN to mathbbN 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) mathbbN to mathbbN 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::FinGenAbGroupElem)","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: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]\nZ^2\n\njulia> H[2][2]\nIdentity map\n of Z^2\n\njulia> G = abelian_group(ZZMatrix([1 -1]));\n\njulia> g = gen(G, 1)\nAbelian group element [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\nZ\n\njulia> iso\nMap\n from Z\n to finitely generated abelian group with 2 generators and 1 relation\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: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]\nZ^2\n\njulia> H[2][2]\nIdentity map\n of Z^2\n\njulia> G = abelian_group(ZZMatrix([1 -1]));\n\njulia> g = gen(G, 1)\nAbelian group element [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]\nZ\n\njulia> H[2][2]\nMap\n from Z\n to finitely generated abelian group with 2 generators and 1 relation\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/affine_algebras/#multi_hilbert_function-Tuple{MPolyQuoRing, FinGenAbGroupElem}","page":"Affine Algebras and Their Ideals","title":"multi_hilbert_function","text":"multi_hilbert_function(A::MPolyQuoRing, g::FinGenAbGroupElem)\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 mathbbN 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: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":"AlgebraicGeometry/Surfaces/ParametrizationSurfaces/","page":"Rational Parametrization of Rational Surfaces","title":"Rational Parametrization of Rational Surfaces","text":"CurrentModule = Oscar","category":"page"},{"location":"AlgebraicGeometry/Surfaces/ParametrizationSurfaces/#Rational-Parametrization-of-Rational-Surfaces","page":"Rational Parametrization of Rational Surfaces","title":"Rational Parametrization of Rational Surfaces","text":"","category":"section"},{"location":"AlgebraicGeometry/Surfaces/ParametrizationSurfaces/","page":"Rational Parametrization of Rational Surfaces","title":"Rational Parametrization of Rational Surfaces","text":"What we present here relies on the function adjunction_process discussed in the previous section.","category":"page"},{"location":"AlgebraicGeometry/Surfaces/ParametrizationSurfaces/#Parametrization","page":"Rational Parametrization of Rational Surfaces","title":"Parametrization","text":"","category":"section"},{"location":"AlgebraicGeometry/Surfaces/ParametrizationSurfaces/","page":"Rational Parametrization of Rational Surfaces","title":"Rational Parametrization of Rational Surfaces","text":"parametrization(X::AbsProjectiveVariety)","category":"page"},{"location":"AlgebraicGeometry/Surfaces/ParametrizationSurfaces/#parametrization-Tuple{AbsProjectiveVariety}","page":"Rational Parametrization of Rational Surfaces","title":"parametrization","text":"parametrization(X::AbsProjectiveVariety)\n\nGiven a smooth rational surface X which is linearly normal in the given embedding, return a rational parametrization of X.\n\nnote: Note\nThe function does not check whether X is smooth. If you are uncertain, enter is_smooth(X) first.\n\nnote: Note\nThe function does not check rationality. In fact, at current state, OSCAR does not offer a direct check for this.\n\nnote: Note\nThe function makes use of the adjunction process. It returns an error message if the terminal object of the adjunction process is not the projective plane. See the OSCAR documentation for information on the adjunction process.\n\nExamples\n\njulia> X = bordiga()\nProjective variety\n in projective 4-space over GF(31991) with coordinates [x, y, z, u, v]\ndefined by ideal with 4 generators\n\njulia> dim(X)\n2\n\njulia> codim(X)\n2\n\njulia> phi = parametrization(X);\n\njulia> domain(phi)\nMultivariate polynomial ring in 5 variables over GF(31991) graded by\n x -> [1]\n y -> [1]\n z -> [1]\n u -> [1]\n v -> [1]\n\njulia> codomain(phi)\nMultivariate polynomial ring in 3 variables over GF(31991) graded by\n z[1] -> [1]\n z[2] -> [1]\n z[3] -> [1]\n\njulia> [degree(phi(x)) for x in gens(ambient_coordinate_ring(X))]\n5-element Vector{FinGenAbGroupElem}:\n [4]\n [4]\n [4]\n [4]\n [4]\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Surfaces/ParametrizationSurfaces/#Contact","page":"Rational Parametrization of Rational Surfaces","title":"Contact","text":"","category":"section"},{"location":"AlgebraicGeometry/Surfaces/ParametrizationSurfaces/","page":"Rational Parametrization of Rational Surfaces","title":"Rational Parametrization of Rational Surfaces","text":"Please direct questions about this part of OSCAR to the following people:","category":"page"},{"location":"AlgebraicGeometry/Surfaces/ParametrizationSurfaces/","page":"Rational Parametrization of Rational Surfaces","title":"Rational Parametrization of Rational Surfaces","text":"Wolfram Decker.","category":"page"},{"location":"AlgebraicGeometry/Surfaces/ParametrizationSurfaces/","page":"Rational Parametrization of Rational Surfaces","title":"Rational Parametrization of Rational Surfaces","text":"You can ask questions in the OSCAR Slack.","category":"page"},{"location":"AlgebraicGeometry/Surfaces/ParametrizationSurfaces/","page":"Rational Parametrization of Rational Surfaces","title":"Rational Parametrization of Rational Surfaces","text":"Alternatively, you can raise an issue on github.","category":"page"},{"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":"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 of Euclidean rings with type EuclideanRingResidueRingElem{T} or in the case of residue rings that are known to be fields, EuclideanRingResidueFieldElem{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 EuclideanRingResidueRing{T} and those of residue fields have type EuclideanRingResidueField{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/#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) together with the canonical projection. 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);\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: univariate polynomial ring -> residue ring)\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);\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);\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);\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);\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> g = rand(S, 2:2, -10:10)\n-1//4*x^2 - 2//7*x + 1","category":"page"},{"location":"Hecke/manual/number_fields/intro/","page":"Introduction","title":"Introduction","text":"CurrentModule = Hecke","category":"page"},{"location":"Hecke/manual/number_fields/intro/#NumberFieldsLink","page":"Introduction","title":"Introduction","text":"","category":"section"},{"location":"Hecke/manual/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/manual/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/manual/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/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/MatRing.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.MatRingElem{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.MatRing{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 MatRingElem{T} and the parent types belong to MatRing{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":"matrix_ring(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 = matrix_ring(R, 3)\nMatrix ring 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.MatRingElem{T}) where T <: RingElement","category":"page"},{"location":"AbstractAlgebra/matrix_algebras/#identity_matrix-Union{Tuple{AbstractAlgebra.Generic.MatRingElem{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::MatRingElem{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 = matrix_ring(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.MatRingElem)","category":"page"},{"location":"AbstractAlgebra/matrix_algebras/#degree-Tuple{AbstractAlgebra.Generic.MatRingElem}","page":"Generic matrix algebras","title":"degree","text":"degree(a::MatRingElem{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 = matrix_ring(R, 3)\nMatrix ring 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/manual/abelian/maps/","page":"Morphisms","title":"Morphisms","text":"CurrentModule = Hecke\nDocTestSetup = quote\n using Hecke\nend","category":"page"},{"location":"Hecke/manual/abelian/maps/#Maps","page":"Morphisms","title":"Maps","text":"","category":"section"},{"location":"Hecke/manual/abelian/maps/","page":"Morphisms","title":"Morphisms","text":"Maps between abelian groups are mainly of type FinGenAbGroupHom. They allow normal map operations such as image, preimage, domain, codomain and can be created in a variety of situations.","category":"page"},{"location":"Hecke/manual/abelian/maps/","page":"Morphisms","title":"Morphisms","text":"Maps between abelian groups can be constructed via","category":"page"},{"location":"Hecke/manual/abelian/maps/","page":"Morphisms","title":"Morphisms","text":"images of the generators\npairs of elements\nvia composition\nand isomorphism/ inclusion testing","category":"page"},{"location":"Hecke/manual/abelian/maps/","page":"Morphisms","title":"Morphisms","text":"hom_direct_sum(G::FinGenAbGroup, H::FinGenAbGroup, A::Matrix{ <: Map{FinGenAbGroup, FinGenAbGroup}})\nis_isomorphic(G::FinGenAbGroup, H::FinGenAbGroup)","category":"page"},{"location":"Hecke/manual/abelian/maps/#hom_direct_sum-Tuple{FinGenAbGroup, FinGenAbGroup, Matrix{<:Map{FinGenAbGroup, FinGenAbGroup}}}","page":"Morphisms","title":"hom_direct_sum","text":"hom_direct_sum(G::FinGenAbGroup, H::FinGenAbGroup, A::Matrix{ <: Map{FinGenAbGroup, FinGenAbGroup}}) -> 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/manual/abelian/maps/#is_isomorphic-Tuple{FinGenAbGroup, FinGenAbGroup}","page":"Morphisms","title":"is_isomorphic","text":"is_isomorphic(G::FinGenAbGroup, H::FinGenAbGroup) -> Bool\n\nReturn whether G and H are isomorphic.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/abelian/maps/","page":"Morphisms","title":"Morphisms","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/manual/abelian/maps/","page":"Morphisms","title":"Morphisms","text":"Homomorphisms also allow addition and subtraction corresponding to the pointwise operation:","category":"page"},{"location":"Hecke/manual/abelian/maps/","page":"Morphisms","title":"Morphisms","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":"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 qadic_field function.","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 QadicFieldElem 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":"qadic_field\nunramified_extension","category":"page"},{"location":"Nemo/qadic/#qadic_field","page":"Qadics","title":"qadic_field","text":"qadic_field(p::Integer, d::Int, var::String = \"a\"; precision::Int=64, cached::Bool=true, check::Bool=true)\nqadic_field(p::ZZRingElem, d::Int, var::String = \"a\"; precision::Int=64, cached::Bool=true, check::Bool=true)\n\nReturn an unramified extension K of degree d of a p-adic field for the given prime p. The generator of K is printed as var.\n\nThe default absolute precision of elements of K may be set with precision.\n\nSee also unramified_extension.\n\n\n\n\n\n","category":"function"},{"location":"Nemo/qadic/#unramified_extension","page":"Qadics","title":"unramified_extension","text":"unramified_extension(Qp::PadicField, d::Int, var::String = \"a\"; precision::Int=64, cached::Bool=true)\n\nReturn an unramified extension K of degree d of the given p-adic field Qp. The generator of K is printed as var.\n\nThe default absolute precision of elements of K may be set with precision.\n\n\n\n\n\n","category":"function"},{"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 = qadic_field(7, 1, precision = 30);\n\njulia> S, _ = qadic_field(ZZ(65537), 1, precision = 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(::QadicField, ::Integer)\nO(::QadicField, ::ZZRingElem)\nO(::QadicField, ::QQFieldElem)","category":"page"},{"location":"Nemo/qadic/#O-Tuple{QadicField, Integer}","page":"Qadics","title":"O","text":"O(R::QadicField, 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{QadicField, ZZRingElem}","page":"Qadics","title":"O","text":"O(R::QadicField, 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{QadicField, QQFieldElem}","page":"Qadics","title":"O","text":"O(R::QadicField, 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, _ = qadic_field(7, 1, precision = 30);\n\njulia> S, _ = qadic_field(ZZ(65537), 1, precision = 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(::QadicField)","category":"page"},{"location":"Nemo/qadic/#prime-Tuple{QadicField}","page":"Qadics","title":"prime","text":"prime(R::QadicField)\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(::QadicFieldElem)","category":"page"},{"location":"Nemo/qadic/#precision-Tuple{QadicFieldElem}","page":"Qadics","title":"precision","text":"precision(a::QadicFieldElem)\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(::QadicFieldElem)","category":"page"},{"location":"Nemo/qadic/#valuation-Tuple{QadicFieldElem}","page":"Qadics","title":"valuation","text":"valuation(a::QadicFieldElem)\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, ::QadicFieldElem)\nlift(::ZZPolyRing, ::QadicFieldElem)","category":"page"},{"location":"Nemo/qadic/#lift-Tuple{QQPolyRing, QadicFieldElem}","page":"Qadics","title":"lift","text":"lift(R::QQPolyRing, a::QadicFieldElem)\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, QadicFieldElem}","page":"Qadics","title":"lift","text":"lift(R::ZZPolyRing, a::QadicFieldElem)\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, _ = qadic_field(7, 1, precision = 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 = QQ[\"x\"]\np = lift(Qx, a)\nZy, y = ZZ[\"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(::QadicFieldElem)","category":"page"},{"location":"Nemo/qadic/#sqrt-Tuple{QadicFieldElem}","page":"Qadics","title":"sqrt","text":"Base.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\nsqrt(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\n","category":"method"},{"location":"Nemo/qadic/","page":"Qadics","title":"Qadics","text":"Examples","category":"page"},{"location":"Nemo/qadic/","page":"Qadics","title":"Qadics","text":"julia> R, _ = qadic_field(7, 1, precision = 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(::QadicFieldElem)","category":"page"},{"location":"Nemo/qadic/#exp-Tuple{QadicFieldElem}","page":"Qadics","title":"exp","text":"exp(a::QadicFieldElem)\n\nReturn the p-adic exponential of a, assuming the p-adic exponential function converges at a.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/qadic/","page":"Qadics","title":"Qadics","text":"log(::QadicFieldElem)","category":"page"},{"location":"Nemo/qadic/#log-Tuple{QadicFieldElem}","page":"Qadics","title":"log","text":"log(a::QadicFieldElem)\n\nReturn the p-adic logarithm of a, assuming the p-adic logarithm converges at a.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/qadic/","page":"Qadics","title":"Qadics","text":"teichmuller(::QadicFieldElem)","category":"page"},{"location":"Nemo/qadic/#teichmuller-Tuple{QadicFieldElem}","page":"Qadics","title":"teichmuller","text":"teichmuller(a::QadicFieldElem)\n\nReturn the Teichmuller lift of the q-adic value a. We require the valuation of a to be non-negative. 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(::QadicFieldElem, ::Int)","category":"page"},{"location":"Nemo/qadic/#frobenius-Tuple{QadicFieldElem, Int64}","page":"Qadics","title":"frobenius","text":"frobenius(a::QadicFieldElem, 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, _ = qadic_field(7, 1, precision = 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":"TropicalGeometry/groebner_theory/#Groebner-theory","page":"Groebner theory","title":"Groebner theory","text":"","category":"section"},{"location":"TropicalGeometry/groebner_theory/#Introduction","page":"Groebner theory","title":"Introduction","text":"","category":"section"},{"location":"TropicalGeometry/groebner_theory/","page":"Groebner theory","title":"Groebner theory","text":"Tropical algebraic geometry incorporates the valuation of the underlying ground field, and therefore so does its Groebner theory. Tropical Groebner theory is a generalization of its classical counterpart to fields with valuation, and the classical Groebner theory is a specialization of tropical Groebner theory to fields with trivial valuation. Instead of monomial orderings there are term orderings which take the valuation into account, and initial forms and ideals live over the residue field. For details, see Chapter 2.4 in [MS15].","category":"page"},{"location":"TropicalGeometry/groebner_theory/#Groebner-bases","page":"Groebner theory","title":"Groebner bases","text":"","category":"section"},{"location":"TropicalGeometry/groebner_theory/","page":"Groebner theory","title":"Groebner theory","text":"Groebner bases in [MS15] are only defined for homogeneous ideals and they are finite sets whose initial forms generate the initial ideal. Groebner bases in OSCAR are defined for all ideals and they are finite generating sets whose initial forms generate the initial ideal. For homogeneous ideals generating the initial ideal implies generating the original ideal, so both notions coincide. For principal and binomial ideals the algorithm simply returns its input.","category":"page"},{"location":"TropicalGeometry/groebner_theory/","page":"Groebner theory","title":"Groebner theory","text":"groebner_basis(I::MPolyIdeal, nu::TropicalSemiringMap, w::Vector{<:Union{QQFieldElem,ZZRingElem,Rational,Integer}})","category":"page"},{"location":"TropicalGeometry/groebner_theory/#groebner_basis-Tuple{MPolyIdeal, TropicalSemiringMap, Vector{<:Union{Integer, QQFieldElem, ZZRingElem, Rational}}}","page":"Groebner theory","title":"groebner_basis","text":"groebner_basis(I::MPolyIdeal, nu::TropicalSemiringMap, w::AbstractVector{<:Union{QQFieldElem,ZZRingElem,Rational,Integer}})\n\nReturn a (tropical) Groebner basis of I with respect to the tropical semiring map nu and weight vector w.\n\nExamples\n\njulia> R,(x,y) = QQ[:x, :y];\n\njulia> I = ideal([x^3-5*x^2*y,3*y^3-2*x^2*y]);\n\njulia> nu = tropical_semiring_map(QQ,2);\n\njulia> w = [0,0];\n\njulia> groebner_basis(I,nu,w)\n2-element Vector{QQMPolyRingElem}:\n x^3 - 5*x^2*y\n -2*x^2*y + 3*y^3\n\n\n\n\n\n\n","category":"method"},{"location":"TropicalGeometry/groebner_theory/#Initial-forms-and-initial-ideals","page":"Groebner theory","title":"Initial forms and initial ideals","text":"","category":"section"},{"location":"TropicalGeometry/groebner_theory/","page":"Groebner theory","title":"Groebner theory","text":"initial(f::MPolyRingElem, nu::TropicalSemiringMap, w::AbstractVector{<:Union{QQFieldElem,ZZRingElem,Rational,Integer}})\ninitial(I::MPolyIdeal, nu::TropicalSemiringMap, w::AbstractVector{<:Union{QQFieldElem,ZZRingElem,Rational,Integer}}; skip_groebner_basis_computation::Bool=false)","category":"page"},{"location":"TropicalGeometry/groebner_theory/#initial-Tuple{MPolyRingElem, TropicalSemiringMap, AbstractVector{<:Union{Integer, QQFieldElem, ZZRingElem, Rational}}}","page":"Groebner theory","title":"initial","text":"initial(f::MPolyRingElem, nu::TropicalSemiringMap, w::Vector)\n\nReturn the initial form of f with respect to the tropical semiring map nu and weight vector w.\n\nExamples (trivial and p-adic valuation)\n\njulia> R,(x,y) = QQ[:x, :y];\n\njulia> nu_0 = tropical_semiring_map(QQ,max);\n\njulia> nu_2 = tropical_semiring_map(QQ,2);\n\njulia> w = [0,0];\n\njulia> f = x+y+2;\n\njulia> initial(f,nu_2,w) # polynomial over GF(2)\nx + y\n\njulia> initial(f,nu_0,w) # polynomial over QQ\nx + y + 2\n\n\nExamples (t-adic valuation)\n\njulia> K,t = rational_function_field(GF(2),\"t\");\n\njulia> nu_t = tropical_semiring_map(K,t,max);\n\njulia> R,(x,y) = K[:x, :y];\n\njulia> w = [1,1];\n\njulia> f = t*x+t*y+1;\n\njulia> initial(f,nu_t,w) # polynomial over GF(2)\nx + y + 1\n\n\n\n\n\n\n","category":"method"},{"location":"TropicalGeometry/groebner_theory/#initial-Tuple{MPolyIdeal, TropicalSemiringMap, AbstractVector{<:Union{Integer, QQFieldElem, ZZRingElem, Rational}}}","page":"Groebner theory","title":"initial","text":"initial(I::MPolyIdeal, nu::TropicalSemiringMap, w::Vector; skip_groebner_basis_computation::Bool=false)\n\nReturn the initial ideal of I with respect to the tropical semiring map nu and weight vector w. If skip_groebner_basis_computation=true, skips the necessary Groebner basis computation and returns the ideal generated by the initial forms of gens(I).\n\nExamples\n\njulia> R,(x,y) = QQ[:x, :y];\n\njulia> I = ideal([x^3-5*x^2*y,3*y^3-2*x^2*y]);\n\njulia> nu_2 = tropical_semiring_map(QQ,2);\n\njulia> nu_0 = tropical_semiring_map(QQ);\n\njulia> w = [0,0];\n\njulia> initial(I,nu_2,w)\nIdeal generated by\n x^3 + x^2*y\n y^3\n\njulia> initial(I,nu_0,w)\nIdeal generated by\n x^3 - 5*x^2*y\n -2*x^2*y + 3*y^3\n\n\n\n\n\n","category":"method"},{"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":"AlgebraicGeometry/Curves/ProjectivePlaneCurves/","page":"Projective Plane Curves","title":"Projective Plane Curves","text":"CurrentModule = Oscar","category":"page"},{"location":"AlgebraicGeometry/Curves/ProjectivePlaneCurves/#Projective-Plane-Curves","page":"Projective Plane Curves","title":"Projective Plane Curves","text":"","category":"section"},{"location":"AlgebraicGeometry/Curves/ProjectivePlaneCurves/","page":"Projective Plane Curves","title":"Projective Plane Curves","text":"ProjectivePlaneCurve","category":"page"},{"location":"AlgebraicGeometry/Curves/ProjectivePlaneCurves/#ProjectivePlaneCurve","page":"Projective Plane Curves","title":"ProjectivePlaneCurve","text":"ProjectivePlaneCurve <: AbsProjectiveCurve\n\nA reduced curve in the projective plane.\n\nExamples\n\njulia> R, (x,y,z) = graded_polynomial_ring(QQ, [:x, :y, :z]);\n\njulia> C = plane_curve(y^3*x^6 - y^6*x^2*z)\nProjective plane curve\n defined by 0 = x^5*y - x*y^4*z\n\n\n\n\n\n\n","category":"type"},{"location":"AlgebraicGeometry/Curves/ProjectivePlaneCurves/","page":"Projective Plane Curves","title":"Projective Plane Curves","text":"Projective plane curves are modeled in Oscar as projective algebraic sets. See AbsProjectiveAlgebraicSet(@ref). In addition to the methods for algebraic sets and curves the following methods special to plane curves are available.","category":"page"},{"location":"AlgebraicGeometry/Curves/ProjectivePlaneCurves/","page":"Projective Plane Curves","title":"Projective Plane Curves","text":"defining_equation(C::ProjectivePlaneCurve{S,MPolyQuoRing{T}}) where {S,T}\ndegree(C::ProjectivePlaneCurve)\ncommon_components(C::S, D::S) where {S<:ProjectivePlaneCurve}\nmultiplicity(C::ProjectivePlaneCurve, P::AbsProjectiveRationalPoint)\ntangent_lines(C::ProjectivePlaneCurve, P::AbsProjectiveRationalPoint)\nintersection_multiplicity(C::S, D::S, P::AbsProjectiveRationalPoint) where S <: ProjectivePlaneCurve\nis_transverse_intersection(C::S, D::S, P::AbsProjectiveRationalPoint) where S <: ProjectivePlaneCurve","category":"page"},{"location":"AlgebraicGeometry/Curves/ProjectivePlaneCurves/#defining_equation-Union{Tuple{ProjectivePlaneCurve{S, MPolyQuoRing{T}}}, Tuple{T}, Tuple{S}} where {S, T}","page":"Projective Plane Curves","title":"defining_equation","text":"defining_equation(C::AffinePlaneCurve)\n\nReturn the defining equation of C.\n\n\n\n\n\ndefining_equation(C::ProjectivePlaneCurve)\n\nReturn the defining equation of the (reduced) plane curve C.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Curves/ProjectivePlaneCurves/#degree-Tuple{ProjectivePlaneCurve}","page":"Projective Plane Curves","title":"degree","text":"degree(C::ProjectivePlaneCurve)\n\nReturn the degree of the defining polynomial of C.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Curves/ProjectivePlaneCurves/#common_components-Union{Tuple{S}, Tuple{S, S}} where S<:ProjectivePlaneCurve","page":"Projective Plane Curves","title":"common_components","text":"common_components(C::S, D::S) where {S<:ProjectivePlaneCurve}\n\nReturn the projective plane curve consisting of the common components 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":"AlgebraicGeometry/Curves/ProjectivePlaneCurves/#multiplicity-Tuple{ProjectivePlaneCurve, Oscar.AbsProjectiveRationalPoint}","page":"Projective Plane Curves","title":"multiplicity","text":"multiplicity(C::ProjectivePlaneCurve{S}, P::AbsProjectiveRationalPoint)\n\nReturn the multiplicity of C at P.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Curves/ProjectivePlaneCurves/#tangent_lines-Tuple{ProjectivePlaneCurve, Oscar.AbsProjectiveRationalPoint}","page":"Projective Plane Curves","title":"tangent_lines","text":"tangent_lines(C::ProjectivePlaneCurve{S}, P::AbsProjectiveRationalPoint) where S <: FieldElem\n\nReturn the tangent lines at P to C with their multiplicity.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Curves/ProjectivePlaneCurves/#intersection_multiplicity-Union{Tuple{S}, Tuple{S, S, Oscar.AbsProjectiveRationalPoint}} where S<:ProjectivePlaneCurve","page":"Projective Plane Curves","title":"intersection_multiplicity","text":"intersection_multiplicity(C::S, D::S, P::AbsProjectiveRationalPoint) where S <: ProjectivePlaneCurve\n\nReturn the intersection multiplicity of C and D at P.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Curves/ProjectivePlaneCurves/#is_transverse_intersection-Union{Tuple{S}, Tuple{S, S, Oscar.AbsProjectiveRationalPoint}} where S<:ProjectivePlaneCurve","page":"Projective Plane Curves","title":"is_transverse_intersection","text":"is_transverse_intersection(C::S, D::S, P::AbsProjectiveRationalPoint) where S <: ProjectivePlaneCurve\n\nReturn true if C and D intersect transversally at P and false otherwise.\n\n\n\n\n\n","category":"method"},{"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(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\nelem_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":"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\nbase_ring_type","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/#base_ring_type","page":"Extending the interface of AbstractAlgebra.jl","title":"base_ring_type","text":"base_ring_type(a)\n\nReturn the type of the base ring of the given element, element type, parent or parent type a.\n\nExamples\n\njulia> R, x = polynomial_ring(ZZ, :x)\n(Univariate polynomial ring in x over integers, x)\n\njulia> base_ring_type(R) == typeof(base_ring(R))\ntrue\n\njulia> base_ring_type(zero(R)) == typeof(base_ring(zero(R)))\ntrue\n\njulia> base_ring_type(typeof(R)) == typeof(base_ring(R))\ntrue\n\njulia> base_ring_type(typeof(zero(R))) == typeof(base_ring(zero(R)))\ntrue\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 = puiseux_series_field(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 = matrix_ring(QQ, 2)\nMatrix ring 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 = puiseux_series_field(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 = puiseux_series_field(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":"CommutativeAlgebra/ModulesOverMultivariateRings/complexes/","page":"Chain and Cochain Complexes","title":"Chain and Cochain Complexes","text":"CurrentModule = Oscar\nDocTestSetup = Oscar.doctestsetup()","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":"InvariantTheory/intro/","page":"Introduction","title":"Introduction","text":"CurrentModule = Oscar","category":"page"},{"location":"InvariantTheory/intro/#invariant_theory","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 groups, tori, 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 right 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 a right 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":"note: Note\nIn OSCAR, group actions are by convention assumed to be right actions and we follow this convention with our definition above. Note, however, that the left action given by pi f = f circ rho(pi^-1) is quite common in the literature.","category":"page"},{"location":"InvariantTheory/intro/","page":"Introduction","title":"Introduction","text":"The invariants of G are the fixed points of the action defined above, 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, fixing a basis of V and its dual basis, say, x_1 dots x_n of V^*, we may identify operatornameGL(V) cong operatornameGL_n(K) and KVcong Kx_1 dots x_n. Then the action of an element pi in G with rho(pi) = (a_i j) on a polynomial fin Kx_1dots x_n is given as follows:","category":"page"},{"location":"InvariantTheory/intro/","page":"Introduction","title":"Introduction","text":"(f pi) (x_1 dots x_n) = fbigl(sum_j a_1 jx_j dots sum_j a_n jx_jbigr)","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":"[DK15]","category":"page"},{"location":"InvariantTheory/intro/","page":"Introduction","title":"Introduction","text":"and the survey article","category":"page"},{"location":"InvariantTheory/intro/","page":"Introduction","title":"Introduction","text":"[DJ98]","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":"Base.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::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\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::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\nexp(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\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 = puiseux_series_ring(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":"DeveloperDocumentation/serialization/#dev_serialization","page":"Serialization","title":"Serialization","text":"","category":"section"},{"location":"DeveloperDocumentation/serialization/","page":"Serialization","title":"Serialization","text":"This document summarizes the serialization efforts of OSCAR, how it works, and what our long-term vision is. Serialization broadly speaking is the process of reading and writing data. There are many reasons for this feature in OSCAR, but the main reason is communication on mathematics by mathematicians.","category":"page"},{"location":"DeveloperDocumentation/serialization/","page":"Serialization","title":"Serialization","text":"We implement our serialization in accordance with the MaRDI file format specification described here. Which means we use a JSON extension to serialize data.","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.mrdi\", 42);\n\njulia> load(\"/tmp/fourtitwo.mrdi\")\n42\n","category":"page"},{"location":"DeveloperDocumentation/serialization/","page":"Serialization","title":"Serialization","text":"The filename hints to the MaRDI file format, which employs JSON. The file looks as follows:","category":"page"},{"location":"DeveloperDocumentation/serialization/","page":"Serialization","title":"Serialization","text":"{\n \"_ns\": {\n \"Oscar\": [\n \"https://github.com/oscar-system/Oscar.jl\",\n \"0.14.0-DEV-8fe2abbe39890a7d3324adcba7f91812119c586a\"\n ]\n },\n \"_type\": \"Base.Int\",\n \"data\": \"42\"\n}","category":"page"},{"location":"DeveloperDocumentation/serialization/","page":"Serialization","title":"Serialization","text":"It contains the precise version of OSCAR used for this serialization. The content is \"42\", it represents a Base.Int, according to the _type field.","category":"page"},{"location":"DeveloperDocumentation/serialization/#Implementation","page":"Serialization","title":"Implementation","text":"","category":"section"},{"location":"DeveloperDocumentation/serialization/","page":"Serialization","title":"Serialization","text":"To list and describe all implementations and encodings of all types in OSCAR is not a possible feat due to the arbitrarily deep and nested type structures available in OSCAR, we point any developer looking to understand the encodings of certain types to the OSCAR source code. All files for serialization can be found in the folder src/Serialization. The convention 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":"We include a basic example of the encoding for a QQPolyRingElem so one can get a taste before delving into the source code. Here we store the polynomial x^3 + 2x + 1//2. The encoding for polynomials is to store a list of tuples, where each entry in the list represents a term of the polynomial and where the first entry of the tuple is the exponent and the second entry is the coefficient. Here we serialize a univariate polynomial so the first entries are always integers, in general this may be an array of integers. The coefficients here are elements of QQ however in general the coefficients themselves may be described as polynomials of the generators of some field extension, i.e. the second entry may again be a list of tuples and so on. The nested structure of the coefficient will depend on the description of the field extension.","category":"page"},{"location":"DeveloperDocumentation/serialization/","page":"Serialization","title":"Serialization","text":"{\n \"_ns\": {\n \"Oscar\": [\n \"https://github.com/oscar-system/Oscar.jl\",\n \"1.1.0-DEV-6f7e717c759f5fc281b64f665c28f58578013c21\"\n ]\n },\n \"_refs\": {\n \"e6c5972c-4052-4408-a408-0f4f11f21e49\": {\n \"_type\": \"PolyRing\",\n \"data\": {\n \"base_ring\": {\n \"_type\": \"QQField\"\n },\n \"symbols\": [\n \"x\"\n ]\n }\n }\n },\n \"_type\": {\n \"name\": \"PolyRingElem\",\n \"params\": \"e6c5972c-4052-4408-a408-0f4f11f21e49\"\n },\n \"data\": [ [ \"0\", \"1//2\" ],\n\t [ \"1\", \"2\" ],\n\t [ \"3\", \"1\" ] ]\n}\n","category":"page"},{"location":"DeveloperDocumentation/serialization/","page":"Serialization","title":"Serialization","text":"When trying to understand an encoding of a particular type in OSCAR it is always best to make a minimal example and store it. Then use a pretty printer to format the JSON, and have it close by while going through the source code.","category":"page"},{"location":"DeveloperDocumentation/serialization/#Description-of-the-saving-and-loading-mechanisms","page":"Serialization","title":"Description of the saving and loading mechanisms","text":"","category":"section"},{"location":"DeveloperDocumentation/serialization/","page":"Serialization","title":"Serialization","text":"We require that any types serialized through OSCAR are registered using @register_serialization_type. This is to ensure user safety during the load process by avoiding code evaluation.","category":"page"},{"location":"DeveloperDocumentation/serialization/","page":"Serialization","title":"Serialization","text":"@register_serialization_type","category":"page"},{"location":"DeveloperDocumentation/serialization/#@register_serialization_type","page":"Serialization","title":"@register_serialization_type","text":"@register_serialization_type NewType \"String Representation of type\" uses_id uses_params [:attr1, :attr2]\n\n@register_serialization_type is a macro to ensure that the string we generate matches exactly the expression passed as first argument, and does not change in unexpected ways when import/export statements are adjusted.\n\nPassing a string argument will override how the type is stored as a string.\n\nWhen setting uses_id the object will be stored as a reference and will be referred to throughout the serialization sessions using a UUID. This should typically only be used for types that do not have a fixed normal form for example PolyRing and MPolyRing.\n\nUsing the uses_params flag will serialize the object with a more structured type description which will make the serialization more efficient see the discussion on save_type_params / load_type_params below.\n\nPassing a vector of symbols that correspond to attributes of type indicates which attributes will be serialized when using save with with_attrs=true.\n\n\n\n\n\n","category":"macro"},{"location":"DeveloperDocumentation/serialization/","page":"Serialization","title":"Serialization","text":"There are three pairs of saving and loading functions that are used during serialization:","category":"page"},{"location":"DeveloperDocumentation/serialization/","page":"Serialization","title":"Serialization","text":"save_typed_object, load_typed_object\nsave_object, load_object\nsave_type_params, load_type_params","category":"page"},{"location":"DeveloperDocumentation/serialization/#save_type_object-/-load_type_object","page":"Serialization","title":"save_type_object / load_type_object","text":"","category":"section"},{"location":"DeveloperDocumentation/serialization/","page":"Serialization","title":"Serialization","text":"For the most part these functions should not be touched, they are high level functions and are used to (de)serialize the object with its type information as well as its data. The data and type nodes are set in save_typed_object resulting in a \"data branch\" and \"type branch\". The usage of these functions can be used inside save_object / load_object and save_type_params / load_type_params. However using save_typed_object inside a save_object implementation will lead to a verbose format and should at some point be moved to save_type_params. Their implemention can be found in the main.jl file.","category":"page"},{"location":"DeveloperDocumentation/serialization/#save_object-/-load_object","page":"Serialization","title":"save_object / load_object","text":"","category":"section"},{"location":"DeveloperDocumentation/serialization/","page":"Serialization","title":"Serialization","text":"These functions should be the first functions to be overloaded when implementing the serialization of a new type. The functions save_data_dict and save_data_array are helpers functions that structure the serialization.","category":"page"},{"location":"DeveloperDocumentation/serialization/","page":"Serialization","title":"Serialization","text":"The examples show how they can be used to save data using the structure of an array or dict. Each nested call to save_data_dict or save_data_array should be called with a key that can be passed as the second parameter.","category":"page"},{"location":"DeveloperDocumentation/serialization/#Examples","page":"Serialization","title":"Examples","text":"","category":"section"},{"location":"DeveloperDocumentation/serialization/#Example-1","page":"Serialization","title":"Example 1","text":"","category":"section"},{"location":"DeveloperDocumentation/serialization/","page":"Serialization","title":"Serialization","text":"function save_object(s::SerializerState, obj::NewType)\n save_data_array(s) do\n save_object(s, obj.1)\n save_object(s, obj.2)\n save_data_dict(s) do\n save_object(s, obj.3, :key1)\n save_object(s, obj.4, :key2)\n end\n end\nend","category":"page"},{"location":"DeveloperDocumentation/serialization/","page":"Serialization","title":"Serialization","text":"This will result in a data format that looks like this.","category":"page"},{"location":"DeveloperDocumentation/serialization/","page":"Serialization","title":"Serialization","text":"[\n obj.1,\n obj.2,\n {\n \"key1\": obj.3,\n \"key2\": obj.4\n }\n]","category":"page"},{"location":"DeveloperDocumentation/serialization/","page":"Serialization","title":"Serialization","text":"With the corresponding loading function similar to this.","category":"page"},{"location":"DeveloperDocumentation/serialization/","page":"Serialization","title":"Serialization","text":"function load_object(s::DeserializerState, ::Type{<:NewType})\n (obj1, obj2, obj3_4) = load_array_node(s) do (i, entry)\n if entry isa JSON3.Object\n obj3 = load_object(s, Obj3Type, :key1)\n obj4 = load_object(s, Obj3Type, :key2)\n return OtherType(obj3, obj4)\n else\n if p(entry) == c\n load_object(s, Obj1Type)\n else\n load_object(s, Obj2Type)\n end\n end\n end\n return NewType(obj1, obj2, obj3_4)\nend","category":"page"},{"location":"DeveloperDocumentation/serialization/#Example-2","page":"Serialization","title":"Example 2","text":"","category":"section"},{"location":"DeveloperDocumentation/serialization/","page":"Serialization","title":"Serialization","text":"function save_object(s::SerializerState, obj::NewType)\n save_data_dict(s) do\n save_object(s, obj.1, :key1)\n save_data_array(s, :key2) do\n save_object(s, obj.3)\n save_typed_object(s, obj.4) # This is ok\n end\n end\nend","category":"page"},{"location":"DeveloperDocumentation/serialization/","page":"Serialization","title":"Serialization","text":"This will result in a data format that looks like this.","category":"page"},{"location":"DeveloperDocumentation/serialization/","page":"Serialization","title":"Serialization","text":"{\n \"key1\": obj.1,\n \"key2\":[\n obj.3,\n {\n \"type\": \"Type of obj.4\",\n \"data\": obj.4\n }\n ]\n}","category":"page"},{"location":"DeveloperDocumentation/serialization/","page":"Serialization","title":"Serialization","text":"The corresponding loading function would look something like this.","category":"page"},{"location":"DeveloperDocumentation/serialization/","page":"Serialization","title":"Serialization","text":"function load_object(s::DeserializerState, ::Type{<:NewType}, params::ParamsObj)\n obj1 = load_object(s, Obj1Type, params[1], :key1)\n\n (obj3, obj4) = load_array_node(s, :key2) do (i, entry)\n if i == 1\n load_object(s, Obj3Type, params[2])\n else\n load_typed_object(s)\n end\n end\n return NewType(obj1, OtherType(obj3, obj4))\n end","category":"page"},{"location":"DeveloperDocumentation/serialization/","page":"Serialization","title":"Serialization","text":"This is ok","category":"page"},{"location":"DeveloperDocumentation/serialization/","page":"Serialization","title":"Serialization","text":"function save_object(s::SerializerState, obj:NewType)\n save_object(s, obj.1)\nend","category":"page"},{"location":"DeveloperDocumentation/serialization/","page":"Serialization","title":"Serialization","text":"While this will throw an error","category":"page"},{"location":"DeveloperDocumentation/serialization/","page":"Serialization","title":"Serialization","text":"function save_object(s::SerializerState, obj:NewType)\n save_object(s, obj.1, :key)\nend","category":"page"},{"location":"DeveloperDocumentation/serialization/","page":"Serialization","title":"Serialization","text":"If you insist on having a key you should use a save_data_dict.","category":"page"},{"location":"DeveloperDocumentation/serialization/","page":"Serialization","title":"Serialization","text":"function save_object(s::SerializerState, obj:NewType)\n save_data_dict(s) do\n save_object(s, obj.1, :key)\n end\nend\n\nfunction load_object(s::SerializerState, ::Type{<:NewType})\n load_node(s, :key) do x\n info = do_something(x)\n\n if info\n load_object(s, OtherType)\n else\n load_object(s, AnotherType)\n end\n end\nend","category":"page"},{"location":"DeveloperDocumentation/serialization/","page":"Serialization","title":"Serialization","text":"Note for now save_typed_object must be wrapped in either a save_data_array or save_data_dict. Otherwise you will get a key override error.","category":"page"},{"location":"DeveloperDocumentation/serialization/#save_type_params-/-load_type_params","page":"Serialization","title":"save_type_params / load_type_params","text":"","category":"section"},{"location":"DeveloperDocumentation/serialization/","page":"Serialization","title":"Serialization","text":"The serialization mechanism stores data in the format of a tree, with the exception that some nodes may point to a shared reference. The \"data branch\" is anything that is a child node of a data node, whereas the \"type branch\" is any information that is stored in a node that is a child of a type node. Avoiding type information inside the data branch will lead to a more efficient serialization format. When the uses_params is set when registering the type with @register_serialization_type (de)serialization will use save_type_params / load_type_params to format the type information. In general we expect that implementing a save_type_params and load_type_params should not always be necessary. Many types will serialize their types in a similar fashion for example serialization of a FieldElem will use the save_type_params / load_type_params from RingElem since in both cases the only parameter needed for such types is their parent.","category":"page"},{"location":"DeveloperDocumentation/serialization/#Import-helper","page":"Serialization","title":"Import helper","text":"","category":"section"},{"location":"DeveloperDocumentation/serialization/","page":"Serialization","title":"Serialization","text":"When implementing the serialization of a new type in a module that is not Oscar (e.g. in a submodule of Oscar) it is necessary to import the a lot of helper functions (see the examples above). To ease this process, the @import_all_serialization_functions macro can be used.","category":"page"},{"location":"DeveloperDocumentation/serialization/","page":"Serialization","title":"Serialization","text":"Oscar.@import_all_serialization_functions","category":"page"},{"location":"DeveloperDocumentation/serialization/#@import_all_serialization_functions","page":"Serialization","title":"@import_all_serialization_functions","text":"Oscar.@import_all_serialization_functions\n\nThis macro imports all serialization related functions that one may need for implementing serialization for custom types from Oscar into the current module. One can instead import the functions individually if needed but this macro is provided for convenience.\n\n\n\n\n\n","category":"macro"},{"location":"DeveloperDocumentation/serialization/#Serializers","page":"Serialization","title":"Serializers","text":"","category":"section"},{"location":"DeveloperDocumentation/serialization/","page":"Serialization","title":"Serialization","text":"The code for the different types of serializers and their states is found in the serializers.jl file. Different serializers have different use cases, the default serializer JSONSerializer is used for writting to a file. Currently the only other serializer is the IPCSerializer which at the moment is quite similar to the JSONSerializer except that it does not store the refs of any types that are registered with the uses_id flag. When using the IPCSerializer it is left up to the user to guarantee that any refs required by a process are sent prior.","category":"page"},{"location":"DeveloperDocumentation/serialization/#Upgrades","page":"Serialization","title":"Upgrades","text":"","category":"section"},{"location":"DeveloperDocumentation/serialization/","page":"Serialization","title":"Serialization","text":"All upgrade scripts can be found in the src/Serialization/Upgrades folder. The mechanics of upgrading are found in the main.jl file where the Oscar.upgrade function provides the core functionality. Upgrading is triggered during load when the version of the file format to be loaded is older than the current Oscar version.","category":"page"},{"location":"DeveloperDocumentation/serialization/","page":"Serialization","title":"Serialization","text":"Oscar.upgrade\nOscar.upgrade_data","category":"page"},{"location":"DeveloperDocumentation/serialization/#upgrade","page":"Serialization","title":"upgrade","text":"upgrade(format_version::VersionNumber, dict::Dict)\n\nFinds the first version where an upgrade can be applied and then incrementally upgrades to each intermediate version until the structure of the current version has been achieved.\n\n\n\n\n\n","category":"function"},{"location":"DeveloperDocumentation/serialization/#upgrade_data","page":"Serialization","title":"upgrade_data","text":"upgrade_data(upgrade::Function, s::UpgradeState, dict::Dict)\n\nupgrade_data is a helper function that provides functionality for recursing on the tree structure. It is independent of any particular file format version and can be used in any upgrade script.\n\n\n\n\n\n","category":"function"},{"location":"DeveloperDocumentation/serialization/#Upgrade-Scripts","page":"Serialization","title":"Upgrade Scripts","text":"","category":"section"},{"location":"DeveloperDocumentation/serialization/","page":"Serialization","title":"Serialization","text":"All upgrade scripts should be contained in a file named after the version they upgrade to. For example a script that upgrades to Oscar version 0.13.0 should be named 0.13.0.jl.","category":"page"},{"location":"DeveloperDocumentation/serialization/","page":"Serialization","title":"Serialization","text":"Oscar.UpgradeScript","category":"page"},{"location":"DeveloperDocumentation/serialization/#UpgradeScript","page":"Serialization","title":"UpgradeScript","text":"UpgradeScript(version::VersionNumber, script::Function)\n\nAny upgrade scripts schould be created using the UpgradeScript constructor and then pushed to the upgrade_scripts_set. The name of the function is not particularly important however one should be assigned so that it can be used for recursion if necessary for upgrade. The upgrde script should be independent from any Oscar code and should relie solely on julia core functionality so to avoid conflicts with any future Oscar code deprecations.\n\nExample\n\npush!(upgrade_scripts_set, UpgradeScript(\n v\"0.13.0\",\n function upgrade_0_13_0(s::UpgradeState, dict::Dict)\n ...\n end\n))\n\n\n\n\n\n","category":"type"},{"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":"DeveloperDocumentation/serialization/#External-Implementations","page":"Serialization","title":"External Implementations","text":"","category":"section"},{"location":"DeveloperDocumentation/serialization/","page":"Serialization","title":"Serialization","text":"Any external body implementing a save/load following the .mrdi format specification and using the OSCAR namespace should be sure to check validity against our schema defined here.","category":"page"},{"location":"DeveloperDocumentation/serialization/","page":"Serialization","title":"Serialization","text":"We make no attempt whatsoever to verify the mathematics of the file, and neither should anyone implementing a save/load. Loading should not throw a parse error if the mathematics of the file is incorrect, the file should be parsed and allow the computer algebra system to throw the error. We cannot guarantee that any file that has been manipulated by hand is still valid and should be validated against the schema. In the same way we cannot guarantee that any files created externally are valid in terms of the mathematics either, these will not lead to a parse error but instead will be handle as though the incorrect input has been passed to one of the Oscar functions.","category":"page"},{"location":"DeveloperDocumentation/serialization/","page":"Serialization","title":"Serialization","text":"External implementations should not be expected to read or write all possible Oscar types. It is perfectly valid for external implementations to throw parse errors when a certain file format is unexpected. For example Oscar will parse a QQFieldElem that has data value \"0 0 7 // - 1 0\" as -7//10, even though this is not how it is serialized. We feel we should not restrict users when deserializing to formats that may have issues deserializing the same format externally.","category":"page"},{"location":"DeveloperDocumentation/serialization/","page":"Serialization","title":"Serialization","text":"Allowing extensions to JSON is not recommended, this is to keep the scope of possible software that can parse the given JSON as large as possible. For example some JSON extensions allow comments in the files, Oscar cannot parse such JSONs and we recommend that any comments should be placed in the meta field.","category":"page"},{"location":"DeveloperDocumentation/serialization/","page":"Serialization","title":"Serialization","text":"When writing UUIDs, adhere to version four UUIDs specified by RFC 4122.","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 = :x; 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 = matrix_ring(ZZ, 2)\nMatrix ring of degree 2\n over integers\n\njulia> S, x = polynomial_ring(R, :x)\n(Univariate polynomial ring in x over matrix ring, x)\n\njulia> T, y = polynomial_ring(S, :y)\n(Univariate polynomial ring in y over univariate polynomial ring in x over matrix ring, y)\n\njulia> U, z = R[:z]\n(Univariate polynomial ring in z over matrix ring, 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 = matrix_ring(ZZ, 2)\nMatrix ring of degree 2\n over integers\n\njulia> S, x = polynomial_ring(R, :x)\n(Univariate polynomial ring in x over matrix ring, x)\n\njulia> T, y = polynomial_ring(S, :y)\n(Univariate polynomial ring in y over univariate polynomial ring in x over matrix ring, 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 ring\n\njulia> V = base_ring(y + 1)\nUnivariate polynomial ring in x over matrix ring\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 ring\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 = matrix_ring(ZZ, 2)\nMatrix ring of degree 2\n over integers\n\njulia> S, x = polynomial_ring(R, :x)\n(Univariate polynomial ring in x over matrix ring, x)\n\njulia> T, y = polynomial_ring(S, :y)\n(Univariate polynomial ring in y over univariate polynomial ring in x over matrix ring, 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 = matrix_ring(ZZ, 2)\nMatrix ring of degree 2\n over integers\n\njulia> S, x = polynomial_ring(R, :x)\n(Univariate polynomial ring in x over matrix ring, x)\n\njulia> T, y = polynomial_ring(S, :y)\n(Univariate polynomial ring in y over univariate polynomial ring in x over matrix ring, 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 = matrix_ring(ZZ, 2)\nMatrix ring of degree 2\n over integers\n\njulia> S, x = polynomial_ring(R, :x)\n(Univariate polynomial ring in x over matrix ring, x)\n\njulia> T, y = polynomial_ring(S, :y)\n(Univariate polynomial ring in y over univariate polynomial ring in x over matrix ring, 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 = matrix_ring(ZZ, 2)\nMatrix ring of degree 2\n over integers\n\njulia> S, x = polynomial_ring(R, :x)\n(Univariate polynomial ring in x over matrix ring, x)\n\njulia> T, y = polynomial_ring(S, :y)\n(Univariate polynomial ring in y over univariate polynomial ring in x over matrix ring, 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 = matrix_ring(ZZ, 2)\nMatrix ring of degree 2\n over integers\n\njulia> S, x = polynomial_ring(R, :x)\n(Univariate polynomial ring in x over matrix ring, x)\n\njulia> T, y = polynomial_ring(S, :y)\n(Univariate polynomial ring in y over univariate polynomial ring in x over matrix ring, 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 = matrix_ring(ZZ, 2)\nMatrix ring of degree 2\n over integers\n\njulia> S, x = polynomial_ring(R, :x)\n(Univariate polynomial ring in x over matrix ring, x)\n\njulia> T, y = polynomial_ring(S, :y)\n(Univariate polynomial ring in y over univariate polynomial ring in x over matrix ring, 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":"CommutativeAlgebra/rings/","page":"Creating Multivariate Rings","title":"Creating Multivariate Rings","text":"CurrentModule = Oscar\nDocTestSetup = Oscar.doctestsetup()","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, xs::AbstractVector{<:VarName}; cached::Bool = true)","category":"page"},{"location":"CommutativeAlgebra/rings/","page":"Creating Multivariate Rings","title":"Creating Multivariate Rings","text":"Given a ring C and a vector xs of Symbols, Strings, or Characters, return a tuple R, vars, say, which consists of a polynomial ring R with coefficient ring C and a vector vars of generators (variables) which print according to the entries of xs.","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.","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\n","category":"page"},{"location":"CommutativeAlgebra/rings/","page":"Creating Multivariate Rings","title":"Creating Multivariate Rings","text":"julia> R1, _ = polynomial_ring(ZZ, [:x, :y, :z]);\n\njulia> R2, _ = polynomial_ring(ZZ, [\"x\", \"y\", \"z\"]);\n\njulia> R3, _ = polynomial_ring(ZZ, ['x', 'y', 'z']);\n\njulia> R1 === R2 === R3\ntrue\n","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{FqMPolyRingElem}:\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)\nPrime field of characteristic 3\n\njulia> GF(ZZ(2)^127 - 1)\nPrime 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> finite_field(2, 70, \"a\")\n(Finite field of degree 70 and characteristic 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)\nPrime field of characteristic 3\n\njulia> T, t = polynomial_ring(F, :t)\n(Univariate polynomial ring in t over F, t)\n\njulia> K, a = finite_field(t^2 + 1, \"a\")\n(Finite field of degree 2 and characteristic 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 [MS05] and [KR05] 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 [MS05]).","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) && number_of_generators(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) && number_of_generators(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 modeled 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{FinGenAbGroupElem})","category":"page"},{"location":"CommutativeAlgebra/rings/#grade-Tuple{MPolyRing, Vector{FinGenAbGroupElem}}","page":"Creating Multivariate Rings","title":"grade","text":"grade(R::MPolyRing, W::Vector{FinGenAbGroupElem})\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])\nZ\n\njulia> g = gen(G, 1)\nAbelian group element [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])\nZ^2\n\njulia> g = gens(G)\n2-element Vector{FinGenAbGroupElem}:\n [1, 0]\n [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])\nFinitely generated abelian group\n with 4 generators and 4 relations and relation matrix\n [0 0 0 0]\n [0 0 0 0]\n [0 0 2 0]\n [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]]\n5-element Vector{FinGenAbGroupElem}:\n [1, 0, 1, 1]\n [0, 1, 0, 1]\n [1, 0, 1, 0]\n [0, 1, 0, 0]\n [1, 1, 0, 0]\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::AbstractVector{<:AbstractVector{<:IntegerUnion}})\n\nGiven a vector W of ngens(R) integer vectors of the same size m, say, create a free abelian group of type FinGenAbGroup 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, AbstractMatrix{<: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::AbstractVector{<:IntegerUnion})\n\nGiven a vector W of ngens(R) integers, create a free abelian group of type FinGenAbGroup 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)","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, args...; weights, kwargs...)\n\nCreate a multivariate polynomial_ring with coefficient ring C and variables as described by args... (using the exact same syntax as polynomial_ring), and grade this ring according to the data provided by the keyword argument weights. Return the graded ring as an object of type MPolyDecRing, together with the variables.\n\nIf weights is omitted the grading is the standard mathbb Z-grading, i.e. all variables are graded with weight 1.\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; weights = 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]; weights = [1, 2, 3])\n(Graded multivariate polynomial ring in 3 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x, y, z])\n\njulia> T, x = graded_polynomial_ring(QQ, :x => 1:3)\n(Graded multivariate polynomial ring in 3 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x[1], x[2], x[3]])\n\njulia> T, x, y = graded_polynomial_ring(QQ, :x => 1:3, :y => (1:2, 1:2); weights=1:7)\n(Graded multivariate polynomial ring in 7 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x[1], x[2], x[3]], MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[y[1, 1] y[1, 2]; y[2, 1] y[2, 2]])\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> S, (x, y, z) = graded_polynomial_ring(QQ, [:x, :y, :z]; weights = [1, 2, 3])\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 G is free abelian of rank 1, and ngens(G) == 1.\n\nExamples\n\njulia> S, (x, y, z) = graded_polynomial_ring(QQ, [:x, :y, :z]; weights = [1, 2, 3])\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 G is free abelian of rank m, and ngens(G) == m.\n\nExamples\n\njulia> G = abelian_group([0, 0, 2, 2])\nFinitely generated abelian group\n with 4 generators and 4 relations and relation matrix\n [0 0 0 0]\n [0 0 0 0]\n [0 0 2 0]\n [0 0 0 2]\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 = graded_polynomial_ring(QQ, :x => 1:5; weights=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)\nAbelian group element [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> S, (t, x, y) = graded_polynomial_ring(QQ, [:t, :x, :y]; weights = [-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> G = abelian_group([0, 2])\nFinitely generated abelian group\n with 2 generators and 2 relations and relation matrix\n [0 0]\n [0 2]\n\njulia> W = [gen(G, 1)+gen(G, 2), gen(G, 1)]\n2-element Vector{FinGenAbGroupElem}:\n [1, 1]\n [1, 0]\n\njulia> S, (x, y) = graded_polynomial_ring(QQ, [:x, :y]; weights = 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,\nnumber_of_generators(R) / ngens(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> number_of_generators(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)\nZ\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::FinGenAbGroupElem)","category":"page"},{"location":"CommutativeAlgebra/rings/#monomial_basis-Tuple{MPolyDecRing, FinGenAbGroupElem}","page":"Creating Multivariate Rings","title":"monomial_basis","text":"monomial_basis(R::MPolyDecRing, g::FinGenAbGroupElem)\n\nGiven a polynomial ring R over a field which is graded by a free group of type FinGenAbGroup, 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)\nZ\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::FinGenAbGroupElem)","category":"page"},{"location":"CommutativeAlgebra/rings/#homogeneous_component-Tuple{MPolyDecRing, FinGenAbGroupElem}","page":"Creating Multivariate Rings","title":"homogeneous_component","text":"homogeneous_component(R::MPolyDecRing, g::FinGenAbGroupElem)\n\nGiven a polynomial ring R over a field which is graded by a free group, 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 will be thrown.\n\nExamples\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, _ = graded_polynomial_ring(QQ, :x => 1:2, :y => 1:3; weights = W);\n\njulia> G = grading_group(S)\nZ^2\n\njulia> L = homogeneous_component(S, [1, 1]);\n\njulia> L[1]\nS_[1 1] of dim 6\n\njulia> FG = gens(L[1]);\n\njulia> EMB = L[2]\nMap defined by a julia-function with inverse\n from S_[1 1] of dim 6\n to graded multivariate polynomial ring in 5 variables over QQ\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 R\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), FqMPolyRingElem[x, y])\n\njulia> c = map(GF(5), [1, 2, 3])\n3-element Vector{FqFieldElem}:\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 prime 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{FinGenAbGroupElem, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}} with 2 entries:\n [2] => x^2 + y\n [3] => z\n\njulia> G = abelian_group([0, 0, 2, 2])\nFinitely generated abelian group\n with 4 generators and 4 relations and relation matrix\n [0 0 0 0]\n [0 0 0 0]\n [0 0 2 0]\n [0 0 0 2]\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 = graded_polynomial_ring(QQ, :x => 1:5; weights=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{FinGenAbGroupElem, 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::FinGenAbGroupElem)","category":"page"},{"location":"CommutativeAlgebra/rings/#homogeneous_component-Tuple{MPolyDecRingElem, FinGenAbGroupElem}","page":"Creating Multivariate Rings","title":"homogeneous_component","text":"homogeneous_component(f::MPolyDecRingElem, g::FinGenAbGroupElem)\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> G = abelian_group([0, 0, 2, 2])\nFinitely generated abelian group\n with 4 generators and 4 relations and relation matrix\n [0 0 0 0]\n [0 0 0 0]\n [0 0 2 0]\n [0 0 0 2]\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 = graded_polynomial_ring(QQ, :x => 1:5; weights=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:4; weights=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]; weights=[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> G = abelian_group([0, 0, 2, 2])\nFinitely generated abelian group\n with 4 generators and 4 relations and relation matrix\n [0 0 0 0]\n [0 0 0 0]\n [0 0 2 0]\n [0 0 0 2]\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 = graded_polynomial_ring(QQ, :x => 1:5; weights=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)\nAbelian group element [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: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))\nFinGenAbGroupElem\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 = finite_field(2, 2, \"a\");\n\njulia> R, (x, y) = polynomial_ring(K, [:x, :y]);\n\njulia> F = hom(R, R, z -> z^2, [y, x])\nRing homomorphism\n from multivariate polynomial ring in 2 variables over K\n to multivariate polynomial ring in 2 variables over K\ndefined by\n x -> y\n y -> x\nwith map on coefficients\n #1\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])\nRing homomorphism\n from multivariate polynomial ring in 2 variables over Qi\n to multivariate polynomial ring in 2 variables over Qi\ndefined by\n x -> x^2\n y -> y^2\nwith map on coefficients\n Map: Qi -> Qi\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))\nRing homomorphism\n from multivariate polynomial ring in 2 variables over ZZ\n to multivariate polynomial ring in 2 variables over GF(2)\ndefined by\n x -> x\n y -> y\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 = Oscar.doctestsetup()","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,\ndegree, with value a positive integer, meaning entries only for characters whose character field has the given degree over its prime field,\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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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\nReturn a vector of strings that describe the orthogonal discriminants of the orthogonal irreducible characters of tbl of even degree.\n\nThe length of this vector is the number of irreducible characters of tbl, the i-th entry is an empty string if the i-th character is not orthogonal or has odd degree, and the i-th entry is equal to \"?\" if the orthogonal discriminant is unknown.\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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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\nReturn a string that describes the orthogonal discriminant of chi:\n\n\"?\" if the value is unknown,\none of \"O+\", \"O-\" in positive characteristic,\nsomething that can be evaluated with atlas_irrationality in characteristic 0, and\n\"\" if `chi is not irreducible, not orthogonal, or has odd degree.\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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"function"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/","page":"Monomial Orderings","title":"Monomial Orderings","text":"CurrentModule = Oscar\nDocTestSetup = Oscar.doctestsetup()","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 mathbbN^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 mathbbN^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 $ \\mathbb{N}^n$ such that alpha beta implies $ \\gamma + \\alpha > \\gamma + \\beta$ for all alpha beta gamma in mathbbN^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 mathbbN^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 R\n\njulia> cmp(lex(R)*invlex(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 (deg(x^alpha) = deg(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":"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-Inverse-Lexicographical-Ordering","page":"Monomial Orderings","title":"The Inverse Lexicographical Ordering","text":"","category":"section"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/","page":"Monomial Orderings","title":"Monomial Orderings","text":"The inverse lexicographical ordering invlex 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":"invlex(R::MPolyRing)","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/#invlex-Tuple{MPolyRing}","page":"Monomial Orderings","title":"invlex","text":"invlex(R::MPolyRing) -> MonomialOrdering\n\nReturn the inverse lexicographical ordering on the set of monomials in the variables of R.\n\ninvlex(V::AbstractVector{<:MPolyRingElem}) -> MonomialOrdering\n\nGiven a vector V of variables, return the inverse 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 = invlex(R)\ninvlex([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 = invlex([w, x])\ninvlex([w, x])\n\njulia> o3 = invlex(gens(R)[3:4])\ninvlex([y, z])\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/#The-Degree-Inverse-Lexicographical-Ordering","page":"Monomial Orderings","title":"The Degree Inverse Lexicographical Ordering","text":"","category":"section"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/","page":"Monomial Orderings","title":"Monomial Orderings","text":"The degree inverse lexicographical ordering deginvlex is defined by setting","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 (deg(x^alpha) = deg(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":"deginvlex(R::MPolyRing)","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/#deginvlex-Tuple{MPolyRing}","page":"Monomial Orderings","title":"deginvlex","text":"deginvlex(R::MPolyRing) -> MonomialOrdering\n\nReturn the degree inverse lexicographical ordering on the set of monomials in the variables of R.\n\ndeginvlex(V::AbstractVector{<:MPolyRingElem}) -> MonomialOrdering\n\nGiven a vector V of variables, return the degree inverse 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 = deginvlex(R)\ndeginvlex([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 = deginvlex([w, x])\ndeginvlex([w, x])\n\njulia> o3 = deginvlex(gens(R)[3:4])\ndeginvlex([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 (deg(x^alpha) = deg(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":"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 (deg(x^alpha) = deg(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":"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-Inverse-Lexicographical-Ordering","page":"Monomial Orderings","title":"The Negative Inverse Lexicographical Ordering","text":"","category":"section"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/","page":"Monomial Orderings","title":"Monomial Orderings","text":"The negative inverse lexicographical ordering neginvlex 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":"neginvlex(R::MPolyRing)","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/orderings/#neginvlex-Tuple{MPolyRing}","page":"Monomial Orderings","title":"neginvlex","text":"neginvlex(R::MPolyRing) -> MonomialOrdering\n\nReturn the negative inverse lexicographical ordering on the set of monomials in the variables of R.\n\nneginvlex(V::AbstractVector{<:MPolyRingElem}) -> MonomialOrdering\n\nGiven a vector V of variables, return the negative inverse 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 = neginvlex(R)\nneginvlex([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 = neginvlex([w, x])\nneginvlex([w, x])\n\njulia> o3 = neginvlex(gens(R)[3:4])\nneginvlex([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 (deg(x^alpha) = deg(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":"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{<:IntegerUnion}, 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::MonomialOrdering)\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 invlex. 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 R\n\njulia> o1 = degrevlex(R)*invlex(gens(F))\ndegrevlex([w, x, y, z])*invlex([gen(1), gen(2), gen(3)])\n\njulia> o2 = invlex(gens(F))*degrevlex(R)\ninvlex([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 R\n\njulia> o = invlex(gens(F))*degrevlex(R)\ninvlex([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":"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 behavior 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 behavior 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 behavior 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":"Hecke/manual/algebras/groupalgebras/#Group-algebras","page":"Group algebras","title":"Group algebras","text":"","category":"section"},{"location":"Hecke/manual/algebras/groupalgebras/","page":"Group algebras","title":"Group algebras","text":"CurrentModule = Hecke\nDocTestSetup = quote\n using Hecke\nend","category":"page"},{"location":"Hecke/manual/algebras/groupalgebras/","page":"Group algebras","title":"Group algebras","text":"As is natural, the basis of a group algebra KG correspond to the elements of G with respect to some arbitrary ordering.","category":"page"},{"location":"Hecke/manual/algebras/groupalgebras/#Creation","page":"Group algebras","title":"Creation","text":"","category":"section"},{"location":"Hecke/manual/algebras/groupalgebras/","page":"Group algebras","title":"Group algebras","text":"group_algebra(::Field, ::Group)","category":"page"},{"location":"Hecke/manual/algebras/groupalgebras/#group_algebra-Tuple{Field, AbstractAlgebra.Group}","page":"Group algebras","title":"group_algebra","text":"group_algebra(K::Ring, G::Group; cached::Bool = true) -> GroupAlgebra\n\nReturn the group algebra of the group G over the ring R. Shorthand syntax for this construction is R[G].\n\nExamples\n\njulia> QG = group_algebra(QQ, small_group(8, 5))\nGroup algebra\n of generic group of order 8 with multiplication table\n over rational field\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/algebras/groupalgebras/#Elements","page":"Group algebras","title":"Elements","text":"","category":"section"},{"location":"Hecke/manual/algebras/groupalgebras/","page":"Group algebras","title":"Group algebras","text":"Given a group algebra A and an element of a group g, the corresponding group algebra element can be constructed using the syntax A(g).","category":"page"},{"location":"Hecke/manual/algebras/groupalgebras/","page":"Group algebras","title":"Group algebras","text":"julia> G = abelian_group([2, 2]); a = G([0, 1]);\n\njulia> QG = group_algebra(QQ, G);\n\njulia> x = QG(a)\n[0, 0, 1, 0]","category":"page"},{"location":"Hecke/manual/algebras/groupalgebras/","page":"Group algebras","title":"Group algebras","text":"Vice versa, one can obtain the coordinate of a group algebra element x with respect to a group element a using the syntax x[a].","category":"page"},{"location":"Hecke/manual/algebras/groupalgebras/","page":"Group algebras","title":"Group algebras","text":"julia> x[a]\n1","category":"page"},{"location":"Hecke/manual/algebras/groupalgebras/","page":"Group algebras","title":"Group algebras","text":"It is also possible to create elements by specifying for each group element the corresponding coordinate either by a list of pairs or a dictionary:","category":"page"},{"location":"Hecke/manual/algebras/groupalgebras/","page":"Group algebras","title":"Group algebras","text":"julia> QG(a => 2, zero(G) => 1) == 2 * QG(a) + 1 * QG(zero(G))\ntrue\n\njulia> QG(Dict(a => 2, zero(G) => 1)) == 2 * QG(a) + 1 * QG(zero(G))\ntrue","category":"page"},{"location":"Experimental/LieAlgebras/lie_algebras/","page":"Lie algebras","title":"Lie algebras","text":"CurrentModule = Oscar\nDocTestSetup = Oscar.doctestsetup()","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)\ncharacteristic(L::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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/lie_algebras/#characteristic-Tuple{LieAlgebra}","page":"Lie algebras","title":"characteristic","text":"characteristic(L::LieAlgebra) -> Int\n\nReturn the characteristic of the coefficient ring of the Lie algebra L.\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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":"coerce_to_lie_algebra_elem(::LinearLieAlgebra{C}, ::MatElem{C}) where {C<:FieldElem}\nmatrix_repr_basis(::LinearLieAlgebra{C}) where {C<:FieldElem}\nmatrix_repr_basis(::LinearLieAlgebra{C}, ::Int) where {C<:FieldElem}\nmatrix_repr(::LinearLieAlgebraElem{C}) where {C<:FieldElem}","category":"page"},{"location":"Experimental/LieAlgebras/lie_algebras/#coerce_to_lie_algebra_elem-Union{Tuple{C}, Tuple{LinearLieAlgebra{C}, MatElem{C}}} where C<:FieldElem","page":"Lie algebras","title":"coerce_to_lie_algebra_elem","text":"coerce_to_lie_algebra_elem(L::LinearLieAlgebra{C}, x::MatElem{C}) -> LinearLieAlgebraElem{C}\n\nReturn the element of L whose matrix representation corresponds to x. If no such element exists, an error is thrown.\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/lie_algebras/#matrix_repr_basis-Union{Tuple{LinearLieAlgebra{C}}, Tuple{C}} where C<:FieldElem","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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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<:FieldElem","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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/lie_algebras/#matrix_repr-Union{Tuple{LinearLieAlgebraElem{C}}, Tuple{C}} where C<:FieldElem","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/#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_nilpotent(L::LieAlgebra)\nis_perfect(L::LieAlgebra)\nis_simple(L::LieAlgebra)\nis_solvable(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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/lie_algebras/#is_nilpotent-Tuple{LieAlgebra}","page":"Lie algebras","title":"is_nilpotent","text":"is_nilpotent(L::LieAlgebra) -> Bool\n\nReturn true if L is nilpotent, i.e. the lower central series of L terminates in 0.\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/lie_algebras/#is_perfect-Tuple{LieAlgebra}","page":"Lie algebras","title":"is_perfect","text":"is_perfect(L::LieAlgebra) -> Bool\n\nReturn true if L is perfect, i.e. L L = L.\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/lie_algebras/#is_solvable-Tuple{LieAlgebra}","page":"Lie algebras","title":"is_solvable","text":"is_solvable(L::LieAlgebra) -> Bool\n\nReturn true if L is solvable, i.e. the derived series of L terminates in 0.\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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":"center(L::LieAlgebra)\ncentralizer(L::LieAlgebra, xs::AbstractVector{<:LieAlgebraElem})\ncentralizer(L::LieAlgebra, x::LieAlgebraElem)\nderived_algebra(L::LieAlgebra)\nderived_series(L::LieAlgebra)\nlower_central_series(L::LieAlgebra)","category":"page"},{"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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/lie_algebras/#derived_series-Tuple{LieAlgebra}","page":"Lie algebras","title":"derived_series","text":"derived_series(L::LieAlgebra) -> Vector{LieAlgebraIdeal}\n\nReturn the derived series of L, i.e. the sequence of ideals L^(0) = L, L^(i + 1) = L^(i) L^(i).\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/lie_algebras/#lower_central_series-Tuple{LieAlgebra}","page":"Lie algebras","title":"lower_central_series","text":"lower_central_series(L::LieAlgebra) -> Vector{LieAlgebraIdeal}\n\nReturn the lower central series of L, i.e. the sequence of ideals L^(0) = L, L^(i + 1) = L L^(i).\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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::GapObj, s::Vector{<:VarName}) -> 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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\nlie_algebra(R::Field, struct_consts::Matrix{sparse_row_type(R)}, s::Vector{<:VarName}; check::Bool) -> AbstractLieAlgebra{elem_type(R)}\n\nConstruct the Lie algebra over the field 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.\ncheck: If true, check that the structure constants are anti-symmetric and satisfy the Jacobi identity. This is true by default.\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\nlie_algebra(R::Field, struct_consts::Array{elem_type(R),3}, s::Vector{<:VarName}; check::Bool) -> AbstractLieAlgebra{elem_type(R)}\n\nConstruct the Lie algebra over the field 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.\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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\nlie_algebra(R::Field, rs::RootSystem) -> AbstractLieAlgebra{elem_type(R)}\n\nConstruct a simple Lie algebra over the field R with the root system rs. The internally used basis of this Lie algebra is the Chevalley basis.\n\nThe experienced user may supply a boolean vector of length n_positive_roots(rs) - n_simple_roots(rs) via the kwarg extraspecial_pair_signs::Vector{Bool} to specify the concrete Lie algebra to be constructed. If (alphabeta) is the extraspecial pair for the non-simple root root(rs, i), then varepsilon_alphabeta = 1 iff extraspecial_pair_signs[i - n_simple_roots(rs)] = true. For the used notation and the definition of extraspecial pairs, see [CMT04].\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\nlie_algebra(R::Field, fam::Symbol, rk::Int) -> AbstractLieAlgebra{elem_type(R)}\n\nConstruct a simple Lie algebra over the field R with Dynkin type given by fam and rk. See cartan_matrix(fam::Symbol, rk::Int) for allowed combinations. The internally used basis of this Lie algebra is the Chevalley basis.\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\nlie_algebra(R::Field, n::Int, basis::Vector{<:MatElem{elem_type(R)}}, s::Vector{<:VarName}; check::Bool=true) -> LinearLieAlgebra{elem_type(R)}\n\nConstruct the Lie algebra over the field R with basis basis and basis element names given by s. The basis elements must be square matrices of size n.\n\nWe require basis to be linearly independent, and to contain the Lie bracket of any two basis elements in its span (this is currently not checked). Setting check=false disables these checks (once they are in place).\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\nlie_algebra(S::LieSubalgebra) -> LieAlgebra\n\nReturn S as a Lie algebra LS, together with an embedding LS -> L, where L is the Lie algebra where S lives in.\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\nlie_algebra(I::LieAlgebraIdeal) -> LieAlgebra\n\nReturn I as a Lie algebra LI, together with an embedding LI -> L, where L is the Lie algebra where I lives in.\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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":"abelian_lie_algebra(R::Field, n::Int)\ngeneral_linear_lie_algebra(R::Field, n::Int)\nspecial_linear_lie_algebra(R::Field, n::Int)\nspecial_orthogonal_lie_algebra\nsymplectic_lie_algebra","category":"page"},{"location":"Experimental/LieAlgebras/lie_algebras/#abelian_lie_algebra-Tuple{Field, Int64}","page":"Lie algebras","title":"abelian_lie_algebra","text":"abelian_lie_algebra(R::Field, n::Int) -> LinearLieAlgebra{elem_type(R)}\nabelian_lie_algebra(::Type{LinearLieAlgebra}, R::Field, n::Int) -> LinearLieAlgebra{elem_type(R)}\nabelian_lie_algebra(::Type{AbstractLieAlgebra}, R::Field, n::Int) -> AbstractLieAlgebra{elem_type(R)}\n\nReturn the abelian Lie algebra of dimension n over the field R. The first argument can be optionally provided to specify the type of the returned Lie algebra.\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/lie_algebras/#general_linear_lie_algebra-Tuple{Field, Int64}","page":"Lie algebras","title":"general_linear_lie_algebra","text":"general_linear_lie_algebra(R::Field, n::Int) -> LinearLieAlgebra{elem_type(R)}\n\nReturn the general linear Lie algebra mathfrakgl_n(R), i.e., the Lie algebra of all n times n matrices over the field 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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/lie_algebras/#special_linear_lie_algebra-Tuple{Field, Int64}","page":"Lie algebras","title":"special_linear_lie_algebra","text":"special_linear_lie_algebra(R::Field, n::Int) -> LinearLieAlgebra{elem_type(R)}\n\nReturn the special linear Lie algebra mathfraksl_n(R), i.e., the Lie algebra of all n times n matrices over the field R with trace zero.\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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/lie_algebras/#special_orthogonal_lie_algebra","page":"Lie algebras","title":"special_orthogonal_lie_algebra","text":"special_orthogonal_lie_algebra(R::Field, n::Int) -> LinearLieAlgebra{elem_type(R)}\nspecial_orthogonal_lie_algebra(R::Field, n::Int, gram::MatElem) -> LinearLieAlgebra{elem_type(R)}\nspecial_orthogonal_lie_algebra(R::Field, n::Int, gram::Matrix) -> LinearLieAlgebra{elem_type(R)}\n\nReturn the special orthogonal Lie algebra mathfrakso_n(R).\n\nGiven a non-degenerate symmetric bilinear form f via its Gram matrix gram, mathfrakso_n(R) is the Lie algebra of all n times n matrices x over the field R such that f(xv w) = -f(v xw) for all v w in R^n.\n\nIf gram is not provided, for n = 2k the form defined by beginmatrix 0 I_k -I_k 0 endmatrix is used, and for n = 2k + 1 the form defined by beginmatrix 1 0 0 0 0 I_k 0 I_k 0 endmatrix.\n\nExamples\n\njulia> L1 = special_orthogonal_lie_algebra(QQ, 4)\nSpecial orthogonal Lie algebra of degree 4\n of dimension 6\nover rational field\n\njulia> basis(L1)\n6-element Vector{LinearLieAlgebraElem{QQFieldElem}}:\n x_1\n x_2\n x_3\n x_4\n x_5\n x_6\n\njulia> matrix_repr_basis(L1)\n6-element Vector{QQMatrix}:\n [1 0 0 0; 0 0 0 0; 0 0 -1 0; 0 0 0 0]\n [0 1 0 0; 0 0 0 0; 0 0 0 0; 0 0 -1 0]\n [0 0 0 1; 0 0 -1 0; 0 0 0 0; 0 0 0 0]\n [0 0 0 0; 1 0 0 0; 0 0 0 -1; 0 0 0 0]\n [0 0 0 0; 0 1 0 0; 0 0 0 0; 0 0 0 -1]\n [0 0 0 0; 0 0 0 0; 0 1 0 0; -1 0 0 0]\n\njulia> L2 = special_orthogonal_lie_algebra(QQ, 3, identity_matrix(QQ, 3))\nSpecial orthogonal Lie algebra of degree 3\n of dimension 3\nover rational field\n\njulia> basis(L2)\n3-element Vector{LinearLieAlgebraElem{QQFieldElem}}:\n x_1\n x_2\n x_3\n\njulia> matrix_repr_basis(L2)\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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"function"},{"location":"Experimental/LieAlgebras/lie_algebras/#symplectic_lie_algebra","page":"Lie algebras","title":"symplectic_lie_algebra","text":"symplectic_lie_algebra(R::Field, n::Int) -> LinearLieAlgebra{elem_type(R)}\nsymplectic_lie_algebra(R::Field, n::Int, gram::MatElem) -> LinearLieAlgebra{elem_type(R)}\nsymplectic_lie_algebra(R::Field, n::Int, gram::Matrix) -> LinearLieAlgebra{elem_type(R)}\n\nReturn the symplectic Lie algebra mathfraksp_n(R).\n\nGiven a non-degenerate skew-symmetric bilinear form f via its Gram matrix gram, mathfraksp_n(R) is the Lie algebra of all n times n matrices x over the field R such that f(xv w) = -f(v xw) for all v w in R^n.\n\nIf gram is not provided, for n = 2k the form defined by beginmatrix 0 I_k -I_k 0 endmatrix is used. For odd n there is no non-degenerate skew-symmetric bilinear form on R^n.\n\nExamples\n\njulia> L = symplectic_lie_algebra(QQ, 4)\nSymplectic Lie algebra of degree 4\n of dimension 10\nover rational field\n\njulia> basis(L)\n10-element Vector{LinearLieAlgebraElem{QQFieldElem}}:\n x_1\n x_2\n x_3\n x_4\n x_5\n x_6\n x_7\n x_8\n x_9\n x_10\n\njulia> matrix_repr_basis(L)\n10-element Vector{QQMatrix}:\n [1 0 0 0; 0 0 0 0; 0 0 -1 0; 0 0 0 0]\n [0 1 0 0; 0 0 0 0; 0 0 0 0; 0 0 -1 0]\n [0 0 1 0; 0 0 0 0; 0 0 0 0; 0 0 0 0]\n [0 0 0 1; 0 0 1 0; 0 0 0 0; 0 0 0 0]\n [0 0 0 0; 1 0 0 0; 0 0 0 -1; 0 0 0 0]\n [0 0 0 0; 0 1 0 0; 0 0 0 0; 0 0 0 -1]\n [0 0 0 0; 0 0 0 1; 0 0 0 0; 0 0 0 0]\n [0 0 0 0; 0 0 0 0; 1 0 0 0; 0 0 0 0]\n [0 0 0 0; 0 0 0 0; 0 1 0 0; 1 0 0 0]\n [0 0 0 0; 0 0 0 0; 0 0 0 0; 0 1 0 0]\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"function"},{"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":"AlgebraicGeometry/Curves/ProjectiveCurves/","page":"Projective Curves","title":"Projective Curves","text":"CurrentModule = Oscar","category":"page"},{"location":"AlgebraicGeometry/Curves/ProjectiveCurves/#Projective-Curves","page":"Projective Curves","title":"Projective Curves","text":"","category":"section"},{"location":"AlgebraicGeometry/Curves/ProjectiveCurves/","page":"Projective Curves","title":"Projective Curves","text":"ProjectiveCurve\ninvert_birational_map\ngeometric_genus","category":"page"},{"location":"AlgebraicGeometry/Curves/ProjectiveCurves/#ProjectiveCurve","page":"Projective Curves","title":"ProjectiveCurve","text":"ProjectiveCurve\n\nA reduced projective curve, defined as the vanishing locus of a homogeneous (but not necessarily radical) ideal.\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 = projective_curve(I)\nProjective curve\n in projective 3-space over QQ with coordinates [w, x, y, z]\ndefined by ideal (w*y - x^2, w*z - x*y, x*z - y^2)\n\n\n\n\n\n\n","category":"type"},{"location":"AlgebraicGeometry/Curves/ProjectiveCurves/#invert_birational_map","page":"Projective Curves","title":"invert_birational_map","text":"invert_birational_map(phi::Vector{T}, C::ProjectiveCurve) 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\ninvert_birational_map(phi::Vector{T}, C::ProjectivePlaneCurve) 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 plane 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":"function"},{"location":"AlgebraicGeometry/Curves/ProjectiveCurves/#geometric_genus","page":"Projective Curves","title":"geometric_genus","text":"geometric_genus(X::AbsProjectiveScheme{<:Field}; algorithm::Symbol=:default) -> Int\n\nGiven a projective curve X return the genus of X, i.e. the integer p_g = p_a - delta where p_a is the arithmetic genus and \\delta the delta-invariant of the curve.\n\nThe algorithm keyword can be specified to \n\n:normalization to compute delta a normalization\n:primary_decomposition to proceed with a primary decomposition\n\nNormalization is usually slower, but not always.\n\nExamples\n\njulia> R, (x,y,z) = graded_polynomial_ring(QQ, [:x, :y, :z]);\n\njulia> C = plane_curve(z*x^2-y^3)\nProjective plane curve\n defined by 0 = x^2*z - y^3\n\njulia> geometric_genus(C)\n0\n\n\n\n\n\n\n","category":"function"},{"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":"rational_function_field(k::Field, s::VarName; cached::Bool = true)\nrational_function_field(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 = rational_function_field(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) = rational_function_field(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 = rational_function_field(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 = rational_function_field(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":"Base.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::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\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 = rational_function_field(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":"function_field(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 = rational_function_field(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 = function_field(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 = rational_function_field(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 = function_field(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 = rational_function_field(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 = function_field(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 = rational_function_field(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 = function_field(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 = rational_function_field(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 = function_field(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":"Combinatorics/EnumerativeCombinatorics/partitions/","page":"Partitions","title":"Partitions","text":"CurrentModule = Oscar\nDocTestSetup = Oscar.doctestsetup()","category":"page"},{"location":"Combinatorics/EnumerativeCombinatorics/partitions/#Partitions","page":"Partitions","title":"Partitions","text":"","category":"section"},{"location":"Combinatorics/EnumerativeCombinatorics/partitions/","page":"Partitions","title":"Partitions","text":"A partition of a non-negative integer n is a decreasing sequence lambda_1 geq lambda_2geq dots geq lambda_r of positive integers lambda_i such that n = lambda_1 + dots + lambda_r. The lambda_i are called the parts of the partition and r is called the length. General references on partitions are [Ful97] and [Knu11], Section 7.2.1.4.","category":"page"},{"location":"Combinatorics/EnumerativeCombinatorics/partitions/","page":"Partitions","title":"Partitions","text":"A partition can be encoded as an array with elements lambda_i. In OSCAR, the parametric type Partition{T} is provided which is a subtype of AbstractVector{T}. Here, T can be any subtype of IntegerUnion. 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.","category":"page"},{"location":"Combinatorics/EnumerativeCombinatorics/partitions/","page":"Partitions","title":"Partitions","text":"partition","category":"page"},{"location":"Combinatorics/EnumerativeCombinatorics/partitions/#partition","page":"Partitions","title":"partition","text":"partition([T::Type{<:IntegerUnion}], parts::IntegerUnion...; check::Bool = true)\npartition(parts::Vector{T}; check::Bool = true) where T <: IntegerUnion\n\nReturn the partition given by the integer sequence parts as an object of type Partition{T}.\n\nThe element type T may be optionally specified, see also the examples below.\n\nIf check is true (default), it is checked whether the given sequence defines a partition.\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) # the same partition\n[6, 4, 4, 2]\n\njulia> P = partition(Int8, 6, 4, 4, 2) # save the elements in 8-bit integers\nInt8[6, 4, 4, 2]\n\n\n\n\n\n","category":"function"},{"location":"Combinatorics/EnumerativeCombinatorics/partitions/","page":"Partitions","title":"Partitions","text":"Because Partition is a subtype of AbstractVector, all functions that can be used for vectors (1-dimensional arrays) can be used for partitions as well.","category":"page"},{"location":"Combinatorics/EnumerativeCombinatorics/partitions/","page":"Partitions","title":"Partitions","text":"julia> P = partition(6, 4, 4, 2)\n[6, 4, 4, 2]\n\njulia> length(P)\n4\n\njulia> P[1]\n6","category":"page"},{"location":"Combinatorics/EnumerativeCombinatorics/partitions/","page":"Partitions","title":"Partitions","text":"However, usually, lambda = n is called the size of lambda. In Julia, the function size for arrays already exists and returns the dimension of an array. Instead, one can use the Julia function sum to get the sum of the parts.","category":"page"},{"location":"Combinatorics/EnumerativeCombinatorics/partitions/","page":"Partitions","title":"Partitions","text":"julia> P = partition(6, 4, 4, 2)\n[6, 4, 4, 2]\n\njulia> sum(P)\n16","category":"page"},{"location":"Combinatorics/EnumerativeCombinatorics/partitions/","page":"Partitions","title":"Partitions","text":"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. For this, OSCAR provides the function getindex_safe:","category":"page"},{"location":"Combinatorics/EnumerativeCombinatorics/partitions/","page":"Partitions","title":"Partitions","text":"getindex_safe","category":"page"},{"location":"Combinatorics/EnumerativeCombinatorics/partitions/#getindex_safe","page":"Partitions","title":"getindex_safe","text":"getindex_safe(P::Partition, i::IntegerUnion)\n\nReturn P[i] if i < length(P) and 0 otherwise. It is assumed that i is positive.\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/EnumerativeCombinatorics/partitions/","page":"Partitions","title":"Partitions","text":"If you are sure that P[i] exists, use getindex because this will be faster.","category":"page"},{"location":"Combinatorics/EnumerativeCombinatorics/partitions/#Generating-and-counting","page":"Partitions","title":"Generating and counting","text":"","category":"section"},{"location":"Combinatorics/EnumerativeCombinatorics/partitions/","page":"Partitions","title":"Partitions","text":"partitions(::Oscar.IntegerUnion)\nnumber_of_partitions(::Oscar.IntegerUnion)","category":"page"},{"location":"Combinatorics/EnumerativeCombinatorics/partitions/#partitions-Tuple{Union{Integer, ZZRingElem}}","page":"Partitions","title":"partitions","text":"partitions(n::IntegerUnion)\n\nReturn an iterator over all partitions of a non-negative integer n, produced in lexicographically descending order. Using a smaller integer type for n (e.g. Int8) may increase performance.\n\nThe algorithm used is \"Algorithm ZS1\" by [ZS98]. This algorithm is also discussed in [Knu11], Algorithm P (page 392).\n\nExamples\n\njulia> p = partitions(4);\n\njulia> first(p)\n[4]\n\njulia> collect(p)\n5-element Vector{Partition{Int64}}:\n [4]\n [3, 1]\n [2, 2]\n [2, 1, 1]\n [1, 1, 1, 1]\n\njulia> collect(partitions(Int8(4))) # using less memory\n5-element Vector{Partition{Int8}}:\n Int8[4]\n Int8[3, 1]\n Int8[2, 2]\n Int8[2, 1, 1]\n Int8[1, 1, 1, 1]\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/EnumerativeCombinatorics/partitions/#number_of_partitions-Tuple{Union{Integer, ZZRingElem}}","page":"Partitions","title":"number_of_partitions","text":"number_of_partitions(n::IntegerUnion)\n\nReturn the number of integer partitions of n. For n < 0, return 0.\n\nExamples\n\njulia> number_of_partitions(1000)\n24061467864032622473692149727991\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/EnumerativeCombinatorics/partitions/","page":"Partitions","title":"Partitions","text":"For counting partitions, the Hardy-Ramanujan-Rademachen formula is used, see [Joh12] for details. See also [Knu11], Section 7.2.1.4 and [OEIS], A000041.","category":"page"},{"location":"Combinatorics/EnumerativeCombinatorics/partitions/#Partitions-with-restrictions","page":"Partitions","title":"Partitions with restrictions","text":"","category":"section"},{"location":"Combinatorics/EnumerativeCombinatorics/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/EnumerativeCombinatorics/partitions/","page":"Partitions","title":"Partitions","text":"This is Exercise 11 in [Knu11], Section 7.2.1.4. 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/EnumerativeCombinatorics/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/EnumerativeCombinatorics/partitions/","page":"Partitions","title":"Partitions","text":"julia> collect(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/EnumerativeCombinatorics/partitions/","page":"Partitions","title":"Partitions","text":"and there are 4562 ways for the first question in the exercise:","category":"page"},{"location":"Combinatorics/EnumerativeCombinatorics/partitions/","page":"Partitions","title":"Partitions","text":"julia> length(collect(partitions(100, [1, 2, 5, 10, 20, 50])))\n4562","category":"page"},{"location":"Combinatorics/EnumerativeCombinatorics/partitions/","page":"Partitions","title":"Partitions","text":"The original \"Ways to change one dollar\" problem has 292 solutions:","category":"page"},{"location":"Combinatorics/EnumerativeCombinatorics/partitions/","page":"Partitions","title":"Partitions","text":"julia> length(collect(partitions(100, [1, 5, 10, 25, 50])))\n292","category":"page"},{"location":"Combinatorics/EnumerativeCombinatorics/partitions/","page":"Partitions","title":"Partitions","text":"number_of_partitions(::Oscar.IntegerUnion, ::Oscar.IntegerUnion)","category":"page"},{"location":"Combinatorics/EnumerativeCombinatorics/partitions/#number_of_partitions-Tuple{Union{Integer, ZZRingElem}, Union{Integer, ZZRingElem}}","page":"Partitions","title":"number_of_partitions","text":"number_of_partitions(n::IntegerUnion, k::IntegerUnion)\n\nReturn the number of integer partitions of the non-negative integer n into k >= 0 parts. If n < 0 or k < 0, return 0.\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/EnumerativeCombinatorics/partitions/","page":"Partitions","title":"Partitions","text":"For counting the partitions the recurrence relation p_k(n) = p_k - 1(n - 1) + p_k(n - k) is used, where p_k(n) denotes the number of partitions of n into k parts; see [Knu11], Section 7.2.1.4, Equation (39), and also [OEIS], A008284.","category":"page"},{"location":"Combinatorics/EnumerativeCombinatorics/partitions/","page":"Partitions","title":"Partitions","text":"partitions(::Oscar.IntegerUnion, ::Oscar.IntegerUnion, ::Oscar.IntegerUnion, ::Oscar.IntegerUnion)\npartitions(::T, ::Vector{T}) where T <: Oscar.IntegerUnion","category":"page"},{"location":"Combinatorics/EnumerativeCombinatorics/partitions/#partitions-NTuple{4, Union{Integer, ZZRingElem}}","page":"Partitions","title":"partitions","text":"partitions(n::IntegerUnion, k::IntegerUnion; only_distinct_parts::Bool = false)\npartitions(n::IntegerUnion, k::IntegerUnion, lb::IntegerUnion, ub::IntegerUnion; only_distinct_parts::Bool = false)\n\nReturn an iterator over all partitions of a non-negative integer n into k >= 0 parts. Optionally, a lower bound lb >= 0 and an upper bound ub for the parts can be supplied. In this case, the partitions are produced in decreasing order.\n\nThere are two choices for the parameter only_distinct_parts:\n\nfalse: no further restriction (default);\ntrue: only distinct parts.\n\nThe implemented algorithm is \"parta\" in [RJ76].\n\nExamples\n\nAll partitions of 7 into 3 parts:\n\njulia> collect(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\nAll partitions of 7 into 3 parts where all parts are between 1 and 4:\n\njulia> collect(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> collect(partitions(7, 3, 1, 4; only_distinct_parts = true))\n1-element Vector{Partition{Int64}}:\n [4, 2, 1]\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/EnumerativeCombinatorics/partitions/#partitions-Union{Tuple{T}, Tuple{T, Vector{T}}} where T<:Union{Integer, ZZRingElem}","page":"Partitions","title":"partitions","text":"partitions(n::T, v::Vector{T}) where T <: IntegerUnion\npartitions(n::T, v::Vector{T}, mu::Vector{<:IntegerUnion}) where T <: IntegerUnion\npartitions(n::T, k::IntegerUnion, v::Vector{T}, mu::Vector{<:IntegerUnion}) where T <: IntegerUnion\n\nReturn an iterator over all partitions of a non-negative integer n where each part is an element in the vector v of positive integers. It is assumed that the entries in v are strictly increasing.\n\nIf the optional vector mu is supplied, then each v[i] occurs a maximum of mu[i] > 0 times per partition.\n\nIf the optional integer k >= 0 is supplied, the partitions will be into k parts. In this case, the partitions are produced in lexicographically decreasing order.\n\nThe implemented algorithm is \"partb\" in [RJ76].\n\nExample\n\nThe number of partitions of 100 where the parts are from {1, 2, 5, 10, 20, 50}:\n\njulia> length(collect(partitions(100, [1, 2, 5, 10, 20, 50])))\n4562\n\nAll 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> collect(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\nThe 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> collect(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\n\n\n\n\n","category":"method"},{"location":"Combinatorics/EnumerativeCombinatorics/partitions/#Operations","page":"Partitions","title":"Operations","text":"","category":"section"},{"location":"Combinatorics/EnumerativeCombinatorics/partitions/","page":"Partitions","title":"Partitions","text":"The conjugate of a partition lambda is obtained by considering its Young diagram (see Tableaux) and then flipping it along its main diagonal, see [Ful97], page 2, and [Knu11], Section 7.2.1.4.","category":"page"},{"location":"Combinatorics/EnumerativeCombinatorics/partitions/","page":"Partitions","title":"Partitions","text":"conjugate","category":"page"},{"location":"Combinatorics/EnumerativeCombinatorics/partitions/#conjugate","page":"Partitions","title":"conjugate","text":"conjugate(lambda::Partition)\n\nReturn the conjugate of the partition lambda.\n\nExamples\n\njulia> conjugate(partition(8, 8, 8, 7, 2, 1, 1))\n[7, 5, 4, 4, 4, 4, 4, 3]\n\n\n\n\n\n","category":"function"},{"location":"Combinatorics/EnumerativeCombinatorics/partitions/#Relations","page":"Partitions","title":"Relations","text":"","category":"section"},{"location":"Combinatorics/EnumerativeCombinatorics/partitions/","page":"Partitions","title":"Partitions","text":"The dominance order on partitions is the partial order trianglerighteq defined by lambda trianglerighteqmu if and only if lambda_1 + dots + lambda_i geq mu_1 + dots + mu_i for all i. If lambdatrianglerighteqmu one says that lambda dominates mu. See [Ful97], page 26, and [Knu11], Section 7.2.1.4, Exercise 54.","category":"page"},{"location":"Combinatorics/EnumerativeCombinatorics/partitions/","page":"Partitions","title":"Partitions","text":"Note that whereas the lexicographic ordering is a total ordering, the dominance ordering is not. Further, [Knu11] says majorizes instead of dominates and uses the symbol succeq instead of trianglerighteq.","category":"page"},{"location":"Combinatorics/EnumerativeCombinatorics/partitions/","page":"Partitions","title":"Partitions","text":"dominates","category":"page"},{"location":"Combinatorics/EnumerativeCombinatorics/partitions/#dominates","page":"Partitions","title":"dominates","text":"dominates(lambda::Partition, mu::Partition)\n\nReturn true if lambda dominates mu, false otherwise.\n\nExamples\n\njulia> dominates(partition(3, 1), partition(2, 2))\ntrue\n\njulia> dominates(partition(4, 1), partition(3, 3))\nfalse\n\n\n\n\n\n","category":"function"},{"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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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 pseudo-reflections contained in the group G, see [Ben93].","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 pseudo-reflections.\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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 [Kol13].\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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 [Kol13].\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/IntersectionTheory/BlowUps/","page":"Blowups","title":"Blowups","text":"CurrentModule = Oscar","category":"page"},{"location":"Experimental/IntersectionTheory/BlowUps/#Blowups","page":"Blowups","title":"Blowups","text":"","category":"section"},{"location":"Experimental/IntersectionTheory/BlowUps/","page":"Blowups","title":"Blowups","text":"present_finite_extension_ring(F::Oscar.AffAlgHom)","category":"page"},{"location":"Experimental/IntersectionTheory/BlowUps/#present_finite_extension_ring-Tuple{Oscar.MPolyAnyMap{DT, CT, Nothing} where {T<:FieldElem, U1<:MPolyRingElem{T}, U2<:MPolyRingElem{T}, DT<:Union{MPolyRing{T}, MPolyQuoRing{U1}}, CT<:Union{MPolyRing{T}, MPolyQuoRing{U2}}}}","page":"Blowups","title":"present_finite_extension_ring","text":" present_finite_extension_ring(F::Oscar.AffAlgHom)\n\nGiven a finite homomorphism F A rightarrow B of algebras of type <: Union{MPolyRing, MPolyQuoRing} over a field, return a presentation\n\nA^r rightarrow A^srightarrow B rightarrow 0\n\nof B as an A-module.\n\nMore precisely, return a tuple (gs, PM, sect), say, where\n\ngs is a vector of polynomials representing generators for B as an A-module,\nPM is an r times s-matrix of polynomials defining the map A^r rightarrow A^s, and\nsect is a function which gives rise to a section of the augmentation map $ A^s\\rightarrow B$.\n\nnote: Note\nThe finiteness condition on F is checked by the function.\n\nnote: Note\nThe function is implemented so that the last element of gs is one(B).\n\nExamples\n\njulia> RA, (h,) = polynomial_ring(QQ, [:h]);\n\njulia> A, _ = quo(RA, ideal(RA, [h^9]));\n\njulia> RB, (k, l) = polynomial_ring(QQ, [:k, :l]);\n\njulia> B, _ = quo(RB, ideal(RB, [k^3, l^3]));\n\njulia> F = hom(A, B, [k+l])\nRing homomorphism\n from quotient of multivariate polynomial ring by ideal (h^9)\n to quotient of multivariate polynomial ring by ideal (k^3, l^3)\ndefined by\n h -> k + l\n\njulia> gs, PM, sect = present_finite_extension_ring(F);\n\njulia> gs\n3-element Vector{QQMPolyRingElem}:\n l^2\n l\n 1\n\njulia> PM\n3×3 Matrix{QQMPolyRingElem}:\n h^3 0 0\n -3*h^2 h^3 0\n 3*h -3*h^2 h^3\n\njulia> sect(k*l)\n3-element Vector{QQMPolyRingElem}:\n -1\n h\n 0\n\n\njulia> R, (x, y, z) = polynomial_ring(QQ, [:x, :y, :z]);\n\njulia> I = ideal(R, [z^2-y^2*(y+1)]);\n\njulia> A, _ = quo(R, I);\n\njulia> B, (s,t) = polynomial_ring(QQ, [:s, :t]);\n\njulia> F = hom(A,B, [s, t^2-1, t*(t^2-1)])\nRing homomorphism\n from quotient of multivariate polynomial ring by ideal (-y^3 - y^2 + z^2)\n to multivariate polynomial ring in 2 variables over QQ\ndefined by\n x -> s\n y -> t^2 - 1\n z -> t^3 - t\n\njulia> gs, PM, sect = present_finite_extension_ring(F);\n\njulia> gs\n2-element Vector{QQMPolyRingElem}:\n t\n 1\n\njulia> PM\n2×2 Matrix{QQMPolyRingElem}:\n y -z\n -z y^2 + y\n\njulia> sect(t)\n2-element Vector{QQMPolyRingElem}:\n 1\n 0\n\njulia> sect(one(B))\n2-element Vector{QQMPolyRingElem}:\n 0\n 1\n\njulia> sect(s)\n2-element Vector{QQMPolyRingElem}:\n 0\n x\n\n\njulia> A, (a, b, c) = polynomial_ring(QQ, [:a, :b, :c]);\n\njulia> R, (x, y, z) = polynomial_ring(QQ, [:x, :y, :z]);\n\njulia> I = ideal(R, [x*y]);\n\njulia> B, _ = quo(R, I);\n\njulia> (x, y, z) = gens(B);\n\njulia> F = hom(A, B, [x^2+z, y^2-1, z^3])\nRing homomorphism\n from multivariate polynomial ring in 3 variables over QQ\n to quotient of multivariate polynomial ring by ideal (x*y)\ndefined by\n a -> x^2 + z\n b -> y^2 - 1\n c -> z^3\n\njulia> gs, PM, sect = present_finite_extension_ring(F);\n\njulia> gs\n2-element Vector{QQMPolyRingElem}:\n y\n 1\n\njulia> PM\n2×2 Matrix{QQMPolyRingElem}:\n a^3 - c 0\n 0 a^3*b + a^3 - b*c - c\n\njulia> sect(y)\n2-element Vector{QQMPolyRingElem}:\n 1\n 0\n\njulia> sect(one(B))\n2-element Vector{QQMPolyRingElem}:\n 0\n 1\n\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/IntersectionTheory/BlowUps/","page":"Blowups","title":"Blowups","text":"blowup(i::AbstractVarietyMap; symbol::String = \"e\")","category":"page"},{"location":"Experimental/IntersectionTheory/BlowUps/#blowup-Tuple{AbstractVarietyMap}","page":"Blowups","title":"blowup","text":" blowup(i::AbstractVarietyMap; symbol::String=\"e\")\n\nGiven an inclusion i$ : $ X rightarrow Y, say, return the blowup of Y along X.\n\nMore precisely, return a tuple (Bl, E, j), say, where\n\nBl, an abstract variety, is the blowup,\nE, an abstract variety, is the exceptional divisor, and\nj, a map of abstract varieties, is the inclusion of E into Bl.\n\nnote: Note\nThe resulting maps Bl rightarrow Y and E rightarrow X are obtained entering structure_map(Bl) and structure_map(E), respectively.\n\nExamples\n\njulia> P2 = abstract_projective_space(2)\nAbstractVariety of dim 2\n\njulia> P5 = abstract_projective_space(5, symbol = \"H\")\nAbstractVariety of dim 5\n\njulia> h = gens(P2)[1]\nh\n\njulia> H = gens(P5)[1]\nH\n\njulia> i = hom(P2, P5, [2*h])\nAbstractVarietyMap from AbstractVariety of dim 2 to AbstractVariety of dim 5\n\njulia> Bl, E, j = blowup(i)\n(AbstractVariety of dim 5, AbstractVariety of dim 4, AbstractVarietyMap from AbstractVariety of dim 4 to AbstractVariety of dim 5)\n\njulia> e, HBl = gens(chow_ring(Bl))\n2-element Vector{MPolyQuoRingElem{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}}:\n e\n H\n\njulia> integral((6*HBl-2*e)^5)\n3264\n\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/IntersectionTheory/BlowUps/","page":"Blowups","title":"Blowups","text":"blowup_points(X::AbstractVariety, n::Int; symbol::String = \"e\")","category":"page"},{"location":"Experimental/IntersectionTheory/BlowUps/#blowup_points-Tuple{AbstractVariety, Int64}","page":"Blowups","title":"blowup_points","text":"function blowup_points(X::AbstractVariety, n::Int; symbol::String = \"e\")\n\nReturn the blowup of X at n points.\n\nExamples\n\njulia> P2 = abstract_projective_space(2)\nAbstractVariety of dim 2\n\njulia> Bl = blowup_points(P2, 1)\nAbstractVariety of dim 2\n\njulia> chow_ring(Bl)\nQuotient\n of multivariate polynomial ring in 2 variables over QQ graded by\n e -> [1]\n h -> [1]\n by ideal (e*h, e^2 + h^2)\n\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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 = Oscar.doctestsetup()","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(F::T) where T <: FinField\next_of_degree","category":"page"},{"location":"Fields/algebraic_closure_fp/#algebraic_closure-Tuple{T} where T<:FinField","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 order 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":"method"},{"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 = Oscar.doctestsetup()","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(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(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(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(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\n from Sym(4)\n to Sym(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(4)\n\njulia> A = automorphism_group(S)\nAut( Sym( [ 1 .. 4 ] ) )\n\njulia> g = hom(S,S,x->x^S[1])\nGroup homomorphism\n from Sym(4)\n to Sym(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::GAPGroup) where T <: GAPGroup\nrestrict_automorphism(f::GAPGroupElem{AutomorphismGroup{T}}, H::GAPGroup, 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}}, Oscar.GAPGroup}} where T<:Oscar.GAPGroup","page":"Groups of automorphisms","title":"is_invariant","text":"is_invariant(f::GAPGroupElem{AutomorphismGroup{T}}, H::GAPGroup) where T <: GAPGroup\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}}, Oscar.GAPGroup}, Tuple{GAPGroupElem{AutomorphismGroup{T}}, Oscar.GAPGroup, Any}} where T<:Oscar.GAPGroup","page":"Groups of automorphisms","title":"restrict_automorphism","text":"restrict_automorphism(f::GAPGroupElem{AutomorphismGroup{T}}, H::GAPGroup) where T <: GAPGroup\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":"Hecke/manual/misc/conjugacy/#Conjugacy-of-integral-matrices","page":"Conjugacy of integral matrices","title":"Conjugacy of integral matrices","text":"","category":"section"},{"location":"Hecke/manual/misc/conjugacy/","page":"Conjugacy of integral matrices","title":"Conjugacy of integral matrices","text":"is_GLZ_conjugate(::ZZMatrix, ::ZZMatrix)","category":"page"},{"location":"Hecke/manual/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\n\n","category":"method"},{"location":"Hecke/manual/algebras/basics/#Basics","page":"Basics","title":"Basics","text":"","category":"section"},{"location":"Hecke/manual/algebras/basics/","page":"Basics","title":"Basics","text":"CurrentModule = Hecke\nDocTestSetup = quote\n using Hecke\nend","category":"page"},{"location":"Hecke/manual/algebras/basics/#Creation-of-algebras","page":"Basics","title":"Creation of algebras","text":"","category":"section"},{"location":"Hecke/manual/algebras/basics/","page":"Basics","title":"Basics","text":"See the corresponding sections on structure constant algebras.","category":"page"},{"location":"Hecke/manual/algebras/basics/","page":"Basics","title":"Basics","text":"zero_algebra(::Field)","category":"page"},{"location":"Hecke/manual/algebras/basics/#zero_algebra-Tuple{Field}","page":"Basics","title":"zero_algebra","text":"zero_algebra([T, ] K::Field) -> AbstractAssociativeAlgebra\n\nReturn the zero ring as an algebra over the field K.\n\nThe optional first argument determines the type of the algebra, and can be StructureConstantAlgebra (default) or MatrixAlgebra.\n\nExamples\n\njulia> A = zero_algebra(QQ)\nStructure constant algebra of dimension 0 over QQ\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/algebras/basics/#Basic-properties","page":"Basics","title":"Basic properties","text":"","category":"section"},{"location":"Hecke/manual/algebras/basics/","page":"Basics","title":"Basics","text":"base_ring(::Hecke.AbstractAssociativeAlgebra)\nbasis(::Hecke.AbstractAssociativeAlgebra)","category":"page"},{"location":"Hecke/manual/algebras/basics/#base_ring-Tuple{Hecke.AbstractAssociativeAlgebra}","page":"Basics","title":"base_ring","text":"base_ring(A::AbstractAssociativeAlgebra) -> Field\n\nGiven a K-algebra A, return K.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/algebras/basics/#basis-Tuple{Hecke.AbstractAssociativeAlgebra}","page":"Basics","title":"basis","text":"basis(A::AbstractAssociativeAlgebra) -> Vector\n\nGiven a K-algebra A return the K-basis of A. See also coordinates to get the the coordinates of an element with respect to the bases.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/algebras/basics/#Predicates","page":"Basics","title":"Predicates","text":"","category":"section"},{"location":"Hecke/manual/algebras/basics/","page":"Basics","title":"Basics","text":"is_zero(::Hecke.AbstractAssociativeAlgebra)\nis_commutative(::Hecke.AbstractAssociativeAlgebra)\nis_central(::AbstractAssociativeAlgebra)","category":"page"},{"location":"Hecke/manual/algebras/basics/#is_zero-Tuple{Hecke.AbstractAssociativeAlgebra}","page":"Basics","title":"is_zero","text":"is_zero(A::AbstractAssociativeAlgebra) -> Bool\n\nReturn whether A is the zero algebra.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/algebras/basics/#is_commutative-Tuple{Hecke.AbstractAssociativeAlgebra}","page":"Basics","title":"is_commutative","text":"is_commutative(A::AbstractAssociativeAlgebra) -> Bool\n\nReturn whether A is commutative.\n\nExamples\n\njulia> A = matrix_algebra(QQ, 2);\n\njulia> is_commutative(A)\nfalse\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/algebras/basics/#is_central-Tuple{Hecke.AbstractAssociativeAlgebra}","page":"Basics","title":"is_central","text":"is_central(A::AbstractAssociativeAlgebra)\n\nReturn whether the K-algebra A is central, that is, whether K is the center of A.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/algebras/basics/#Generators","page":"Basics","title":"Generators","text":"","category":"section"},{"location":"Hecke/manual/algebras/basics/","page":"Basics","title":"Basics","text":"gens(::AbstractAssociativeAlgebra)\ngens_with_data(::AbstractAssociativeAlgebra)","category":"page"},{"location":"Hecke/manual/algebras/basics/#gens-Tuple{Hecke.AbstractAssociativeAlgebra}","page":"Basics","title":"gens","text":"gens(A::AbstractAssociativeAlgebra; thorough_search::Bool = false) -> Vector\n\nGiven a K-algebra A, return a subset of basis(A), which generates A as an algebra over K.\n\nIf thorough_search is true, the number of returned generators is possibly smaller. This will in general increase the runtime. It is not guaranteed that the number of generators is minimal in any case.\n\nThe gens_with_data function computes additional data for expressing a basis as words in the generators.\n\nExamples\n\njulia> A = matrix_algebra(QQ, 3);\n\njulia> gens(A; thorough_search = true)\n5-element Vector{MatAlgebraElem{QQFieldElem, QQMatrix}}:\n [1 0 0; 0 0 0; 0 0 0]\n [0 0 0; 1 0 0; 0 0 0]\n [0 0 0; 0 0 0; 1 0 0]\n [0 1 0; 0 0 0; 0 0 0]\n [0 0 1; 0 0 0; 0 0 0]\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/algebras/basics/#gens_with_data-Tuple{Hecke.AbstractAssociativeAlgebra}","page":"Basics","title":"gens_with_data","text":"gens_with_data(A::AbstractAssociativeAlgebra; thorough_search::Bool = false)\n -> Vector, Vector, Vector\n\nGiven a K-algebra A, return a triple (G B w) consisting of\n\na subset G of basis(A), which generates A as an algebra over K,\na (new) basis B and a vector w::Vector{Tuple{Int, Int}}, such that B[i] = prod(G[j]^k for (j, k) in w[i].\n\nIf thorough_search is true, the number of returned generators is possibly smaller. This will in general increase the runtime. It is not guaranteed that the number of generators is minimal in any case.\n\nExamples\n\njulia> A = matrix_algebra(QQ, 3);\n\njulia> G, B, w = gens_with_data(A; thorough_search = true);\n\njulia> B[1] == prod(G[i]^j for (i, j) in w[1])\ntrue\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/algebras/basics/#Center","page":"Basics","title":"Center","text":"","category":"section"},{"location":"Hecke/manual/algebras/basics/","page":"Basics","title":"Basics","text":"center(::Hecke.AbstractAssociativeAlgebra)\ndimension_of_center(::Hecke.AbstractAssociativeAlgebra)\ndimension_over_center(::Hecke.AbstractAssociativeAlgebra)","category":"page"},{"location":"Hecke/manual/algebras/basics/#center-Tuple{Hecke.AbstractAssociativeAlgebra}","page":"Basics","title":"center","text":"center(A::AbstractAssociativeAlgebra)\n -> StructureConstantAlgebra, Map\n\nReturns the center C of A and the inclusion C to A. Note that C itself is an algebra.\n\nExamples\n\njulia> A = matrix_algebra(QQ, 2);\n\njulia> C, CtoA = center(A);\n\njulia> C\nStructure constant algebra of dimension 1 over QQ\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/algebras/basics/#dimension_of_center-Tuple{Hecke.AbstractAssociativeAlgebra}","page":"Basics","title":"dimension_of_center","text":"dimension_of_center(A::AbstractAssociativeAlgebra) -> Int\n\nGiven a K-algebra, return the K-dimension of the center of A.\n\nExamples\n\njulia> A = matrix_algebra(QQ, 2);\n\njulia> dimension_of_center(A)\n1\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/algebras/basics/#dimension_over_center-Tuple{Hecke.AbstractAssociativeAlgebra}","page":"Basics","title":"dimension_over_center","text":"dimension_over_center(A::AbstractAssociativeAlgebra) -> Int\n\nGiven a simple K-algebra with center C, return the C-dimension A.\n\nExamples\n\njulia> A = matrix_algebra(QQ, 2);\n\njulia> dimension_of_center(A)\n1\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":"puiseux_series_ring(R::Ring, prec_max::Int, s::VarName; cached::Bool = true)","category":"page"},{"location":"AbstractAlgebra/puiseux/","page":"Generic Puiseux series","title":"Generic Puiseux series","text":"puiseux_series_ring(R::Field, prec_max::Int, s::VarName; cached::Bool = true)","category":"page"},{"location":"AbstractAlgebra/puiseux/","page":"Generic Puiseux series","title":"Generic Puiseux series","text":"puiseux_series_field(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 = puiseux_series_ring(ZZ, 10, :x)\n(Puiseux series ring in x over integers, x + O(x^11))\n\njulia> S, y = puiseux_series_field(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 = puiseux_series_ring(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 = puiseux_series_ring(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 = puiseux_series_ring(QQ, 10, :t)\n(Puiseux series field in t over rationals, t + O(t^11))\n\njulia> S, x = puiseux_series_ring(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":"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\ninv(f::EllCrvIso) -> EllCrvIso\n\nReturn the inverse of the isomorphism f.\n\n\n\n\n\nBase.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::LocalizedEuclideanRingElem{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\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 = puiseux_series_ring(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(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::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::MPolyRingElem{T}, x::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\nderivative(a::Generic.PuiseuxSeriesElem{T}) where T <: RingElement\n\nReturn the derivative of the given Puiseux series a.\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(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\nintegral(f::RelPowerSeriesRingElem{T}) -> RelPowerSeriesRingElem\n\nReturn the integral of the power series f.\n\n\n\n\n\nintegral(a::Generic.PuiseuxSeriesElem{T}) where T <: RingElement\n\nReturn the integral of the given Puiseux series a.\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 = puiseux_series_ring(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::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\nexp(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\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":"Base.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::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\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 = puiseux_series_ring(R, 30, :x)\n(Puiseux series ring in x over univariate polynomial ring, x + O(x^31))\n\njulia> T, z = puiseux_series_ring(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, warnonly=true, open_browser=true, start_server=false)\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.10 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 warnonly is passed on to makedocs of Documenter.jl and if set to false then according to the manual of Documenter.jl \"a doctesting error will always make makedocs throw an error in this mode\". Alternatively, one can pass a list of symbols to warnonly to suppress errors for the given error types.\n\nTo prevent the opening of the browser at the end, set the optional parameter open_browser to false.\n\nAlternatively, one can use the optional parameter start_server to start a web server in the build directory which is accessible via 127.0.0.1:8000. If both start_server and open_browser are true, the browser will show this page. The server keeps running in the background until the julia session is terminated, so the proposed usage for this option is to run build_doc(start_server = true) for the first build and build_doc(open_browser = false) for following builds and only refresh the browser tab.\n\nWhen working on the manual the Revise package can significantly speed 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, subsequent 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/","page":"Documenting OSCAR code","title":"Documenting OSCAR code","text":"note: Browser reports denied access\nDepending on your system, it might happen that the browser opens after a successful build, but only informs you that the access to the file was denied. This happens, for example, on Ubuntu which comes with a sandboxed Firefox. In this case, using build_doc with start_server = true should circumvent this problem.","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":"If you just want to fix some of the jldoctests, and do not want to build the documentation, you can also use Oscar.doctest_fix:","category":"page"},{"location":"DeveloperDocumentation/documentation/","page":"Documenting OSCAR code","title":"Documenting OSCAR code","text":"Oscar.doctest_fix","category":"page"},{"location":"DeveloperDocumentation/documentation/#doctest_fix","page":"Documenting OSCAR code","title":"doctest_fix","text":"doctest_fix(f::Function; set_meta::Bool = false)\n\nFixes all doctests for the given function f.\n\nExample\n\nThe following call fixes all doctests for the function symmetric_group:\n\njulia> Oscar.doctest_fix(symmetric_group)\n\n\n\n\n\ndoctest_fix(path::String; set_meta::Bool = false)\n\nFixes all doctests for all files in Oscar where path occurs in the full pathname.\n\nExample\n\nThe following call fixes all doctests in files that live in a directory called Rings (or a subdirectory thereof), so e.g. everything in src/Rings/:\n\njulia> Oscar.doctest_fix(\"/Rings/\")\n\n\n\n\n\n","category":"function"},{"location":"DeveloperDocumentation/documentation/","page":"Documenting OSCAR code","title":"Documenting OSCAR code","text":"danger: Danger\nPlease use these commands 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 these commands fail 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":"DeveloperDocumentation/documentation/","page":"Documenting OSCAR code","title":"Documenting OSCAR code","text":"Please follow the additional guidelines below, that are not checked by bibtool:","category":"page"},{"location":"DeveloperDocumentation/documentation/","page":"Documenting OSCAR code","title":"Documenting OSCAR code","text":"Do not escape special characters like umlauts or accented characters. Instead, use the unicode character directly.\nYou do not need to use braces to preserve capitalization as DocumenterCitations.jl keeps entries as is (in contrast to bibtex). In some cases, braces can even be harmful, i.e., show up in the output.\nIf a DOI is available for your reference, please add it as a doi field to the BibTeX entry. In this case, please refrain from adding an additional url field.\nIf your reference has no DOI or the paper is not open-access, but is available as an arXiv preprint, you can add the arXiv link as a eprint field (even additionally to a doi field). For other preprint servers (e.g. HAL), please refer to the DocumenterCitations.jl docs.\nDocuments available only as an arXiv preprint should be added as @Misc entries with the arXiv-ID in the eprint field, e.g., archiveprefix = {arXiv} and eprint = {2008.12651}.","category":"page"},{"location":"General/architecture/","page":"Architecture","title":"Architecture","text":"CurrentModule = Oscar\nDocTestSetup = Oscar.doctestsetup()","category":"page"},{"location":"General/architecture/","page":"Architecture","title":"Architecture","text":"using Oscar","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":"AlgebraicGeometry/Schemes/RationalPointsAffine/","page":"Rational Points on Affine Schemes","title":"Rational Points on Affine Schemes","text":"CurrentModule = Oscar","category":"page"},{"location":"AlgebraicGeometry/Schemes/RationalPointsAffine/","page":"Rational Points on Affine Schemes","title":"Rational Points on Affine Schemes","text":"using Oscar","category":"page"},{"location":"AlgebraicGeometry/Schemes/RationalPointsAffine/#Rational-Points-on-Affine-Schemes","page":"Rational Points on Affine Schemes","title":"Rational Points on Affine Schemes","text":"","category":"section"},{"location":"AlgebraicGeometry/Schemes/RationalPointsAffine/","page":"Rational Points on Affine Schemes","title":"Rational Points on Affine Schemes","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/Schemes/RationalPointsAffine/#AbsAffineRationalPoint","page":"Rational Points on Affine Schemes","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/Schemes/RationalPointsAffine/#AffineRationalPoint","page":"Rational Points on Affine Schemes","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/Schemes/RationalPointsAffine/#coordinates-Tuple{Oscar.AffineRationalPoint}","page":"Rational Points on Affine Schemes","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/Schemes/RationalPointsAffine/#ideal-Tuple{AbsAffineRationalPoint}","page":"Rational Points on Affine Schemes","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/Schemes/RationalPointsAffine/#scheme-Tuple{AbsAffineRationalPoint}","page":"Rational Points on Affine Schemes","title":"scheme","text":"scheme(P::AbsAffineRationalPoint) -> AbsAffineScheme\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/Schemes/RationalPointsAffine/#closed_embedding-Tuple{AbsAffineRationalPoint}","page":"Rational Points on Affine Schemes","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/Schemes/RationalPointsAffine/#is_smooth-Tuple{AbsAffineRationalPoint}","page":"Rational Points on Affine Schemes","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/Schemes/RationalPointsAffine/#tangent_space-Tuple{AbsAffineRationalPoint{<:FieldElem}}","page":"Rational Points on Affine Schemes","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::AbsAffineScheme{<:Field}, P::AbsAffineRationalPoint)\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/RationalPointsAffine/","page":"Rational Points on Affine Schemes","title":"Rational Points on Affine Schemes","text":"Some experimental methods are available too. Note that their interface is likely to change in the future.","category":"page"},{"location":"AlgebraicGeometry/Schemes/RationalPointsAffine/","page":"Rational Points on Affine Schemes","title":"Rational Points on Affine Schemes","text":"is_du_val_singularity(P::AbsAffineRationalPoint{<:FieldElem})\ndecide_du_val_singularity(P::AbsAffineRationalPoint{<:FieldElem,<:Any})","category":"page"},{"location":"AlgebraicGeometry/Schemes/RationalPointsAffine/#is_du_val_singularity-Tuple{AbsAffineRationalPoint{<:FieldElem}}","page":"Rational Points on Affine Schemes","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/Schemes/RationalPointsAffine/#decide_du_val_singularity-Tuple{AbsAffineRationalPoint{<:FieldElem}}","page":"Rational Points on Affine Schemes","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/manual/elliptic_curves/intro/#Introduction","page":"Introduction","title":"Introduction","text":"","category":"section"},{"location":"Hecke/manual/elliptic_curves/intro/","page":"Introduction","title":"Introduction","text":"CurrentModule = Hecke\nDocTestSetup = quote\n using Hecke\nend\n","category":"page"},{"location":"Hecke/manual/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/manual/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/manual/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/manual/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/manual/elliptic_curves/intro/","page":"Introduction","title":"Introduction","text":"y^2 = x^3 + a_4 x + a_6","category":"page"},{"location":"Hecke/manual/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":"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 [Oxl11].","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\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)\nmatroid_from_matroid_hex(str::AbstractString)","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 [Oxl11].\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 [Oxl11].\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 [Oxl11].\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 [Oxl11].\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 [Oxl11].\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 [Oxl11].\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","page":"Matroids","title":"cycle_matroid","text":"cycle_matroid(g::Graph{Undirected})\n\nThe cycle matroid of a graph g.\n\nSee Section 1.1 of [Oxl11].\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":"function"},{"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 [Oxl11].\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/#matroid_from_matroid_hex-Tuple{AbstractString}","page":"Matroids","title":"matroid_from_matroid_hex","text":"matroid_from_matroid_hex(str::AbstractString)\n\nReturns a matroid from a string of hex characters.\n\nExamples\n\nTo retrieve the fano matroid from its hex encoding write:\n\njulia> matroid_from_matroid_hex(\"r3n7_3f7eefd6f\")\nMatroid of rank 3 on 7 elements\n\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()\nmoebius_kantor_matroid()\nnon_fano_matroid()\nnon_pappus_matroid()\npappus_matroid()\nperles_matroid()\nR10_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/#moebius_kantor_matroid-Tuple{}","page":"Matroids","title":"moebius_kantor_matroid","text":"moebius_kantor_matroid()\n\nConstruct the Möbius-Kantor 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/#perles_matroid-Tuple{}","page":"Matroids","title":"perles_matroid","text":"perles_matroid()\n\nConstruct the Perles matroid.\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/matroids/#R10_matroid-Tuple{}","page":"Matroids","title":"R10_matroid","text":"R10_matroid()\n\nConstruct the R10 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 [Oxl11].\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 [Oxl11]. 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 [Oxl11]. 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 [Oxl11].\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 [Oxl11].\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 [Oxl11].\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 [Oxl11].\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 [Oxl11].\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 [Oxl11].\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, Edge, 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 [Oxl11].\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, Edge, 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 [Oxl11].\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, Edge, Integer, String, ZZRingElem}, Union{Char, Edge, 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 [Oxl11].\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, Edge, Integer, String, ZZRingElem}, Union{Char, Edge, 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 [Oxl11].\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)\nmatroid_hex(M::Matroid)\nautomorphism_group(M::Matroid)\nmatroid_base_polytope(M::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([::Type{Int},] M::Matroid)\n\nReturn the list of bases of the matroid M. If Int is passed as a first argument then the bases will be returned as indices instead of ground set elements.\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{Int64}}:\n []\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{Int64}}:\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 [Oxl11].\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{Int64}}:\n []\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{Int64}}:\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, Edge, 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 [Oxl11]. 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, Edge, 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 [Oxl11]. 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{Int64}}:\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{Int64}}:\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 [Oxl11].\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 [Oxl11].\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 [Oxl11].\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 [Oxl11].\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 [Oxl11].\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 [Oxl11].\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 [Oxl11].\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 [Oxl11].\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 [Oxl11].\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 [Oxl11].\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())\nInt64[]\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())\nInt64[]\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 [Oxl11].\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 [Oxl11].\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 [Oxl11].\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 [Oxl11].\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 [Oxl11].\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 [Oxl11].\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 [Oxl11].\n\nExamples\n\njulia> tutte_connectivity(fano_matroid())\n3\n\njulia> tutte_connectivity(uniform_matroid(2,4))\ninfinity\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)\ntutte_polynomial(M::Matroid; parent::ZZMPolyRing)\ntutte_polynomial(parent::ZZMPolyRing, 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 [Oxl11].\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)\ncharacteristic_polynomial(M::Matroid; parent::ZZPolyRing)\ncharacteristic_polynomial(parent::ZZPolyRing, 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 [Oxl11].\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)\nreduced_characteristic_polynomial(M::Matroid; parent::ZZPolyRing)\nreduced_characteristic_polynomial(parent::ZZPolyRing, 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 [Oxl11].\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 of the matroid M.\n\nExamples\n\nTo get the revlex basis encoding of the fano matroid and to produce a matrod form the encoding write:\n\njulia> str = revlex_basis_encoding(fano_matroid())\n\"0******0******0***0******0*0**0****\"\n\njulia> matroid_from_revlex_basis_encoding(str, 3, 7)\nMatroid of rank 3 on 7 elements\n\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/#matroid_hex-Tuple{Matroid}","page":"Matroids","title":"matroid_hex","text":"matroid_hex(M::Matroid)\n\nStores a matroid as a string of hex characters. The first part of the string is \"r\" followed by the rank of the matroid. This is followed by \"n\" and the number of elements. The rest of the string is the revlex basis encoding. The encoding is done by converting the basis encoding to a vector of bits and then to a string of characters. The bits are padded to a multiple of 4 and then converted to hex characters.\n\nExamples\n\nTo get the hex encoding of the fano matroid write:\n\njulia> matroid_hex(fano_matroid())\n\"r3n7_3f7eefd6f\"\n\n\n\n\n\n\n","category":"method"},{"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)\nPermutation group of degree 4\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/matroids/#matroid_base_polytope-Tuple{Matroid}","page":"Matroids","title":"matroid_base_polytope","text":"matroid_base_polytope(M::Matroid)\n\nThe base polytope of the matroid M. \n\nExamples\n\njulia> D = matroid_base_polytope(uniform_matroid(2,4));\n\njulia> vertices(D)\n6-element SubObjectIterator{PointVector{QQFieldElem}}:\n [1, 1, 0, 0]\n [1, 0, 1, 0]\n [1, 0, 0, 1]\n [0, 1, 1, 0]\n [0, 1, 0, 1]\n [0, 0, 1, 1]\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 [AHK18] and [BES19]. \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 [BHMPW20]. \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/#Quantum-Automorphisms","page":"Matroids","title":"Quantum Automorphisms","text":"","category":"section"},{"location":"Combinatorics/matroids/","page":"Matroids","title":"Matroids","text":"quantum_symmetric_group(n::Int)\nquantum_automorphism_group(M::Matroid, structure::Symbol)","category":"page"},{"location":"Combinatorics/matroids/#quantum_symmetric_group-Tuple{Int64}","page":"Matroids","title":"quantum_symmetric_group","text":"quantum_symmetric_group(n::Int)\n\nReturn the ideal that defines the quantum symmetric group on n elements. It is comprised of 2*n + n^2 + 2*n*n*(n-1) many generators.\n\nThe relations are:\n\nrow and column sum relations: 2*n relations\nidempotent relations: n^2 relations\nrelations of type u[i,j]*u[i,k] and u[j,i]*u[k,i] for k != j: 2*n*n*(n-1) relations\n\nExample\n\njulia> S4 = quantum_symmetric_group(4);\n\njulia> length(gens(S4))\n120\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/matroids/#quantum_automorphism_group-Tuple{Matroid, Symbol}","page":"Matroids","title":"quantum_automorphism_group","text":"quantum_automorphism_group(M::Matroid, structure::Symbol=:bases)\n\nReturn the ideal that defines the quantum automorphism group of a matroid for a given structure.\n\nExamples\n\njulia> G = complete_graph(4)\nUndirected graph with 4 nodes and the following edges:\n(2, 1)(3, 1)(3, 2)(4, 1)(4, 2)(4, 3)\n\njulia> M = cycle_matroid(G);\n\njulia> qAut = quantum_automorphism_group(M,:bases);\n\njulia> length(gens(qAut))\n23448\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":"free_module(R::Ring, rank::Int)\nvector_space(F::Field, dim::Int)","category":"page"},{"location":"AbstractAlgebra/free_module/#free_module-Tuple{Ring, Int64}","page":"Free Modules and Vector Spaces","title":"free_module","text":"free_module(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/#vector_space-Tuple{Field, Int64}","page":"Free Modules and Vector Spaces","title":"vector_space","text":"vector_space(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 = free_module(ZZ, 3)\nFree module of rank 3 over integers\n\njulia> V = vector_space(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 = free_module(ZZ, 3)\nFree module of rank 3 over integers\n\njulia> V = vector_space(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":"CommutativeAlgebra/GroebnerBases/groebner_bases/","page":"Gröbner/Standard Bases Over Fields","title":"Gröbner/Standard Bases Over Fields","text":"CurrentModule = Oscar\nDocTestSetup = Oscar.doctestsetup()","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/groebner_bases/#gb_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":"default_ordering(::MPolyRing)","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/groebner_bases/#default_ordering-Tuple{MPolyRing}","page":"Gröbner/Standard Bases Over Fields","title":"default_ordering","text":"default_ordering(R::MPolyRing)\n\nReturn the monomial ordering that is used for computations with ideals in R if no other ordering is specified – either directly by the user or by requirements of a specific algorithm.\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":"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 R\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/","page":"Gröbner/Standard Bases Over Fields","title":"Gröbner/Standard Bases Over Fields","text":"Expert users may temporarily choose a different default ordering for a given ring.","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/groebner_bases/","page":"Gröbner/Standard Bases Over Fields","title":"Gröbner/Standard Bases Over Fields","text":"with_ordering","category":"page"},{"location":"CommutativeAlgebra/GroebnerBases/groebner_bases/#with_ordering","page":"Gröbner/Standard Bases Over Fields","title":"with_ordering","text":"with_ordering(f, R::MPolyRing, o::MonomialOrdering)\n\nUse the monomial ordering o for computations in R during the execution of f. This may be used with do block syntax, see the example.\n\nThis functionality is meant for advanced users. In general it should not be necessary to explicitly set a monomial ordering. Further, there is no guarantee that o is actually used. For example, if an algorithm requires an elimination ordering, o might be ignored.\n\nExample\n\njulia> R, (x, y, z) = QQ[:x, :y, :z];\n\njulia> f = x + y^2;\n\njulia> I = ideal(R, [y^2 - z, x - z^2]);\n\njulia> normal_form(f, I) # this uses degrevlex\nx + z\n\njulia> with_ordering(R, lex(R)) do\n # this uses lex\n normal_form(f, I)\n end\nz^2 + z\n\nNotice that in this small example we could have achieved the same by using the keyword argument ordering:\n\njulia> normal_form(f, I, ordering = lex(R))\nz^2 + z\n\n\n\n\n\n","category":"function"},{"location":"CommutativeAlgebra/GroebnerBases/groebner_bases/#monomials_terms_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 R\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.","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 ordering::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::Union{Vector{T}, IdealGens{T}};\n ordering::MonomialOrdering = default_ordering(g)), complete_reduction::Bool = false) 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::Union{Vector{T}, IdealGens{T}};\n ordering::MonomialOrdering = default_ordering(parent(G[1])), complete_reduction::Bool = false) where T <: MPolyRingElem\n\nReturn a Vector which contains, for each element g of G, a remainder as above.\n\nnote: Note\nThe returned remainders are fully reduced if complete_reduction is set to true and ordering is global.\n\nnote: Note\nThe reduction strategy behind the reduce function and the reduction strategy behind the functions reduce_with_quotients and reduce_with_quotients_and_unit differ. As a consequence, the computed remainders may differ.\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> reduce(g, [f1, f2], ordering = lex(R))\n-3*x^10 + x^6 + x^5\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> reduce(g, [f1, f2, f3], ordering = lex(R))\nx^5 + x^3*y + x^2*y^2*z^2 + z^6\n\njulia> reduce(g, [f1,f2, f3], ordering = lex(R), complete_reduction = true)\nx^5 - x^3 + y^6 + z^6\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 ordering::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::Union{Vector{T}, IdealGens{T}};\n ordering::MonomialOrdering = default_ordering(parent(g)), complete_reduction::Bool = false) 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::Union{Vector{T}, IdealGens{T}};\n ordering::MonomialOrdering = default_ordering(parent(G[1])), complete_reduction::Bool = false) where T <: MPolyRingElem\n\nReturn a Vector which contains, for each element g of G, quotients and a remainder as above.\n\nnote: Note\nThe returned remainders are fully reduced if complete_reduction is set to true and ordering is global.\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> Q, h = reduce_with_quotients(g, [f1,f2, f3], ordering = lex(R));\n\njulia> h\nx^5 - x^3 + y^6 + z^6\n\njulia> g == Q[1]*f1+Q[2]*f2+Q[3]*f3+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 ordering::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::Union{Vector{T}, IdealGens{T}};\n ordering::MonomialOrdering = default_ordering(parent(g)), complete_reduction::Bool = false) 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::Union{Vector{T}, IdealGens{T}};\n ordering::MonomialOrdering = default_ordering(parent(G[1])), complete_reduction::Bool = false) 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\nThe returned remainders are fully reduced if complete_reduction is set to true and ordering is global.\n\nnote: Note\nThe reduction strategy behind the reduce function and the reduction strategy behind the functions reduce_with_quotients and reduce_with_quotients_and_unit differ. As a consequence, the computed remainders may differ.\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 = lex(R));\n\njulia> u\n[1]\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 = negdegrevlex(R));\n\njulia> U\n[y + 1 0]\n[ 0 y + 1]\n\njulia> Q\n[ x^3 - x*y^2*z^2 + x*y + y^2*z^2 0 y*z^2 + z^2]\n[x*y*z^2 + y^3*z - 3*y^2*z^2 - y*z -x^2*y*z - x^2*z + x*y + x 0]\n\njulia> H\n2-element Vector{QQMPolyRingElem}:\n 0\n 0\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 ord::MonomialOrdering = default_ordering(base_ring(I)),\n complete_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:modular (implementation of multi-modular approach, if applicable),\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\n 1 -> y^2 - x*z\n 2 -> x*y - z\n 3 -> x^2 - y\nwith respect to the ordering\n degrevlex([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\n 1 -> y^3 - z^2\n 2 -> x*z - y^2\n 3 -> x*y - z\n 4 -> x^2 - y\nwith respect to the ordering\n lex([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\n 1 -> 3*x^4 - x*y\n 2 -> 2*x^3*y^2 - 3*y^3\n 3 -> x*y^3\n 4 -> y^4\nwith respect to the ordering\n wdegrevlex([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 ord::MonomialOrdering = default_ordering(base_ring(I)),\n complete_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:modular (implementation of multi-modular approach, if applicable),\n:f4 (implementation of Faugère's F4 algorithm in the msolve package),\n:fglm (implementation of the FGLM algorithm in Singular),\n:hc (implementation of Buchberger's algorithm in Singular trying to first compute the highest corner modulo some prime), and\n:hilbert (implementation of a Hilbert driven Gröbner basis computation in Singular).\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\n 1 -> x\n 2 -> y\nwith respect to the ordering\n negdegrevlex([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 ordering::MonomialOrdering = default_ordering(base_ring(I)),\n complete_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 3 elements w.r.t. degrevlex([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 ordering::MonomialOrdering = default_ordering(base_ring(I)),\n complete_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 1 element w.r.t. neglex([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 [FGLM93] 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, number_of_generators(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 [Fau99] for more information.\n\nnote: Note\nAt current state only prime fields of characteristic 0 < p < 2^{31} and the rationals 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\nnormalize::Bool=true: normalizes elements in computed Gröbner basis for I\ntruncate_lifting::Int=0: degree up to which the elements of the Gröbner basis are lifted to QQ, 0 for complete lifting\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])\n(Multivariate polynomial ring in 3 variables over GF(101), FqMPolyRingElem[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 generated by\n x + 2*y + 2*z + 100\n x^2 + 100*x + 2*y^2 + 2*z^2\n 2*x*y + 2*y*z + 100*y\n\njulia> groebner_basis_f4(I)\nGröbner basis with elements\n 1 -> x + 2*y + 2*z + 100\n 2 -> y*z + 82*z^2 + 10*y + 40*z\n 3 -> y^2 + 60*z^2 + 20*y + 81*z\n 4 -> z^3 + 28*z^2 + 64*y + 13*z\nwith respect to the ordering\n degrevlex([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 generated by\n x*y^2\n y^5\n\njulia> L = leading_ideal([x*y^2-3*x, x^3-14*y^5], ordering=lex(R))\nIdeal generated by\n x*y^2\n 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 generated by\n x*y^2 - 3*x\n x^3 - 14*y^5\n\njulia> L = leading_ideal(I, ordering=degrevlex(R))\nIdeal generated by\n x*y^2\n x^4\n y^5\n\njulia> L = leading_ideal(I, ordering=lex(R))\nIdeal generated by\n y^7\n x*y^2\n 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 generated by\n b + c - 1\n 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 generated by\n b + c - 1\n 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(\n a::Vector{T};\n parent::Union{FreeMod{T}, Nothing} = nothing\n ) where {T<:RingElem}\n\nReturn generators for the syzygies on the polynomials given as elements of a. The optional keyword argument can be used to specify the parent of the output.\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. We make the following assumptions:","category":"page"},{"location":"Experimental/FTheoryTools/hypersurface/","page":"Hypersurface models","title":"Hypersurface models","text":"The generic fiber is a hypersurface in a 2-dimensional toric fiber ambient space F.\nThe first two (homogeneous) coordinates in the coordinate ring of F transform in the","category":"page"},{"location":"Experimental/FTheoryTools/hypersurface/","page":"Hypersurface models","title":"Hypersurface models","text":"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 [KM-POPR15] for more details.","category":"page"},{"location":"Experimental/FTheoryTools/hypersurface/","page":"Hypersurface models","title":"Hypersurface models","text":"Our tools are most powerful if the base space B is a toric variety. Then, based on the above 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/","page":"Hypersurface models","title":"Hypersurface models","text":"Certainly, one often wishes to extend beyond this setting:","category":"page"},{"location":"Experimental/FTheoryTools/hypersurface/","page":"Hypersurface models","title":"Hypersurface models","text":"Oftentimes, a special hypersurface equation is chosen. In the toric setting above, this will","category":"page"},{"location":"Experimental/FTheoryTools/hypersurface/","page":"Hypersurface models","title":"Hypersurface models","text":"be a polynomial in the Cox ring of the toric ambient space. Since said ambient space, and therefore also its Cox ring, are computed in the cause of the above construction, we do not support one constructor, which immediately accepts a special hypersurface equation. Rather, in this case, the user must first use one of the general constructors described in the next section. Subsequently, the tune function, described in the methods section below, can be employed.","category":"page"},{"location":"Experimental/FTheoryTools/hypersurface/","page":"Hypersurface models","title":"Hypersurface models","text":"Bases other than toric spaces matter. Often, the F-theory literature will not even assume","category":"page"},{"location":"Experimental/FTheoryTools/hypersurface/","page":"Hypersurface models","title":"Hypersurface models","text":"one particular base space but rather an entire family of base spaces. We extend our machinery to these cases, but such more general settings are typically significantly more limited than the toric setting. This limitation originates from the nature of the matter – the more general the geometry, the less is known.","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. For this, please use our tune function, described in the methods section below.]","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. Here is how we can construct a hypersurface model in OSCAR:","category":"page"},{"location":"Experimental/FTheoryTools/hypersurface/","page":"Hypersurface models","title":"Hypersurface models","text":"hypersurface_model(base::NormalToricVariety, fiber_ambient_space::NormalToricVariety, fiber_twist_divisor_classes::Vector{ToricDivisorClass}, p::MPolyRingElem; completeness_check::Bool = true)","category":"page"},{"location":"Experimental/FTheoryTools/hypersurface/#hypersurface_model-Tuple{NormalToricVariety, NormalToricVariety, Vector{ToricDivisorClass}, MPolyRingElem}","page":"Hypersurface models","title":"hypersurface_model","text":"function hypersurface_model(base::NormalToricVariety, fiber_ambient_space::NormalToricVariety, fiber_twist_divisor_classes::Vector{ToricDivisorClass}, p::MPolyRingElem; 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> b = projective_space(NormalToricVariety, 2)\nNormal toric variety\n\njulia> fiber_ambient_space = weighted_projective_space(NormalToricVariety, [2,3,1])\nNormal toric variety\n\njulia> set_coordinate_names(fiber_ambient_space, [\"x\", \"y\", \"z\"])\n\njulia> D1 = 2 * anticanonical_divisor_class(b)\nDivisor class on a normal toric variety\n\njulia> D2 = 3 * anticanonical_divisor_class(b)\nDivisor class on a normal toric variety\n\njulia> D3 = trivial_divisor_class(b)\nDivisor class on a normal toric variety\n\njulia> new_gens = string.(vcat(gens(cox_ring(b)), gens(cox_ring(fiber_ambient_space))))\n6-element Vector{String}:\n \"x1\"\n \"x2\"\n \"x3\"\n \"x\"\n \"y\"\n \"z\"\n\njulia> ambient_ring, (x1, x2, x3, x, y, z) = polynomial_ring(QQ, new_gens, cached=false)\n(Multivariate polynomial ring in 6 variables over QQ, QQMPolyRingElem[x1, x2, x3, x, y, z])\n\njulia> p = x^3 - y^2 + x1^12 * x * z^4 + x2^18 * z^6 + 13 * x3^3*x*y*z\nx1^12*x*z^4 + x2^18*z^6 + 13*x3^3*x*y*z + x^3 - y^2\n\njulia> h = hypersurface_model(b, fiber_ambient_space, [D1, D2, D3], p; completeness_check = false)\nHypersurface model over a concrete base\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/hypersurface/","page":"Hypersurface models","title":"Hypersurface models","text":"For convenience, it also possible to provide the hypersurface polynomial p as a string.","category":"page"},{"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, fiber_twist_divisor_classes::Vector{Vector{Int64}}, p::MPolyRingElem)","category":"page"},{"location":"Experimental/FTheoryTools/hypersurface/#hypersurface_model-Tuple{Vector{String}, Matrix{Int64}, Int64, NormalToricVariety, Vector{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, fiber_twist_divisor_classes::Vector{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 a family of spaces to represent the base space. This method requires the following information:\n\nThe names of the homogeneous coordinates of the coordinate ring of the generic member\n\nof the family of bsae spaces.\n\nThe grading of the coordinate ring of the generic member of the family of base spaces.\nThe weights telling us how the fiber ambient space coordinates transform under the base.\nThe dimension of the generic member of the family of base spaces.\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 coordinate ring of the generic member of the family of base space, unless the user already provides this grading. Our convention is that the first row of the grading matrix 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> D3 = [0,0]\n2-element Vector{Int64}:\n 0\n 0\n \njulia> d = 3\n3\n\njulia> fiber_ambient_space = weighted_projective_space(NormalToricVariety, [2,3,1])\nNormal toric variety\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, D3], 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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/hypersurface/","page":"Hypersurface models","title":"Hypersurface models","text":"For convenience, the fibertwistdivisor_classes can also be provided as ZZMatrix.","category":"page"},{"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":"All hypersurface models come with a hypersurface equation:","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> B2 = projective_space(NormalToricVariety, 2)\nNormal toric variety\n\njulia> b = torusinvariant_prime_divisors(B2)[1]\nTorus-invariant, prime divisor on a normal toric variety\n\njulia> h = literature_model(arxiv_id = \"1208.2695\", equation = \"B.5\", base_space = B2, defining_classes = Dict(\"b\" => b))\nConstruction over concrete base may lead to singularity enhancement. Consider computing singular_loci. However, this may take time!\n\nHypersurface model over a concrete base\n\njulia> hypersurface_equation(h);\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/hypersurface/","page":"Hypersurface models","title":"Hypersurface models","text":"Note that this equation is a polynomial in the coordinate ring of a suitable ambient space. This ambient space is computed by our constructors. Consequently, the coordinate ring, in which the hypersurface equation is an element, is only available after the model has been constructed.","category":"page"},{"location":"Experimental/FTheoryTools/hypersurface/","page":"Hypersurface models","title":"Hypersurface models","text":"Some hypersurface models parametrize the hypersurface equation with sections of line bundles of the base space. One can obtain those sections and their explicit polynomial expressions over the base with explicit_model_sections. The parametrization of the hypersurface equation by these sections is found as follows:","category":"page"},{"location":"Experimental/FTheoryTools/hypersurface/","page":"Hypersurface models","title":"Hypersurface models","text":"hypersurface_equation_parametrization(h::HypersurfaceModel)","category":"page"},{"location":"Experimental/FTheoryTools/hypersurface/#hypersurface_equation_parametrization-Tuple{HypersurfaceModel}","page":"Hypersurface models","title":"hypersurface_equation_parametrization","text":"hypersurface_equation_parametrization(h::HypersurfaceModel)\n\nReturn the parametrization of the hypersurface equation by the model sections.\n\njulia> h = literature_model(arxiv_id = \"1208.2695\", equation = \"B.5\")\nAssuming that the first row of the given grading is the grading under Kbar\n\nHypersurface model over a not fully specified base\n\njulia> explicit_model_sections(h)\nDict{String, MPolyRingElem} with 5 entries:\n \"c2\" => c2\n \"c1\" => c1\n \"c3\" => c3\n \"b\" => b\n \"c0\" => c0\n\njulia> hypersurface_equation_parametrization(h)\nb*w*v^2 - c0*u^4 - c1*u^3*v - c2*u^2*v^2 - c3*u*v^3 + w^2\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/hypersurface/","page":"Hypersurface models","title":"Hypersurface models","text":"To specify a custom value for the hypersurface equation, first use one of the above constructors. Once completed, employ the tune function described in the methods section to set the hypersurface equation to your desired value.","category":"page"},{"location":"Experimental/FTheoryTools/hypersurface/","page":"Hypersurface models","title":"Hypersurface models","text":"The base space can be obtained with base_space, the ambient space with ambient_space and the fiber ambient space with fiber_ambient_space. Recall that is_base_space_fully_specified will tell if the model has been constructed over a concrete space (in which case the function returns true) or a family of spaces (returning false).","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> B2 = projective_space(NormalToricVariety, 2)\nNormal toric variety\n\njulia> b = torusinvariant_prime_divisors(B2)[1]\nTorus-invariant, prime divisor on a normal toric variety\n\njulia> h = literature_model(arxiv_id = \"1208.2695\", equation = \"B.5\", base_space = B2, defining_classes = Dict(\"b\" => b))\nConstruction over concrete base may lead to singularity enhancement. Consider computing singular_loci. However, this may take time!\n\nHypersurface model over a concrete base\n\njulia> calabi_yau_hypersurface(h)\nClosed subvariety of a normal toric variety\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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 former is known.\n\njulia> t = literature_model(14)\nAssuming that the first row of the given grading is the grading under Kbar\n\nHypersurface model over a not fully specified base\n\njulia> weierstrass_model(t)\nAssuming that the first row of the given grading is the grading under Kbar\n\nWeierstrass model over a not fully specified base -- F-theory weierstrass model dual to hypersurface model with fiber ambient space F_1 based on arXiv paper 1408.4808 Eq. (3.4)\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/hypersurface/#Methods","page":"Hypersurface models","title":"Methods","text":"","category":"section"},{"location":"Experimental/FTheoryTools/hypersurface/#Tuning","page":"Hypersurface models","title":"Tuning","text":"","category":"section"},{"location":"Experimental/FTheoryTools/hypersurface/","page":"Hypersurface models","title":"Hypersurface models","text":"Tuning is possible with the tune function, cf. Functionality for all F-theory models.","category":"page"},{"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 numerous recurring and, at least in part, tedious computations in F-Theory model building, as detailed extensively in [Wei18]. The primary focus of our software is on (complex) elliptic fibrations with singularities. Those singularities hold significant importance. In essence, the absence of these singularities implies that the geometry encodes trivial or uninteresting physics. Therefore, the smooth case is typically not explored.","category":"page"},{"location":"Experimental/FTheoryTools/introduction/","page":"Welcome to FTheoryTools","title":"Welcome to FTheoryTools","text":"A substantial amount of information about the physics is encoded in the geometry of this singular fibration. To some extent it is clear what geometric quantities are to be considered, to some extent this is an open question. Regardless, computing quantities of interest, such as intersection theory and Chern classes, on singular spaces is challenging. However, it is possible to link the physics encoded by the singular geometry to the physics encoded by related smooth geometries. Consequently, almost all F-Theory studies begin by computing a smooting-out, i.e. a resolution, of the singular geometry in question.","category":"page"},{"location":"Experimental/FTheoryTools/introduction/","page":"Welcome to FTheoryTools","title":"Welcome to FTheoryTools","text":"In order to easily link the physics on the singular geometry to the physics of one of its resolution, the resolution in question must be crepant, i.e. must preserve the Calabi-Yau condition. However, this restriction to crepant resolutions introduces additional challenges:","category":"page"},{"location":"Experimental/FTheoryTools/introduction/","page":"Welcome to FTheoryTools","title":"Welcome to FTheoryTools","text":"A crepant resolution cannot resolve all singularities, meaning certain singularities may persist. This is an area of interest in recent F-Theory investigations.\nThe existence of a crepant resolution is not guaranteed.\nExploring whether different resolutions provide insights into different aspects of the singular geometry poses further questions. However, just as it is unclear whether a single crepant resolution is known, there is currently no way to confirm that all crepant resolutions have been identified.","category":"page"},{"location":"Experimental/FTheoryTools/introduction/","page":"Welcome to FTheoryTools","title":"Welcome to FTheoryTools","text":"FTheoryTools may not (yet) answer these profound and fundamental questions. Instead, the goal of this suite of computer tools is to streamline and simplify the crepant singularity resolution process as much as possible, as well as the subsequent extraction of geometric features of the resolved space.","category":"page"},{"location":"Experimental/FTheoryTools/introduction/","page":"Welcome to FTheoryTools","title":"Welcome to FTheoryTools","text":"With FTheoryTools, you can create elliptic fibrations using one of the following models:","category":"page"},{"location":"Experimental/FTheoryTools/introduction/","page":"Welcome to FTheoryTools","title":"Welcome to FTheoryTools","text":"Weierstrass model,\nGlobal Tate model,\nHypersurface model.","category":"page"},{"location":"Experimental/FTheoryTools/introduction/","page":"Welcome to FTheoryTools","title":"Welcome to FTheoryTools","text":"In each case, the base space can be a family of spaces (as used in the literature when an explicit base is not specified) or a toric space. We anticipate an extension to schemes as bases. The dimension of those bases is not limited to 1, 2, or 3, but of course includes those cases important to the physics.","category":"page"},{"location":"Experimental/FTheoryTools/introduction/","page":"Welcome to FTheoryTools","title":"Welcome to FTheoryTools","text":"We also offer a database of models frequently studied in the literature. For those models we use the term 'literature_models.' In essence, you should be able to create a model described in a paper at the click of a button. We anticipate that this feature will greatly simplify future research in F-Theory.","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":"We anticipate the following workflow:","category":"page"},{"location":"Experimental/FTheoryTools/introduction/#User-Input:","page":"Welcome to FTheoryTools","title":"User Input:","text":"","category":"section"},{"location":"Experimental/FTheoryTools/introduction/","page":"Welcome to FTheoryTools","title":"Welcome to FTheoryTools","text":"Create your desired F-Theory model by using one of the methods described above.\nChoose a resolved phase/crepant resolution.\nSelect generating sections for operatornameU(1) symmetries.","category":"page"},{"location":"Experimental/FTheoryTools/introduction/#Output:","page":"Welcome to FTheoryTools","title":"Output:","text":"","category":"section"},{"location":"Experimental/FTheoryTools/introduction/","page":"Welcome to FTheoryTools","title":"Welcome to FTheoryTools","text":"(Crepantly) resolved geometry.\nSingular loci in suitable codimension (e.g., 1, 2, and 3 if the base space has dimension 3).\nFiber diagrams of the resolved fiber 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/","page":"Welcome to FTheoryTools","title":"Welcome to FTheoryTools","text":"Currently, our primary focus is on the Elephant in the room, that is the crepant resolution. While already functional for numerous setups, especially literature models, it is far from complete. At this point, the largest functionality exists for toric cases, with ongoing work to extend those toric resolution techniques to families of spaces and schemes.","category":"page"},{"location":"Experimental/FTheoryTools/introduction/","page":"Welcome to FTheoryTools","title":"Welcome to FTheoryTools","text":"We are also actively expanding our database of supported literature models. At this point, amongst others, our database includes models from the following papers:","category":"page"},{"location":"Experimental/FTheoryTools/introduction/","page":"Welcome to FTheoryTools","title":"Welcome to FTheoryTools","text":"The Tate Form on Steroids: Resolution and Higher Codimension Fibers [LS13],\nF-Theory on all Toric Hypersurface Fibrations and its Higgs Branches [KM-POPR15],\nQuadrillion F-Theory Compactifications with the Exact Chiral Spectrum of the Standard Model [CHLLT19].","category":"page"},{"location":"Experimental/FTheoryTools/introduction/","page":"Welcome to FTheoryTools","title":"Welcome to FTheoryTools","text":"Consequently, we are already covering infinite families of models (e.g., with SU(k) gauge group, where k geq 1). Still, the total number of papers in our database is at this point limited to about 6. This is to be extended a lot.","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,\nMikelis Emils Mikelsons,\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. 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č and Mohab Safey El Din. Martin Bies and Mikelis Mikelsons appreciate support by the TU-Nachwuchsring. The work of Andrew Turner is supported by DOE (HEP) Award DE-SC001352.","category":"page"},{"location":"Hecke/manual/abelian/structural/","page":"Structural Computations","title":"Structural Computations","text":"CurrentModule = Hecke\nDocTestSetup = quote\n using Hecke\nend","category":"page"},{"location":"Hecke/manual/abelian/structural/#Structural-Computations","page":"Structural Computations","title":"Structural Computations","text":"","category":"section"},{"location":"Hecke/manual/abelian/structural/","page":"Structural Computations","title":"Structural Computations","text":"Abelian groups support a wide range of structural operations such as","category":"page"},{"location":"Hecke/manual/abelian/structural/","page":"Structural Computations","title":"Structural Computations","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/manual/abelian/structural/","page":"Structural Computations","title":"Structural Computations","text":"snf(A::FinGenAbGroup)\nHecke.find_isomorphism(G, op, A::Hecke.GrpAb)","category":"page"},{"location":"Hecke/manual/abelian/structural/#snf-Tuple{FinGenAbGroup}","page":"Structural Computations","title":"snf","text":"snf(A::FinGenAbGroup) -> FinGenAbGroup, FinGenAbGroupHom\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/manual/abelian/structural/#find_isomorphism-Tuple{Any, Any, Hecke.GrpAb}","page":"Structural Computations","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/manual/abelian/structural/#Subgroups-and-Quotients","page":"Structural Computations","title":"Subgroups and Quotients","text":"","category":"section"},{"location":"Hecke/manual/abelian/structural/","page":"Structural Computations","title":"Structural Computations","text":"torsion_subgroup(G::FinGenAbGroup)\nsub(G::FinGenAbGroup, s::Vector{FinGenAbGroupElem})\nsub(s::Vector{FinGenAbGroupElem})\nsub(G::FinGenAbGroup, M::ZZMatrix)\nsub(G::FinGenAbGroup, n::ZZRingElem)\nsub(G::FinGenAbGroup, n::Integer)\nsylow_subgroup(G::FinGenAbGroup, p::Union{ZZRingElem, Integer})\nHecke.has_quotient(G::FinGenAbGroup, invariant::Vector{Int})\nHecke.has_complement(f::FinGenAbGroupHom)\nis_pure(U::FinGenAbGroup, G::FinGenAbGroup)\nis_neat(U::FinGenAbGroup, G::FinGenAbGroup)\nsaturate(U::FinGenAbGroup, G::FinGenAbGroup)","category":"page"},{"location":"Hecke/manual/abelian/structural/#torsion_subgroup-Tuple{FinGenAbGroup}","page":"Structural Computations","title":"torsion_subgroup","text":"torsion_subgroup(G::FinGenAbGroup) -> FinGenAbGroup, Map\n\nReturn the torsion subgroup of G.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/abelian/structural/#sub-Tuple{FinGenAbGroup, Vector{FinGenAbGroupElem}}","page":"Structural Computations","title":"sub","text":"sub(G::FinGenAbGroup, s::Vector{FinGenAbGroupElem}) -> FinGenAbGroup, FinGenAbGroupHom\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/manual/abelian/structural/#sub-Tuple{Vector{FinGenAbGroupElem}}","page":"Structural Computations","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\nsub(s::Vector{FinGenAbGroupElem}) -> FinGenAbGroup, FinGenAbGroupHom\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\nsub(F::FreeMod{T}, V::Vector{<:FreeModElem{T}}; cache_morphism::Bool=false) where {T}\n\nGiven a vector V of (homogeneous) elements of F, return a pair (I, inc) consisting of the (graded) submodule I of F generated by these elements and its inclusion map inc : I ↪ F.\n\nWhen cache_morphism is set to true, then inc will be cached and available for transport and friends.\n\nIf only the submodule itself is desired, use sub_object instead.\n\n\n\n\n\nsub(F::FreeMod{T}, A::MatElem{T}; cache_morphism::Bool=false) where {T}\n\nGiven a (homogeneous) matrix A interpret the rows of A as elements of the free module F and return a pair (I, inc) consisting of the (graded) submodule I of F generated by these row vectors, together with its inclusion map inc : I ↪ F.\n\nWhen cache_morphism is set to true, then inc will be cached and available for transport and friends.\n\nIf only the submodule itself is desired, use sub_object instead.\n\n\n\n\n\nsub(F::FreeMod{T}, O::Vector{<:SubquoModuleElem{T}}; cache_morphism::Bool=false) where T\n\nSuppose the ambient_free_module of the parent M of the elements v_i in O is F and M is a submodule (i.e. no relations are present). Then this returns a pair (I, inc) consisting of the submodule I generated by the elements in O in F, together with its inclusion morphism inc : I ↪ F.\n\nWhen cache_morphism is set to true, then inc will be cached and available for transport and friends.\n\nIf only the submodule itself is desired, use sub_object instead.\n\n\n\n\n\nsub(F::FreeMod{T}, M::SubquoModule{T}; cache_morphism::Bool=false) where T\n\nReturn M as a submodule of F, together with its inclusion morphism inc : M ↪ F.\n\nWhen cache_morphism is set to true, then inc will be cached and available for transport and friends.\n\nThe ambient_free_module of M needs to be F and M has to have no relations.\n\nIf only the submodule itself is desired, use sub_object instead.\n\n\n\n\n\nsub(M::SubquoModule{T}, V::Vector{<:SubquoModuleElem{T}}; cache_morphism::Bool=false) where T\n\nGiven a vector V of (homogeneous) elements of M, return the (graded) submodule I of M generated by these elements together with its inclusion map `inc : I ↪ M.\n\nWhen cache_morphism is set to true, then inc will be cached and available for transport and friends.\n\nIf only the submodule itself is desired, use sub_object instead.\n\n\n\n\n\nsub(M::ModuleFP{T}, V::Vector{<:ModuleFPElem{T}}; cache_morphism::Bool=false) where T\n\nGiven a vector V of (homogeneous) elements of M, return the (graded) submodule I of M generated by these elements together with its inclusion map `inc : I ↪ M.\n\nWhen cache_morphism is set to true, then inc will be cached and available for transport and friends.\n\nIf only the submodule itself is desired, use sub_object instead.\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 R\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/abelian/structural/#sub-Tuple{FinGenAbGroup, ZZMatrix}","page":"Structural Computations","title":"sub","text":"sub(G::FinGenAbGroup, M::ZZMatrix) -> FinGenAbGroup, FinGenAbGroupHom\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/manual/abelian/structural/#sub-Tuple{FinGenAbGroup, ZZRingElem}","page":"Structural Computations","title":"sub","text":"sub(G::FinGenAbGroup, n::ZZRingElem) -> FinGenAbGroup, FinGenAbGroupHom\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/manual/abelian/structural/#sub-Tuple{FinGenAbGroup, Integer}","page":"Structural Computations","title":"sub","text":"sub(G::FinGenAbGroup, n::Integer) -> FinGenAbGroup, 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/manual/abelian/structural/#sylow_subgroup-Tuple{FinGenAbGroup, Union{Integer, ZZRingElem}}","page":"Structural Computations","title":"sylow_subgroup","text":"sylow_subgroup(G::FinGenAbGroup, p::IntegerUnion) -> FinGenAbGroup, FinGenAbGroupHom\n\nReturn the Sylow p-subgroup of the finitely generated abelian group G, for a prime p. This is the subgroup of p-power order in G whose index in G is coprime to p.\n\nExamples\n\njulia> A = abelian_group(ZZRingElem[2, 6, 30])\nZ/2 x Z/6 x Z/30\n\njulia> H, j = sylow_subgroup(A, 2);\n\njulia> H\n(Z/2)^3\n\njulia> divexact(order(A), order(H))\n45\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/abelian/structural/#has_quotient-Tuple{FinGenAbGroup, Vector{Int64}}","page":"Structural Computations","title":"has_quotient","text":"has_quotient(G::FinGenAbGroup, 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/manual/abelian/structural/#has_complement-Tuple{FinGenAbGroupHom}","page":"Structural Computations","title":"has_complement","text":"has_complement(f::FinGenAbGroupHom) -> Bool, FinGenAbGroupHom\nhas_complement(U::FinGenAbGroup, G::FinGenAbGroup) -> Bool, FinGenAbGroupHom\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/manual/abelian/structural/#is_pure-Tuple{FinGenAbGroup, FinGenAbGroup}","page":"Structural Computations","title":"is_pure","text":"is_pure(U::FinGenAbGroup, G::FinGenAbGroup) -> 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/manual/abelian/structural/#is_neat-Tuple{FinGenAbGroup, FinGenAbGroup}","page":"Structural Computations","title":"is_neat","text":"is_neat(U::FinGenAbGroup, G::FinGenAbGroup) -> 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/manual/abelian/structural/#saturate-Tuple{FinGenAbGroup, FinGenAbGroup}","page":"Structural Computations","title":"saturate","text":"saturate(U::FinGenAbGroup, G::FinGenAbGroup) -> FinGenAbGroup\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/manual/abelian/structural/","page":"Structural Computations","title":"Structural Computations","text":"A sophisticated algorithm for the enumeration of all (or selected) subgroups of a finite abelian group is available.","category":"page"},{"location":"Hecke/manual/abelian/structural/","page":"Structural Computations","title":"Structural Computations","text":"psubgroups(g::FinGenAbGroup, p::Integer)","category":"page"},{"location":"Hecke/manual/abelian/structural/#psubgroups-Tuple{FinGenAbGroup, Integer}","page":"Structural Computations","title":"psubgroups","text":"psubgroups(g::FinGenAbGroup, 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/manual/abelian/structural/","page":"Structural Computations","title":"Structural Computations","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/manual/abelian/structural/","page":"Structural Computations","title":"Structural Computations","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/manual/abelian/structural/","page":"Structural Computations","title":"Structural Computations","text":"subgroups(g::FinGenAbGroup)","category":"page"},{"location":"Hecke/manual/abelian/structural/#subgroups-Tuple{FinGenAbGroup}","page":"Structural Computations","title":"subgroups","text":"subgroups(g::FinGenAbGroup;\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/manual/abelian/structural/","page":"Structural Computations","title":"Structural Computations","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/manual/abelian/structural/","page":"Structural Computations","title":"Structural Computations","text":"quo(G::FinGenAbGroup, s::Vector{FinGenAbGroupElem})\nquo(G::FinGenAbGroup, M::ZZMatrix)\nquo(G::FinGenAbGroup, n::Integer)\nquo(G::FinGenAbGroup, n::ZZRingElem)\nquo(G::FinGenAbGroup, U::FinGenAbGroup)","category":"page"},{"location":"Hecke/manual/abelian/structural/#quo-Tuple{FinGenAbGroup, Vector{FinGenAbGroupElem}}","page":"Structural Computations","title":"quo","text":"quo(G::FinGenAbGroup, s::Vector{FinGenAbGroupElem}) -> FinGenAbGroup, 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/manual/abelian/structural/#quo-Tuple{FinGenAbGroup, ZZMatrix}","page":"Structural Computations","title":"quo","text":"quo(G::FinGenAbGroup, M::ZZMatrix) -> FinGenAbGroup, FinGenAbGroupHom\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/manual/abelian/structural/#quo-Tuple{FinGenAbGroup, Integer}","page":"Structural Computations","title":"quo","text":"quo(G::FinGenAbGroup, n::Integer}) -> FinGenAbGroup, Map\nquo(G::FinGenAbGroup, n::ZZRingElem}) -> FinGenAbGroup, 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/manual/abelian/structural/#quo-Tuple{FinGenAbGroup, ZZRingElem}","page":"Structural Computations","title":"quo","text":"quo(G::FinGenAbGroup, n::Integer}) -> FinGenAbGroup, Map\nquo(G::FinGenAbGroup, n::ZZRingElem}) -> FinGenAbGroup, 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/manual/abelian/structural/#quo-Tuple{FinGenAbGroup, FinGenAbGroup}","page":"Structural Computations","title":"quo","text":"quo(G::FinGenAbGroup, U::FinGenAbGroup) -> FinGenAbGroup, 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/manual/abelian/structural/","page":"Structural Computations","title":"Structural Computations","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/manual/abelian/structural/","page":"Structural Computations","title":"Structural Computations","text":"intersect(mG::FinGenAbGroupHom, mH::FinGenAbGroupHom)","category":"page"},{"location":"Hecke/manual/abelian/structural/#intersect-Tuple{FinGenAbGroupHom, FinGenAbGroupHom}","page":"Structural Computations","title":"intersect","text":"intersect(mG::FinGenAbGroupHom, mH::FinGenAbGroupHom) -> FinGenAbGroup, 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/manual/abelian/structural/#Direct-Products","page":"Structural Computations","title":"Direct Products","text":"","category":"section"},{"location":"Hecke/manual/abelian/structural/","page":"Structural Computations","title":"Structural Computations","text":"direct_product(G::FinGenAbGroup...)\ncanonical_injection(G::FinGenAbGroup, i::Int)\ncanonical_projection(G::FinGenAbGroup, i::Int)\nflat(G::FinGenAbGroup)","category":"page"},{"location":"Hecke/manual/abelian/structural/#direct_product-Tuple{Vararg{FinGenAbGroup}}","page":"Structural Computations","title":"direct_product","text":"direct_product(G::FinGenAbGroup...) -> FinGenAbGroup, Vector{FinGenAbGroupHom}\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/manual/abelian/structural/#canonical_injection-Tuple{FinGenAbGroup, Int64}","page":"Structural Computations","title":"canonical_injection","text":"canonical_injection(G::FinGenAbGroup, i::Int) -> FinGenAbGroupHom\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/manual/abelian/structural/#canonical_projection-Tuple{FinGenAbGroup, Int64}","page":"Structural Computations","title":"canonical_projection","text":"canonical_projection(G::FinGenAbGroup, i::Int) -> FinGenAbGroupHom\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/manual/abelian/structural/#flat-Tuple{FinGenAbGroup}","page":"Structural Computations","title":"flat","text":"flat(G::FinGenAbGroup) -> FinGenAbGroupHom\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/manual/abelian/structural/#Tensor-Producs","page":"Structural Computations","title":"Tensor Producs","text":"","category":"section"},{"location":"Hecke/manual/abelian/structural/","page":"Structural Computations","title":"Structural Computations","text":"tensor_product(G::FinGenAbGroup...)\nhom_tensor(G::FinGenAbGroup, H::FinGenAbGroup, A::Vector{ <: Map{FinGenAbGroup, FinGenAbGroup}})","category":"page"},{"location":"Hecke/manual/abelian/structural/#tensor_product-Tuple{Vararg{FinGenAbGroup}}","page":"Structural Computations","title":"tensor_product","text":"tensor_product(G::FinGenAbGroup...; task::Symbol = :map) -> FinGenAbGroup, 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/manual/abelian/structural/#hom_tensor-Tuple{FinGenAbGroup, FinGenAbGroup, Vector{<:Map{FinGenAbGroup, FinGenAbGroup}}}","page":"Structural Computations","title":"hom_tensor","text":"hom_tensor(G::FinGenAbGroup, H::FinGenAbGroup, A::Vector{ <: Map{FinGenAbGroup, FinGenAbGroup}}) -> 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/manual/abelian/structural/#Hom-Group","page":"Structural Computations","title":"Hom-Group","text":"","category":"section"},{"location":"Hecke/manual/abelian/structural/","page":"Structural Computations","title":"Structural Computations","text":"hom(::FinGenAbGroup, ::FinGenAbGroup)","category":"page"},{"location":"Hecke/manual/abelian/structural/#hom-Tuple{FinGenAbGroup, FinGenAbGroup}","page":"Structural Computations","title":"hom","text":"hom(G::FinGenAbGroup, H::FinGenAbGroup; task::Symbol = :map) -> FinGenAbGroup, 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":"TropicalGeometry/linear_space/#Tropical-linear-spaces","page":"Tropical linear spaces","title":"Tropical linear spaces","text":"","category":"section"},{"location":"TropicalGeometry/linear_space/#Introduction","page":"Tropical linear spaces","title":"Introduction","text":"","category":"section"},{"location":"TropicalGeometry/linear_space/","page":"Tropical linear spaces","title":"Tropical linear spaces","text":"A tropical linear space is a balanced polyhedral complex supported on a finite intersection of linear tropical hypersurfaces with all multiplicities one. It is dual to a matroid subdivision of a hypersimplex, and may arise as tropicalizations of linear ideals. For more on tropical linear spaces, see","category":"page"},{"location":"TropicalGeometry/linear_space/","page":"Tropical linear spaces","title":"Tropical linear spaces","text":"Chapter 4.4 in [MS15]\nChapter 10 in [Jos21]","category":"page"},{"location":"TropicalGeometry/linear_space/#Note:","page":"Tropical linear spaces","title":"Note:","text":"","category":"section"},{"location":"TropicalGeometry/linear_space/","page":"Tropical linear spaces","title":"Tropical linear spaces","text":"Objects of type TropicalLinearSpace need to be embedded, abstract tropical linear spaces are currently not supported.\nThe type TropicalLinearSpace can be thought of as subtype of TropicalVariety in the sense that it should have all properties and features of the latter.","category":"page"},{"location":"TropicalGeometry/linear_space/#Constructors","page":"Tropical linear spaces","title":"Constructors","text":"","category":"section"},{"location":"TropicalGeometry/linear_space/","page":"Tropical linear spaces","title":"Tropical linear spaces","text":"In addition to converting from TropicalVariety, objects of type TropicalLinearSpace can be constructed from:","category":"page"},{"location":"TropicalGeometry/linear_space/","page":"Tropical linear spaces","title":"Tropical linear spaces","text":"Pluecker vectors over a tropical semiring: uses a low-level implementation in polymake\nPluecker vectors over a field and a tropical semiring map: computes coordinatewise valuation and uses constructor (1.)\nmatrices over a tropical semiring: computes tropical minors and uses constructor (1.)\nmatrices over a field and a tropical semiring map.\nif matrix over QQ and tropical semiring map is trivial, uses an implementation of Rincon's algorithm [Rin13] in polymake\nfor general input, computes minors and uses constructor (2.)","category":"page"},{"location":"TropicalGeometry/linear_space/","page":"Tropical linear spaces","title":"Tropical linear spaces","text":"tropical_linear_space","category":"page"},{"location":"TropicalGeometry/linear_space/#tropical_linear_space","page":"Tropical linear spaces","title":"tropical_linear_space","text":"tropical_linear_space(Lambda::Vector{Vector{Int}}, p::Vector{<:TropicalSemiringElem}; weighted_polyhedral_complex_only::Bool=false)\n\nReturn a tropical linear space from a tropical Pluecker vector with indices Lambda and values p. If weighted_polyhedral_complex==true, will not cache any extra information.\n\nExamples\n\njulia> T = tropical_semiring();\n\njulia> plueckerIndices = [[1,2],[1,3],[1,4],[2,3],[2,4],[3,4]];\n\njulia> plueckerVector = T.([0,0,0,0,0,0]);\n\njulia> tropical_linear_space(plueckerIndices,plueckerVector)\nMin tropical linear space\n\n\n\n\n\n\ntropical_linear_space(k::Int, n::Int, p::Vector{<:TropicalSemiringElem}; weighted_polyhedral_complex_only::Bool=false)\n\nReturn a tropical linear space from a tropical Pluecker vector with indices AbstractAlgebra.combinations(1:n,k) and values p. If weighted_polyhedral_complex==true, will not cache any extra information.\n\nExamples\n\njulia> T = tropical_semiring();\n\njulia> plueckerVector = T.([0,0,0,0,0,0]);\n\njulia> tropical_linear_space(2,4,plueckerVector)\nMin tropical linear space\n\n\n\n\n\n\ntropical_linear_space(Lambda::Vector{Vector{Int}}, p::Vector, nu::TropicalSemiringMap; weighted_polyhedral_complex_only::Bool=false)\n\nReturn a tropical linear space from a tropical Pluecker vector with indices Lambda and values nu(p). If weighted_polyhedral_complex==true, will not cache any extra information.\n\nExamples\n\njulia> nu = tropical_semiring_map(QQ,2)\nMap into Min tropical semiring encoding the 2-adic valuation on Rational field\n\njulia> plueckerIndices = [[1,2],[1,3],[1,4],[2,3],[2,4],[3,4]];\n\njulia> plueckerVector = QQ.([1,3,5,5,3,1]);\n\njulia> tropical_linear_space(plueckerIndices,plueckerVector,nu)\nMin tropical linear space\n\n\n\n\n\n\ntropical_linear_space(k::Int, n::Int, p::Vector, nu::TropicalSemiringMap; weighted_polyhedral_complex_only::Bool=false)\n\nReturn a tropical linear space from a tropical Pluecker vector with indices AbstractAlgebra.combinations(1:n,k) and values nu(p). If weighted_polyhedral_complex==true, will not cache any extra information.\n\nExamples\n\njulia> nu = tropical_semiring_map(QQ);\n\njulia> plueckerVector = QQ.([1,3,5,5,3,1]);\n\njulia> tropical_linear_space(2,4,plueckerVector,nu)\nMin tropical linear space\n\n\n\n\n\n\ntropical_linear_space(A::MatElem{<:TropicalSemiringElem}; weighted_polyhedral_complex_only::Bool=false)\n\nReturn a tropical linear space whose Pluecker vector are the tropical minors of A. Assumes that ncols(A)>=nrows(A). If weighted_polyhedral_complex==true, will not cache any extra information.\n\nExamples\n\njulia> A = matrix(tropical_semiring(),[[1,2,4,8],[8,4,2,1]])\n[(1) (2) (4) (8)]\n[(8) (4) (2) (1)]\n\njulia> tropical_linear_space(A)\nMin tropical linear space\n\n\n\n\n\n\ntropical_linear_space(A::MatElem,nu::TropicalSemiringMap; weighted_polyhedral_complex_only::Bool=false)\n\nReturn a tropical linear space whose Pluecker vector is nu applied to the minors of A. If weighted_polyhedral_complex==true, will not cache any extra information.\n\nExamples\n\njulia> nu = tropical_semiring_map(QQ,2)\nMap into Min tropical semiring encoding the 2-adic valuation on Rational field\n\njulia> A = matrix(QQ,[[1,2,4,8],[8,4,2,1]])\n[1 2 4 8]\n[8 4 2 1]\n\njulia> tropical_linear_space(A, nu)\nMin tropical linear space\n\n\n\n\n\n\ntropical_linear_space(I::MPolyIdeal, nu::TropicalSemiringMap; weighted_polyhedral_complex_only::Bool=false)\n\nReturn the tropicalization of the vanishing set of I with respect to the tropical semiring map nu. Requires the generators of I to be linear and homogeneous. If weighted_polyhedral_complex==true, will not cache any extra information.\n\nExamples\n\njulia> R,(x1,x2,x3,x4) = polynomial_ring(QQ,4);\n\njulia> I = ideal(R,[-x1+x3,-x2+x4])\nIdeal generated by\n -x1 + x3\n -x2 + x4\n\njulia> nu = tropical_semiring_map(QQ)\nMap into Min tropical semiring encoding the trivial valuation on Rational field\n\njulia> tropical_linear_space(I, nu)\nMin tropical linear space\n\n\n\n\n\n\n","category":"function"},{"location":"TropicalGeometry/linear_space/#Properties","page":"Tropical linear spaces","title":"Properties","text":"","category":"section"},{"location":"TropicalGeometry/linear_space/","page":"Tropical linear spaces","title":"Tropical linear spaces","text":"In addition to the properties inherited from TropicalVariety, objects of type TropicalLinearSpace have the following exclusive properties:","category":"page"},{"location":"TropicalGeometry/linear_space/","page":"Tropical linear spaces","title":"Tropical linear spaces","text":"pluecker_indices(TropL::TropicalLinearSpace)\ntropical_pluecker_vector(TropL::TropicalLinearSpace)\nalgebraic_pluecker_vector(TropL::TropicalLinearSpace)\ntropical_semiring_map(TropL::TropicalLinearSpace)\ntropical_matrix(TropL::TropicalLinearSpace)\nalgebraic_matrix(TropL::TropicalLinearSpace)\nalgebraic_ideal(TropL::TropicalLinearSpace)","category":"page"},{"location":"TropicalGeometry/linear_space/#pluecker_indices-Tuple{TropicalLinearSpace}","page":"Tropical linear spaces","title":"pluecker_indices","text":"pluecker_indices(TropL::TropicalLinearSpace)\n\nReturn the Pluecker indices used to construct TropL.\n\n\n\n\n\n","category":"method"},{"location":"TropicalGeometry/linear_space/#tropical_pluecker_vector-Tuple{TropicalLinearSpace}","page":"Tropical linear spaces","title":"tropical_pluecker_vector","text":"tropical_pluecker_vector(TropL::TropicalLinearSpace)\n\nReturn the tropical Pluecker vector of TropL.\n\n\n\n\n\n","category":"method"},{"location":"TropicalGeometry/linear_space/#algebraic_pluecker_vector-Tuple{TropicalLinearSpace}","page":"Tropical linear spaces","title":"algebraic_pluecker_vector","text":"algebraic_pluecker_vector(TropL::TropicalLinearSpace)\n\nReturn the Pluecker vector over a valued field used to construct TropL.\n\n\n\n\n\n","category":"method"},{"location":"TropicalGeometry/linear_space/#tropical_semiring_map-Tuple{TropicalLinearSpace}","page":"Tropical linear spaces","title":"tropical_semiring_map","text":"tropical_semiring_map(TropL::TropicalLinearSpace)\n\nReturn the tropical semiring map used to construct TropL. Raises an error, if it is not cached.\n\n\n\n\n\n","category":"method"},{"location":"TropicalGeometry/linear_space/#tropical_matrix-Tuple{TropicalLinearSpace}","page":"Tropical linear spaces","title":"tropical_matrix","text":"tropical_matrix(TropL::TropicalLinearSpace)\n\nReturn the tropical matrix used to construct TropL. Raises an error, if it is not cached.\n\n\n\n\n\n","category":"method"},{"location":"TropicalGeometry/linear_space/#algebraic_matrix-Tuple{TropicalLinearSpace}","page":"Tropical linear spaces","title":"algebraic_matrix","text":"algebraic_matrix(TropL::TropicalLinearSpace)\n\nReturn the matrix over a valued field used to construct TropL.\n\n\n\n\n\n","category":"method"},{"location":"TropicalGeometry/linear_space/#algebraic_ideal-Tuple{TropicalLinearSpace}","page":"Tropical linear spaces","title":"algebraic_ideal","text":"algebraic_ideal(TropL::TropicalLinearSpace)\n\nReturn the polynomial ideal over a valued field used to construct TropL. Raises an error, if it is not cached.\n\n\n\n\n\n","category":"method"},{"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 CalciumFieldElem 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 CalciumFieldElem 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 (algebraic_closure(QQ)), 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> algebraic_closure(QQ)(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[...]\n\njulia> QQ(C(10) ^ C(10^9))\nERROR: unable to convert to a rational number\n[...]","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)\nComplex Field with 64 bits of precision and error bounds\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::CalciumFieldElem; 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::CalciumFieldElem; 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{CalciumFieldElem}:\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::CalciumFieldElem)\nisone(a::CalciumFieldElem)\nis_algebraic(a::CalciumFieldElem)\nis_rational(a::CalciumFieldElem)\nisinteger(a::CalciumFieldElem)\nisreal(a::CalciumFieldElem)\nis_imaginary(a::CalciumFieldElem)","category":"page"},{"location":"Nemo/exact/#iszero-Tuple{CalciumFieldElem}","page":"Exact real and complex numbers","title":"iszero","text":"iszero(a::CalciumFieldElem)\n\nReturn whether a is the number 0.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/exact/#isone-Tuple{CalciumFieldElem}","page":"Exact real and complex numbers","title":"isone","text":"isone(a::CalciumFieldElem)\n\nReturn whether a is the number 1.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/exact/#is_algebraic-Tuple{CalciumFieldElem}","page":"Exact real and complex numbers","title":"is_algebraic","text":"is_algebraic(a::CalciumFieldElem)\n\nReturn whether a is an algebraic number.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/exact/#is_rational-Tuple{CalciumFieldElem}","page":"Exact real and complex numbers","title":"is_rational","text":"is_rational(a::CalciumFieldElem)\n\nReturn whether a is a rational number.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/exact/#isinteger-Tuple{CalciumFieldElem}","page":"Exact real and complex numbers","title":"isinteger","text":"isinteger(a::CalciumFieldElem)\n\nReturn whether a is an integer.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/exact/#isreal-Tuple{CalciumFieldElem}","page":"Exact real and complex numbers","title":"isreal","text":"isreal(a::CalciumFieldElem)\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{CalciumFieldElem}","page":"Exact real and complex numbers","title":"is_imaginary","text":"is_imaginary(a::CalciumFieldElem)\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::CalciumFieldElem)\nundefined(C::CalciumField)\nunknown(C::CalciumField)\nis_number(a::CalciumFieldElem)\nis_undefined(a::CalciumFieldElem)\nisinf(a::CalciumFieldElem)\nis_uinf(a::CalciumFieldElem)\nis_signed_inf(a::CalciumFieldElem)\nis_unknown(a::CalciumFieldElem)","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{CalciumFieldElem}","page":"Exact real and complex numbers","title":"infinity","text":"infinity(a::CalciumFieldElem)\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{CalciumFieldElem}","page":"Exact real and complex numbers","title":"is_number","text":"is_number(a::CalciumFieldElem)\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{CalciumFieldElem}","page":"Exact real and complex numbers","title":"is_undefined","text":"is_undefined(a::CalciumFieldElem)\n\nReturn whether a is the special value Undefined.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/exact/#isinf-Tuple{CalciumFieldElem}","page":"Exact real and complex numbers","title":"isinf","text":"isinf(a::CalciumFieldElem)\n\nReturn whether a is any infinity (signed or unsigned).\n\n\n\n\n\n","category":"method"},{"location":"Nemo/exact/#is_uinf-Tuple{CalciumFieldElem}","page":"Exact real and complex numbers","title":"is_uinf","text":"is_uinf(a::CalciumFieldElem)\n\nReturn whether a is unsigned infinity.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/exact/#is_signed_inf-Tuple{CalciumFieldElem}","page":"Exact real and complex numbers","title":"is_signed_inf","text":"is_signed_inf(a::CalciumFieldElem)\n\nReturn whether a is any signed infinity.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/exact/#is_unknown-Tuple{CalciumFieldElem}","page":"Exact real and complex numbers","title":"is_unknown","text":"is_unknown(a::CalciumFieldElem)\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::CalciumFieldElem)\nimag(a::CalciumFieldElem)\nangle(a::CalciumFieldElem)\ncsgn(a::CalciumFieldElem)\nsign(a::CalciumFieldElem)\nabs(a::CalciumFieldElem)\nconj(a::CalciumFieldElem; form::Symbol=:default)\nfloor(a::CalciumFieldElem)\nceil(a::CalciumFieldElem)","category":"page"},{"location":"Nemo/exact/#real-Tuple{CalciumFieldElem}","page":"Exact real and complex numbers","title":"real","text":"real(a::CalciumFieldElem)\n\nReturn the real part of a.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/exact/#imag-Tuple{CalciumFieldElem}","page":"Exact real and complex numbers","title":"imag","text":"imag(a::CalciumFieldElem)\n\nReturn the imaginary part of a.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/exact/#angle-Tuple{CalciumFieldElem}","page":"Exact real and complex numbers","title":"angle","text":"angle(a::CalciumFieldElem)\n\nReturn the complex argument of a.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/exact/#csgn-Tuple{CalciumFieldElem}","page":"Exact real and complex numbers","title":"csgn","text":"csgn(a::CalciumFieldElem)\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{CalciumFieldElem}","page":"Exact real and complex numbers","title":"sign","text":"sign(a::CalciumFieldElem)\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{CalciumFieldElem}","page":"Exact real and complex numbers","title":"abs","text":"abs(a::CalciumFieldElem)\n\nReturn the absolute value of a.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/exact/#conj-Tuple{CalciumFieldElem}","page":"Exact real and complex numbers","title":"conj","text":"conj(a::CalciumFieldElem; 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{CalciumFieldElem}","page":"Exact real and complex numbers","title":"floor","text":"floor(a::CalciumFieldElem)\n\nReturn the floor function of a.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/exact/#ceil-Tuple{CalciumFieldElem}","page":"Exact real and complex numbers","title":"ceil","text":"ceil(a::CalciumFieldElem)\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\n[...]","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::CalciumFieldElem)\nexp(a::CalciumFieldElem)\nlog(a::CalciumFieldElem)\npow(a::CalciumFieldElem, b::Int; form::Symbol=:default)\nsin(a::CalciumFieldElem; form::Symbol=:default)\ncos(a::CalciumFieldElem; form::Symbol=:default)\ntan(a::CalciumFieldElem; form::Symbol=:default)\natan(a::CalciumFieldElem; form::Symbol=:default)\nasin(a::CalciumFieldElem; form::Symbol=:default)\nacos(a::CalciumFieldElem; form::Symbol=:default)\ngamma(a::CalciumFieldElem)\nerf(a::CalciumFieldElem)\nerfi(a::CalciumFieldElem)\nerfc(a::CalciumFieldElem)","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{CalciumFieldElem}","page":"Exact real and complex numbers","title":"sqrt","text":"Base.sqrt(a::CalciumFieldElem; check::Bool=true)\n\nReturn the principal square root of a.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/exact/#exp-Tuple{CalciumFieldElem}","page":"Exact real and complex numbers","title":"exp","text":"exp(a::CalciumFieldElem)\n\nReturn the exponential function of a.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/exact/#log-Tuple{CalciumFieldElem}","page":"Exact real and complex numbers","title":"log","text":"log(a::CalciumFieldElem)\n\nReturn the natural logarithm of a.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/exact/#pow-Tuple{CalciumFieldElem, Int64}","page":"Exact real and complex numbers","title":"pow","text":"pow(a::CalciumFieldElem, 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{CalciumFieldElem}","page":"Exact real and complex numbers","title":"sin","text":"sin(a::CalciumFieldElem; 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{CalciumFieldElem}","page":"Exact real and complex numbers","title":"cos","text":"cos(a::CalciumFieldElem; 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{CalciumFieldElem}","page":"Exact real and complex numbers","title":"tan","text":"tan(a::CalciumFieldElem; 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{CalciumFieldElem}","page":"Exact real and complex numbers","title":"atan","text":"atan(a::CalciumFieldElem; 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{CalciumFieldElem}","page":"Exact real and complex numbers","title":"asin","text":"asin(a::CalciumFieldElem; 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{CalciumFieldElem}","page":"Exact real and complex numbers","title":"acos","text":"acos(a::CalciumFieldElem; 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{CalciumFieldElem}","page":"Exact real and complex numbers","title":"gamma","text":"gamma(a::CalciumFieldElem)\n\nReturn the gamma function of a.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/exact/#erf-Tuple{CalciumFieldElem}","page":"Exact real and complex numbers","title":"erf","text":"erf(a::CalciumFieldElem)\n\nReturn the error function of a.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/exact/#erfi-Tuple{CalciumFieldElem}","page":"Exact real and complex numbers","title":"erfi","text":"erfi(a::CalciumFieldElem)\n\nReturn the imaginary error function of a.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/exact/#erfc-Tuple{CalciumFieldElem}","page":"Exact real and complex numbers","title":"erfc","text":"erfc(a::CalciumFieldElem)\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::CalciumFieldElem; deep::Bool=true)","category":"page"},{"location":"Nemo/exact/#complex_normal_form-Tuple{CalciumFieldElem}","page":"Exact real and complex numbers","title":"complex_normal_form","text":"complex_normal_form(a::CalciumFieldElem, 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 [Chr91] and [Ste91].","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/CyclicQuotientSingularities/","page":"Cyclic Quotient Singularities","title":"Cyclic Quotient Singularities","text":"warning: Warning\nNote that [Chr91] and [Ste91] 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 [BJRR10*1] 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 [BJRR10], [BJRR10*1] (see also [RR10], [Jow11] and [BJRR12]).\n\nExamples\n\njulia> dP3 = del_pezzo_surface(NormalToricVariety, 3)\nNormal toric variety\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 [BJRR10], [BJRR10*1] (see also [RR10], [Jow11] and [BJRR12]).\n\nExamples\n\njulia> dP3 = del_pezzo_surface(NormalToricVariety, 3)\nNormal toric variety\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 [BJRR10*1], 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 [Bie18]. 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::NormalToricVarietyType)","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/cohomCalg/#vanishing_sets-Tuple{Union{AffineNormalToricVariety, CyclicQuotientSingularity, NormalToricVariety}}","page":"Line bundle cohomology with cohomCalg","title":"vanishing_sets","text":"vanishing_sets(variety::NormalToricVarietyType)\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 toric variety\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 indices [0]\n Toric vanishing set for cohomology indices [1]\n Toric vanishing set for cohomology indices [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_indices(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 toric variety\n\njulia> vs = vanishing_sets(dP1)\n3-element Vector{ToricVanishingSet}:\n Toric vanishing set for cohomology indices [0]\n Toric vanishing set for cohomology indices [1]\n Toric vanishing set for cohomology indices [2]\n\njulia> toric_variety(vs[3])\nNormal, 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 toric variety\n\njulia> vs = vanishing_sets(dP1)\n3-element Vector{ToricVanishingSet}:\n Toric vanishing set for cohomology indices [0]\n Toric vanishing set for cohomology indices [1]\n Toric vanishing set for cohomology indices [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_indices-Tuple{ToricVanishingSet}","page":"Line bundle cohomology with cohomCalg","title":"cohomology_indices","text":"cohomology_indices(tvs::ToricVanishingSet)\n\nReturn the cohomology indices of the toric vanishing set tvs.\n\nExamples\n\njulia> dP1 = del_pezzo_surface(NormalToricVariety, 1)\nNormal toric variety\n\njulia> vs = vanishing_sets(dP1)\n3-element Vector{ToricVanishingSet}:\n Toric vanishing set for cohomology indices [0]\n Toric vanishing set for cohomology indices [1]\n Toric vanishing set for cohomology indices [2]\n\njulia> cohomology_indices(vs[3])\n1-element Vector{Int64}:\n 2\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":"Certainly, this also allows to compute the immaculate line bundles:","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/cohomCalg/","page":"Line bundle cohomology with cohomCalg","title":"Line bundle cohomology with cohomCalg","text":"immaculate_line_bundles(variety::NormalToricVarietyType)","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/cohomCalg/#immaculate_line_bundles-Tuple{Union{AffineNormalToricVariety, CyclicQuotientSingularity, NormalToricVariety}}","page":"Line bundle cohomology with cohomCalg","title":"immaculate_line_bundles","text":"immaculate_line_bundles(variety::NormalToricVarietyType)\n\nComputes all immaculate line bundles as a toric vanishing set by intersecting the vanishing sets for all cohomology indices.\n\nExamples\n\njulia> dP1 = del_pezzo_surface(NormalToricVariety, 1)\nNormal toric variety\n\njulia> ilb = immaculate_line_bundles(dP1)\nToric vanishing set for cohomology indices [0, 1, 2]\n\njulia> polyhedra(ilb)\n4-element Vector{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\njulia> print_constraints(polyhedra(ilb)[1])\n-x_1 <= 0\n-x_1 + x_2 <= 0\n\njulia> print_constraints(polyhedra(ilb)[2])\n-x_1 + x_2 <= 0\nx_2 <= -2\n\njulia> print_constraints(polyhedra(ilb)[3])\n-x_2 <= -1\nx_1 - x_2 <= -2\n\njulia> print_constraints(polyhedra(ilb)[4])\nx_1 - x_2 <= -2\nx_1 <= -3\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, ZZ 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 only be used with great care in library code. There are a number of reasons for this.","category":"page"},{"location":"Nemo/developer/parents/","page":"Parent objects","title":"Parent objects","text":"One issue is that parent objects are allowed to be arbitrarily large, and they are frequently cached by the system. They can also perform arbitrary precomputations for the ring/field/module etc. that is being constructed. This can lead to excessive memory usage. It can also have odd effects when a behavior affecting change is applied to a cached parent and thus has effects in places where one might not expect it. ","category":"page"},{"location":"Nemo/developer/parents/","page":"Parent objects","title":"Parent objects","text":"Secondly, those parent caches are global objects. This is problematic for any future attempts to parallelise library code. And if the caches are not regularly emptied, in the worst case memory usage can balloon excessively.","category":"page"},{"location":"Nemo/developer/parents/","page":"Parent objects","title":"Parent objects","text":"To deal with this, most parent object constructors take a cached keyword which specifies whether the parent object should be cached which library code should generally set to false. That said it is better overall to simply eschew the use of parent object constructors in library code and instead let parents be passed in via arguments (directly or indirectly, e.g. the parent or base ring of some argument might be a suitable parent for some return values or intermediate objects).","category":"page"},{"location":"Nemo/developer/parents/","page":"Parent objects","title":"Parent objects","text":"One may also use, where applicable, functions such as similar, zero, zero_matrix, identity_matrix, change_base_ring, map, etc. for constructing polynomials and matrices directly without a parent object.","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. 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":"Forcing the creation 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":"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!, 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 = Oscar.doctestsetup()","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.","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)\ncomplement_of_prime_ideal(P::MPolyIdeal; check::Bool=false)\npowers_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=true)\n\nGiven a prime ideal P of a polynomial ring R, say, return the multiplicatively closed subset Rsetminus P\n\nnote: Note\nSince 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 generated by\n 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 (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":"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 generated by\n 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 generated by\n 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 x, y, z\n over rational field\n at complement of prime ideal (x)\n\njulia> iota\nRing homomorphism\n from multivariate polynomial ring in 3 variables over QQ\n to localization of multivariate polynomial ring in 3 variables over QQ at complement of prime ideal (x)\ndefined by\n x -> x\n y -> y\n z -> z\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 generated by\n 2*x^2 - y^3\n 2*x^2 - y^5\n\njulia> P = ideal(R, [y-1, x-a])\nIdeal generated by\n y - 1\n 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 K\n\njulia> RQ, _ = quo(R, I);\n\njulia> RQL, iota = localization(RQ, U);\n\njulia> RQL\nLocalization\n of quotient\n of multivariate polynomial ring in 2 variables x, y\n over number field of degree 2 over QQ\n by ideal (2*x^2 - y^3, 2*x^2 - y^5)\n at complement of prime ideal (y - 1, x - a)\n\njulia> iota\nMap defined by a julia-function\n from quotient of multivariate polynomial ring by ideal (2*x^2 - y^3, 2*x^2 - y^5)\n to localization of RQ at complement of prime ideal\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 generated by\n 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 generated by\n 2*x^2 - y^3\n 2*x^2 - y^5\n\njulia> P = ideal(R, [y-1, x-a])\nIdeal generated by\n y - 1\n 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 K\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 generated by\n 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 generated by\n 2*x^2 - y^3\n 2*x^2 - y^5\n\njulia> P = ideal(R, [y-1, x-a])\nIdeal generated by\n y - 1\n 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 K\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 behavior 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 generated by\n 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 x, y, z\n over rational field\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 generated by\n 2*x^2 - y^3\n 2*x^2 - y^5\n\njulia> P = ideal(R, [y-1, x-a])\nIdeal generated by\n y - 1\n 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 K\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\n of multivariate polynomial ring in 2 variables x, y\n over number field of degree 2 over QQ\n by ideal (2*x^2 - y^3, 2*x^2 - y^5)\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{Oscar.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 generated by\n 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{Oscar.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 generated by\n 2*x^2 - y^3\n 2*x^2 - y^5\n\njulia> P = ideal(R, [y-1, x-a])\nIdeal generated by\n y - 1\n 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 K\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{Oscar.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 RQ at complement of maximal ideal\n to localization of multivariate polynomial ring in 1 variable over QQ at complement of maximal ideal of point (0)\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 of point (0)\n to localization of RQ 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{Oscar.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)\nRing homomorphism\n from multivariate polynomial ring in 3 variables over QQ\n to localization of multivariate polynomial ring in 1 variable over QQ at complement of maximal ideal of point (0)\ndefined by\n x -> t\n y -> t^2\n z -> t^3\n\njulia> psi = restricted_map(PSI)\nRing homomorphism\n from multivariate polynomial ring in 1 variable over QQ\n to localization of RQ at complement of maximal ideal\ndefined by\n t -> x\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 generated by\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,\nnumber_of_generators(I) / ngens(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, [Eis95]). 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{Oscar.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 generated by\n x^2 + x\n\njulia> SI = saturated_ideal(I)\nIdeal generated by\n 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 generated by\n x^2 + x\n\njulia> saturated_ideal(I)\nIdeal generated by\n 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, n_rays(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 n_rays(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, n_rays(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 can be constructed using QQBar = algebraic_closure(QQ). We will leave out this line from all code blocks on this page for brevity.","category":"page"},{"location":"Nemo/algebraic/","page":"Algebraic numbers","title":"Algebraic numbers","text":"Library Element type Parent type\nCalcium QQBarFieldElem QQBarField","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 a 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{QQBarFieldElem}:\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(QQBar, ZZ[1 1 0; 0 1 1; 1 0 1])\n3-element Vector{QQBarFieldElem}:\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::QQBarField, f::ZZPolyRingElem)\nroots(R::QQBarField, f::QQPolyRingElem)\neigenvalues(R::QQBarField, A::ZZMatrix)\neigenvalues_with_multiplicities(R::QQBarField, A::ZZMatrix)\neigenvalues(R::QQBarField, A::QQMatrix)\neigenvalues_with_multiplicities(R::QQBarField, A::QQMatrix)\nrand(R::QQBarField; degree::Int, bits::Int, randtype::Symbol=:null)","category":"page"},{"location":"Nemo/algebraic/#roots-Tuple{QQBarField, ZZPolyRingElem}","page":"Algebraic numbers","title":"roots","text":"roots(R::QQBarField, 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{QQBarField, QQPolyRingElem}","page":"Algebraic numbers","title":"roots","text":"roots(R::QQBarField, 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{QQBarField, ZZMatrix}","page":"Algebraic numbers","title":"eigenvalues","text":"eigenvalues(R::QQBarField, A::ZZMatrix)\neigenvalues(R::QQBarField, A::QQMatrix)\n\nReturn the eigenvalues A 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\neigenvalues(L::Field, M::MatElem{T}) where T <: RingElem\n\nReturn the eigenvalues of M over the field L.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/algebraic/#eigenvalues_with_multiplicities-Tuple{QQBarField, ZZMatrix}","page":"Algebraic numbers","title":"eigenvalues_with_multiplicities","text":"eigenvalues_with_multiplicities(R::QQBarField, A::ZZMatrix)\neigenvalues_with_multiplicities(R::QQBarField, A::QQMatrix)\n\nReturn the eigenvalues A in the field of algebraic numbers R together with their algebraic multiplicities as a vector of tuples. The output array is sorted in the default sort order for algebraic numbers.\n\n\n\n\n\neigenvalues_with_multiplicities(L::Field, M::MatElem{T}) where T <: RingElem\n\nReturn the eigenvalues of M over the field L together with their algebraic multiplicities as a vector of tuples.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/algebraic/#eigenvalues-Tuple{QQBarField, QQMatrix}","page":"Algebraic numbers","title":"eigenvalues","text":"eigenvalues(R::QQBarField, A::ZZMatrix)\neigenvalues(R::QQBarField, A::QQMatrix)\n\nReturn the eigenvalues A 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\neigenvalues(L::Field, M::MatElem{T}) where T <: RingElem\n\nReturn the eigenvalues of M over the field L.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/algebraic/#eigenvalues_with_multiplicities-Tuple{QQBarField, QQMatrix}","page":"Algebraic numbers","title":"eigenvalues_with_multiplicities","text":"eigenvalues_with_multiplicities(R::QQBarField, A::ZZMatrix)\neigenvalues_with_multiplicities(R::QQBarField, A::QQMatrix)\n\nReturn the eigenvalues A in the field of algebraic numbers R together with their algebraic multiplicities as a vector of tuples. The output array is sorted in the default sort order for algebraic numbers.\n\n\n\n\n\neigenvalues_with_multiplicities(L::Field, M::MatElem{T}) where T <: RingElem\n\nReturn the eigenvalues of M over the field L together with their algebraic multiplicities as a vector of tuples.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/algebraic/#rand-Tuple{QQBarField}","page":"Algebraic numbers","title":"rand","text":"rand(R::QQBarField; 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{QQBarFieldElem}:\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::QQBarFieldElem)\nisone(x::QQBarFieldElem)\nisinteger(x::QQBarFieldElem)\nis_rational(x::QQBarFieldElem)\nisreal(x::QQBarFieldElem)\ndegree(x::QQBarFieldElem)\nis_algebraic_integer(x::QQBarFieldElem)\nminpoly(R::ZZPolyRing, x::QQBarFieldElem)\nminpoly(R::QQPolyRing, x::QQBarFieldElem)\nconjugates(a::QQBarFieldElem)\ndenominator(x::QQBarFieldElem)\nnumerator(x::QQBarFieldElem)\nheight(x::QQBarFieldElem)\nheight_bits(x::QQBarFieldElem)","category":"page"},{"location":"Nemo/algebraic/#iszero-Tuple{QQBarFieldElem}","page":"Algebraic numbers","title":"iszero","text":"iszero(x::QQBarFieldElem)\n\nReturn whether x is the number 0.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/algebraic/#isone-Tuple{QQBarFieldElem}","page":"Algebraic numbers","title":"isone","text":"isone(x::QQBarFieldElem)\n\nReturn whether x is the number 1.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/algebraic/#isinteger-Tuple{QQBarFieldElem}","page":"Algebraic numbers","title":"isinteger","text":"isinteger(x::QQBarFieldElem)\n\nReturn whether x is an integer.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/algebraic/#is_rational-Tuple{QQBarFieldElem}","page":"Algebraic numbers","title":"is_rational","text":"is_rational(x::QQBarFieldElem)\n\nReturn whether x is a rational number.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/algebraic/#isreal-Tuple{QQBarFieldElem}","page":"Algebraic numbers","title":"isreal","text":"isreal(x::QQBarFieldElem)\n\nReturn whether x is a real number.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/algebraic/#degree-Tuple{QQBarFieldElem}","page":"Algebraic numbers","title":"degree","text":"degree(x::QQBarFieldElem)\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{QQBarFieldElem}","page":"Algebraic numbers","title":"is_algebraic_integer","text":"is_algebraic_integer(x::QQBarFieldElem)\n\nReturn whether x is an algebraic integer.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/algebraic/#minpoly-Tuple{ZZPolyRing, QQBarFieldElem}","page":"Algebraic numbers","title":"minpoly","text":"minpoly(R::ZZPolyRing, x::QQBarFieldElem)\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, QQBarFieldElem}","page":"Algebraic numbers","title":"minpoly","text":"minpoly(R::ZZPolyRing, x::QQBarFieldElem)\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{QQBarFieldElem}","page":"Algebraic numbers","title":"conjugates","text":"conjugates(a::QQBarFieldElem)\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{QQBarFieldElem}","page":"Algebraic numbers","title":"denominator","text":"denominator(x::QQBarFieldElem)\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{QQBarFieldElem}","page":"Algebraic numbers","title":"numerator","text":"numerator(x::QQBarFieldElem)\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{QQBarFieldElem}","page":"Algebraic numbers","title":"height","text":"height(x::QQBarFieldElem)\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{QQBarFieldElem}","page":"Algebraic numbers","title":"height_bits","text":"height_bits(x::QQBarFieldElem)\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::QQBarFieldElem)\nimag(a::QQBarFieldElem)\nabs(a::QQBarFieldElem)\nabs2(a::QQBarFieldElem)\nconj(a::QQBarFieldElem)\nsign(a::QQBarFieldElem)\ncsgn(a::QQBarFieldElem)\nsign_real(a::QQBarFieldElem)\nsign_imag(a::QQBarFieldElem)","category":"page"},{"location":"Nemo/algebraic/#real-Tuple{QQBarFieldElem}","page":"Algebraic numbers","title":"real","text":"real(a::QQBarFieldElem)\n\nReturn the real part of a.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/algebraic/#imag-Tuple{QQBarFieldElem}","page":"Algebraic numbers","title":"imag","text":"imag(a::QQBarFieldElem)\n\nReturn the imaginary part of a.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/algebraic/#abs-Tuple{QQBarFieldElem}","page":"Algebraic numbers","title":"abs","text":"abs(a::QQBarFieldElem)\n\nReturn the absolute value of a.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/algebraic/#abs2-Tuple{QQBarFieldElem}","page":"Algebraic numbers","title":"abs2","text":"abs2(a::QQBarFieldElem)\n\nReturn the squared absolute value of a.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/algebraic/#conj-Tuple{QQBarFieldElem}","page":"Algebraic numbers","title":"conj","text":"conj(a::QQBarFieldElem)\n\nReturn the complex conjugate of a.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/algebraic/#sign-Tuple{QQBarFieldElem}","page":"Algebraic numbers","title":"sign","text":"sign(a::QQBarFieldElem)\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{QQBarFieldElem}","page":"Algebraic numbers","title":"csgn","text":"csgn(a::QQBarFieldElem)\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{QQBarFieldElem}","page":"Algebraic numbers","title":"sign_real","text":"sign_real(a::QQBarFieldElem)\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{QQBarFieldElem}","page":"Algebraic numbers","title":"sign_imag","text":"sign_imag(a::QQBarFieldElem)\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/#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::QQBarFieldElem, b::QQBarFieldElem)\nis_equal_imag(a::QQBarFieldElem, b::QQBarFieldElem)\nis_equal_abs(a::QQBarFieldElem, b::QQBarFieldElem)\nis_equal_abs_real(a::QQBarFieldElem, b::QQBarFieldElem)\nis_equal_abs_imag(a::QQBarFieldElem, b::QQBarFieldElem)\nis_less_real(a::QQBarFieldElem, b::QQBarFieldElem)\nis_less_imag(a::QQBarFieldElem, b::QQBarFieldElem)\nis_less_abs(a::QQBarFieldElem, b::QQBarFieldElem)\nis_less_abs_real(a::QQBarFieldElem, b::QQBarFieldElem)\nis_less_abs_imag(a::QQBarFieldElem, b::QQBarFieldElem)\nis_less_root_order(a::QQBarFieldElem, b::QQBarFieldElem)","category":"page"},{"location":"Nemo/algebraic/#is_equal_real-Tuple{QQBarFieldElem, QQBarFieldElem}","page":"Algebraic numbers","title":"is_equal_real","text":"is_equal_real(a::QQBarFieldElem, b::QQBarFieldElem)\n\nCompares the real parts of a and b.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/algebraic/#is_equal_imag-Tuple{QQBarFieldElem, QQBarFieldElem}","page":"Algebraic numbers","title":"is_equal_imag","text":"is_equal_imag(a::QQBarFieldElem, b::QQBarFieldElem)\n\nCompares the imaginary parts of a and b.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/algebraic/#is_equal_abs-Tuple{QQBarFieldElem, QQBarFieldElem}","page":"Algebraic numbers","title":"is_equal_abs","text":"is_equal_abs(a::QQBarFieldElem, b::QQBarFieldElem)\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{QQBarFieldElem, QQBarFieldElem}","page":"Algebraic numbers","title":"is_equal_abs_real","text":"is_equal_abs_real(a::QQBarFieldElem, b::QQBarFieldElem)\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{QQBarFieldElem, QQBarFieldElem}","page":"Algebraic numbers","title":"is_equal_abs_imag","text":"is_equal_abs_imag(a::QQBarFieldElem, b::QQBarFieldElem)\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{QQBarFieldElem, QQBarFieldElem}","page":"Algebraic numbers","title":"is_less_real","text":"is_less_real(a::QQBarFieldElem, b::QQBarFieldElem)\n\nCompares the real parts of a and b.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/algebraic/#is_less_imag-Tuple{QQBarFieldElem, QQBarFieldElem}","page":"Algebraic numbers","title":"is_less_imag","text":"is_less_imag(a::QQBarFieldElem, b::QQBarFieldElem)\n\nCompares the imaginary parts of a and b.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/algebraic/#is_less_abs-Tuple{QQBarFieldElem, QQBarFieldElem}","page":"Algebraic numbers","title":"is_less_abs","text":"is_less_abs(a::QQBarFieldElem, b::QQBarFieldElem)\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{QQBarFieldElem, QQBarFieldElem}","page":"Algebraic numbers","title":"is_less_abs_real","text":"is_less_abs_real(a::QQBarFieldElem, b::QQBarFieldElem)\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{QQBarFieldElem, QQBarFieldElem}","page":"Algebraic numbers","title":"is_less_abs_imag","text":"is_less_abs_imag(a::QQBarFieldElem, b::QQBarFieldElem)\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{QQBarFieldElem, QQBarFieldElem}","page":"Algebraic numbers","title":"is_less_root_order","text":"is_less_root_order(a::QQBarFieldElem, b::QQBarFieldElem)\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::QQBarFieldElem)\nroot(a::QQBarFieldElem, n::Int)\nroot_of_unity(C::QQBarField, n::Int)\nroot_of_unity(C::QQBarField, n::Int, k::Int)\nis_root_of_unity(a::QQBarFieldElem)\nroot_of_unity_as_args(a::QQBarFieldElem)\nexp_pi_i(a::QQBarFieldElem)\nlog_pi_i(a::QQBarFieldElem)\nsinpi(a::QQBarFieldElem)\ncospi(a::QQBarFieldElem)\nsincospi(a::QQBarFieldElem)\ntanpi(a::QQBarFieldElem)\nasinpi(a::QQBarFieldElem)\nacospi(a::QQBarFieldElem)\natanpi(a::QQBarFieldElem)","category":"page"},{"location":"Nemo/algebraic/#sqrt-Tuple{QQBarFieldElem}","page":"Algebraic numbers","title":"sqrt","text":"sqrt(a::QQBarFieldElem; check::Bool=true)\n\nReturn the principal square root of a.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/algebraic/#root-Tuple{QQBarFieldElem, Int64}","page":"Algebraic numbers","title":"root","text":"root(a::QQBarFieldElem, 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{QQBarField, Int64}","page":"Algebraic numbers","title":"root_of_unity","text":"root_of_unity(C::QQBarField, 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{QQBarField, Int64, Int64}","page":"Algebraic numbers","title":"root_of_unity","text":"root_of_unity(C::QQBarField, 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{QQBarFieldElem}","page":"Algebraic numbers","title":"is_root_of_unity","text":"is_root_of_unity(a::QQBarFieldElem)\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{QQBarFieldElem}","page":"Algebraic numbers","title":"root_of_unity_as_args","text":"root_of_unity_as_args(a::QQBarFieldElem)\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{QQBarFieldElem}","page":"Algebraic numbers","title":"exp_pi_i","text":"exp_pi_i(a::QQBarFieldElem)\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{QQBarFieldElem}","page":"Algebraic numbers","title":"log_pi_i","text":"log_pi_i(a::QQBarFieldElem)\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{QQBarFieldElem}","page":"Algebraic numbers","title":"sinpi","text":"sinpi(a::QQBarFieldElem)\n\nReturn sin(pi a) as an algebraic number. Throws if this value is transcendental.\n\nExamples\n\njulia> QQBar = algebraic_closure(QQ);\n\njulia> x = sinpi(QQBar(1//3))\nRoot 0.866025 of 4x^2 - 3\n\njulia> sinpi(x)\nERROR: DomainError with Root 0.866025 of 4x^2 - 3:\nnonrational algebraic number\n\n\n\n\n\n","category":"method"},{"location":"Nemo/algebraic/#cospi-Tuple{QQBarFieldElem}","page":"Algebraic numbers","title":"cospi","text":"cospi(a::QQBarFieldElem)\n\nReturn cos(pi a) as an algebraic number. Throws if this value is transcendental.\n\nExamples\n\njulia> QQBar = algebraic_closure(QQ);\n\njulia> x = cospi(QQBar(1//6))\nRoot 0.866025 of 4x^2 - 3\n\njulia> cospi(x)\nERROR: DomainError with Root 0.866025 of 4x^2 - 3:\nnonrational algebraic number\n\n\n\n\n\n","category":"method"},{"location":"Nemo/algebraic/#sincospi-Tuple{QQBarFieldElem}","page":"Algebraic numbers","title":"sincospi","text":"sincospi(a::QQBarFieldElem)\n\nReturn sin(pi a) and cos(pi a) as a pair of algebraic numbers. Throws if either value is transcendental.\n\nExamples\n\njulia> QQBar = algebraic_closure(QQ);\n\njulia> s, c = sincospi(QQBar(1//3))\n(Root 0.866025 of 4x^2 - 3, Root 0.500000 of 2x - 1)\n\njulia> sincospi(s)\nERROR: DomainError with Root 0.866025 of 4x^2 - 3:\nnonrational algebraic number\n\n\n\n\n\n","category":"method"},{"location":"Nemo/algebraic/#tanpi-Tuple{QQBarFieldElem}","page":"Algebraic numbers","title":"tanpi","text":"tanpi(a::QQBarFieldElem)\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{QQBarFieldElem}","page":"Algebraic numbers","title":"asinpi","text":"asinpi(a::QQBarFieldElem)\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{QQBarFieldElem}","page":"Algebraic numbers","title":"acospi","text":"acospi(a::QQBarFieldElem)\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{QQBarFieldElem}","page":"Algebraic numbers","title":"atanpi","text":"atanpi(a::QQBarFieldElem)\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 = RealField(); 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, at best the only algebraic number that can be guessed is the binary floating-point number itself, at worst no guess is possible.","category":"page"},{"location":"Nemo/algebraic/","page":"Algebraic numbers","title":"Algebraic numbers","text":"julia> RR = RealField();\n\njulia> x = RR(0.1) # note: 53-bit binary approximation of 1//10 without radius\n[0.10000000000000000555 +/- 1.12e-21]\n\njulia> guess(QQBar, x, 1)\nERROR: No suitable algebraic number found\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","category":"page"},{"location":"Nemo/algebraic/#guess","page":"Algebraic numbers","title":"guess","text":"guess(R::QQBarField, x::AcbFieldElem, maxdeg::Int, maxbits::Int=0)\nguess(R::QQBarField, x::ArbFieldElem, maxdeg::Int, maxbits::Int=0)\nguess(R::QQBarField, x::ComplexFieldElem, maxdeg::Int, maxbits::Int=0)\nguess(R::QQBarField, x::RealFieldElem, 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 = Oscar.doctestsetup()","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 behavior 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 cancelation 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, number_of_generators, 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 = Oscar.doctestsetup()","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 = incidence_matrix([[1,2],[2,3],[3,4],[4,5],[1,5]]);\n\njulia> PF=polyhedral_fan(IM, R)\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 = incidence_matrix([[1],[2]]);\n\njulia> PF=polyhedral_fan(IM, R, L)\nPolyhedral fan in ambient dimension 3\n\njulia> lineality_dim(PF)\n1\n\n\n\n\n\npolyhedral_fan(cones::AbstractVector{Cone{T}}) where T<:scalar_types\n\nAssemble a polyhedral fan from a non-empty list of cones.\n\n\n\n\n\npolyhedral_fan(v::NormalToricVarietyType)\n\nReturn the fan of an abstract normal toric variety v.\n\nExamples\n\njulia> p2 = projective_space(NormalToricVariety, 2)\nNormal toric variety\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) == n_facets(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)\narrangement_polynomial\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)\nmaximal_cones(PF::PolyhedralFan)\ncones(PF::PolyhedralFan, cone_dim::Int)\ncones(PF::PolyhedralFan)\nn_maximal_cones(PF::PolyhedralFan)\nn_cones(PF::PolyhedralFan)\nn_rays(PF::PolyhedralFan)\nrays(PF::PolyhedralFan)\nrays_modulo_lineality(PF::PolyhedralFan)\nprimitive_collections(PF::PolyhedralFan)\nstar_subdivision(PF::PolyhedralFan, n::Int)\nstar_subdivision(PF::PolyhedralFan, new_ray::AbstractVector{<:IntegerUnion})\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(TropV::TropicalVariety)\n\nSee ambient_dim(::PolyhedralComplex).\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/fans/#arrangement_polynomial","page":"Polyhedral Fans","title":"arrangement_polynomial","text":"arrangement_polynomial([ring::MPolyRing{<: FieldElem},] A::MatElem{<: FieldElem})\n\nGiven some AinmathbbF^ntimes d return the product of the linear forms corresponding to the rows.\n\nLet A be a ntimes d matrix with entries from a field mathbbF. The rows of A are the normal vectors for a hyperplane arrangement mathcalA = H_1dotsH_nH_isubset mathbbF^d We have H_i = V(alpha_i), where alpha_iinmathbbFx_1dotsx_d is a linear form whose coefficients are the entries of the ith row.\n\nThen we have cup_H_iinmathcalAH_i = V(Pi^n_i=1alpha_i)\n\nOptionally one can select to use columns instead of rows in the following way:\n\narrangement_polynomial(... ; hyperplanes=:in_cols)\n\nExample using standard ring and then custom ring.\n\njulia> A = matrix(QQ,[1 2 5//2; 0 0 1; 2 3 2; 1//2 3 5; 3 1 2; 7 8 1])\n[ 1 2 5//2]\n[ 0 0 1]\n[ 2 3 2]\n[1//2 3 5]\n[ 3 1 2]\n[ 7 8 1]\n\njulia> factor(arrangement_polynomial(A))\n(1//4) * (2*x1 + 3*x2 + 2*x3) * (7*x1 + 8*x2 + x3) * (x1 + 6*x2 + 10*x3) * (2*x1 + 4*x2 + 5*x3) * x3 * (3*x1 + x2 + 2*x3)\n\njulia> R,_ = polynomial_ring(QQ, [:x, :y, :z])\n(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])\n\njulia> factor(arrangement_polynomial(R, A))\n(1//4) * (2*x + 3*y + 2*z) * (7*x + 8*y + z) * (x + 6*y + 10*z) * (2*x + 4*y + 5*z) * z * (3*x + y + 2*z)\n\nTo use the columns instead, proceed in the following way:\n\njulia> A = matrix(QQ,[1 0 2 1//2 3 7;2 0 3 3 1 8;5//2 1 2 5 2 1]);\n\njulia> factor(arrangement_polynomial(A; hyperplanes=:in_cols))\n(1//4) * (2*x1 + 3*x2 + 2*x3) * (7*x1 + 8*x2 + x3) * (x1 + 6*x2 + 10*x3) * (2*x1 + 4*x2 + 5*x3) * x3 * (3*x1 + x2 + 2*x3)\n\n\n\n\n\n","category":"function"},{"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(incidence_matrix([[1, 2], [3]]), [1 0; 0 1; -1 -1]);\n\njulia> dim(PF)\n2\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)\nPolytope 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\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(incidence_matrix([[1, 2], [3]]), [1 0; 0 1; -1 -1]);\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\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(incidence_matrix([[1, 2], [2, 3]]), [0 1; 2 1; 1 0]);\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\n","category":"method"},{"location":"PolyhedralGeometry/fans/#lineality_space-Tuple{PolyhedralFan}","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(incidence_matrix([[1, 2, 3], [3, 4, 1]]), [1 0; 0 1; -1 0; 0 -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\n","category":"method"},{"location":"PolyhedralGeometry/fans/#maximal_cones-Tuple{PolyhedralFan}","page":"Polyhedral Fans","title":"maximal_cones","text":"maximal_cones(PF::PolyhedralFan)\n\nReturn the maximal cones of PF.\n\nOptionally IncidenceMatrix can be passed as a first argument to return the incidence matrix specifying the maximal cones of PF. In that case, the indices refer to the output of rays_modulo_lineality(Cone).\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(n_rays(c))\n end\n4\n4\n4\n4\n4\n4\n\njulia> maximal_cones(IncidenceMatrix, PF)\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\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/fans/#cones-Tuple{PolyhedralFan, Int64}","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(incidence_matrix([[1, 2], [3]]), [1 0; 0 1; -1 -1]);\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(incidence_matrix([[1, 2], [3]]), [1 0; 0 1; -1 -1])\nPolyhedral fan in ambient dimension 2\n\njulia> n_cones(PF)\n4\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/fans/#n_rays-Tuple{PolyhedralFan}","page":"Polyhedral Fans","title":"n_rays","text":"n_rays(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> n_rays(face_fan(cube(3)))\n8\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/fans/#rays-Tuple{PolyhedralFan}","page":"Polyhedral Fans","title":"rays","text":"rays([as::Type{T} = RayVector,] PF::PolyhedralFan)\n\nReturn the rays of PF. The rays are defined to be the one-dimensional faces of its cones, so if PF has lineality, there are no rays.\n\nSee also rays_modulo_lineality.\n\nOptional arguments for as include\n\nRayVector.\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\nThe following fan has no rays:\n\njulia> IM = incidence_matrix([[1,2],[2,3]]);\n\njulia> R = [1 0 0; 0 1 0; -1 0 0];\n\njulia> L = [0 0 1];\n\njulia> PF = polyhedral_fan(IM, R, L)\nPolyhedral fan in ambient dimension 3\n\njulia> rays(PF)\n0-element SubObjectIterator{RayVector{QQFieldElem}}\n\n\n\n\n\nrays(TropV::TropicalVariety)\n\nSee rays(::PolyhedralComplex).\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/fans/#rays_modulo_lineality-Tuple{PolyhedralFan}","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\nSee also rays and lineality_space.\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\nrays_modulo_lineality(TropV::TropicalVariety)\n\nSee rays_modulo_lineality(::PolyhedralComplex).\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-Tuple{PolyhedralFan, Int64}","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 [CLS11].\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-Tuple{PolyhedralFan, AbstractVector{<:Union{Integer, ZZRingElem}}}","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 [CLS11].\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\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\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\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\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\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);\n\njulia> K = total_ring_of_fractions(R)\nTotal ring of fractions of residue ring\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\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\nis_divisible_by(f::T, g::T) where T <: RingElem\nis_associated(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\ncoprime_base\ncoprime_base_push!","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/#is_divisible_by-Union{Tuple{T}, Tuple{T, T}} where T<:RingElem","page":"Euclidean Ring Interface","title":"is_divisible_by","text":"is_divisible_by(x::T, y::T) where T <: RingElem\n\nCheck if x is divisible by y, i.e. if x = zy for some z.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/euclidean_interface/#is_associated-Union{Tuple{T}, Tuple{T, T}} where T<:RingElem","page":"Euclidean Ring Interface","title":"is_associated","text":"is_associated(x::T, y::T) where T <: RingElem\n\nCheck if x and y are associated, i.e. if x is a unit times y.\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":"AbstractAlgebra/euclidean_interface/#coprime_base","page":"Euclidean Ring Interface","title":"coprime_base","text":"coprime_base(S::Vector{RingElement}) -> Vector{RingElement}\n\nReturns a coprime base for S, i.e. the resulting array contains pairwise coprime objects that multiplicatively generate the same set as the input array.\n\n\n\n\n\ncoprime_base(A::Vector{AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}}) -> Vector{AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}}\ncoprime_base(A::Vector{AbsSimpleNumFieldOrderElem}) -> Vector{AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}}\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":"function"},{"location":"AbstractAlgebra/euclidean_interface/#coprime_base_push!","page":"Euclidean Ring Interface","title":"coprime_base_push!","text":"coprime_base_push!(S::Vector{RingElem}, a::RingElem) -> Vector{RingElem}\n\nGiven an array S of coprime elements, insert a new element, that is, find a coprime base for push(S, a).\n\n\n\n\n\n","category":"function"},{"location":"NoncommutativeAlgebra/PBWAlgebras/creation/","page":"Creating PBW-Algebras","title":"Creating PBW-Algebras","text":"CurrentModule = Oscar\nDocTestSetup = Oscar.doctestsetup()","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 modeled 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 mathbbN^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,\nnumber_of_generators(A) / ngens(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> number_of_generators(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":"AlgebraicGeometry/SheafCohomology/sheaf_cohomology/","page":"Sheaves on Projective Space","title":"Sheaves on Projective Space","text":"CurrentModule = Oscar\nDocTestSetup = Oscar.doctestsetup()","category":"page"},{"location":"AlgebraicGeometry/SheafCohomology/sheaf_cohomology/#Sheaves-on-Projective-Space","page":"Sheaves on Projective Space","title":"Sheaves on Projective Space","text":"","category":"section"},{"location":"AlgebraicGeometry/SheafCohomology/sheaf_cohomology/","page":"Sheaves on Projective Space","title":"Sheaves on Projective Space","text":"We present two algorithms for computing sheaf cohomology over projective n-space. The algorithms are based on Tate resolutions via the Bernstein-Gelfand-Gelfand-correspondence as introduced in [EFS03] and on local cohomology (see [Eis98]), respectively. While the first algorithm makes use of syzygy computations over the exterior algebra, the second algorithm is based on syzygy computations over the symmetric algebra (see [DE02] for a tutorial). Thus, in most examples, the first algorithm is much faster.","category":"page"},{"location":"AlgebraicGeometry/SheafCohomology/sheaf_cohomology/","page":"Sheaves on Projective Space","title":"Sheaves on Projective Space","text":"sheaf_cohomology(M::ModuleFP{T}, l::Int, h::Int; algorithm::Symbol = :bgg) where {T <: MPolyDecRingElem}","category":"page"},{"location":"AlgebraicGeometry/SheafCohomology/sheaf_cohomology/#sheaf_cohomology-Union{Tuple{T}, Tuple{ModuleFP{T}, Int64, Int64}} where T<:MPolyDecRingElem","page":"Sheaves on Projective Space","title":"sheaf_cohomology","text":"sheaf_cohomology(M::ModuleFP{T}, l::Int, h::Int; algorithm::Symbol = :bgg) where {T <: MPolyDecRingElem}\n\nIf M is a graded module over a standard graded multivariate polynomial ring with coefficients in a field K, say, and mathcal F = widetildeM is the coherent sheaf associated to M on the corresponding projective space mathbb P^n(K), consider the cohomology groups H^i(mathbb P^n(K) mathcal F(d)) as vector spaces over K, and return their dimensions h^i(mathbb P^n(K) mathcal F(d)) in the range of twists d indicated by l and h. The result is presented as a table, where '-' indicates that h^i(mathbb P^n(K) mathcal F(d)) = 0. The line starting with chi lists the Euler characteristic of each twist under consideration. The values in the table can be accessed as shown in the first example below. Note that this example addresses the cotangent bundle on projective 3-space, while the second example is concerned with the structure sheaf of projective 4-space.\n\nThe keyword algorithm can be set to\n\n:bgg (use the Tate resolution via the Bernstein-Gelfand-Gelfand correspondence),\n:loccoh (use local cohomology).\n\nnote: Note\nDue to the shape of the Tate resolution, the algorithm addressed by bgg does not compute all values in the given range l h. The missing values are indicated by a *. To determine all values in the range l h, enter sheaf_cohomology(M, l-ngens(base_ring(M)), h+ngens(base_ring(M))).\n\njulia> R, x = polynomial_ring(QQ, :x => 1:4);\n\njulia> S, _= grade(R);\n\njulia> I = ideal(S, gens(S))\nIdeal generated by\n x[1]\n x[2]\n x[3]\n x[4]\n\njulia> FI = free_resolution(I)\nFree resolution of I\nS^4 <---- S^6 <---- S^4 <---- S^1 <---- 0\n0 1 2 3 4\n\njulia> M = cokernel(map(FI, 2));\n\njulia> tbl = sheaf_cohomology(M, -6, 2)\ntwist: -6 -5 -4 -3 -2 -1 0 1 2\n------------------------------------------\n3: 70 36 15 4 - - - - *\n2: * - - - - - - - -\n1: * * - - - - 1 - -\n0: * * * - - - - - 6\n------------------------------------------\nchi: * * * 4 - - 1 - *\n\njulia> tbl[0, 2]\n6\n\njulia> tbl[1, 0]\n1\n\njulia> sheaf_cohomology(M, -9, 5)\ntwist: -9 -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5\n---------------------------------------------------------------------------------\n3: 280 189 120 70 36 15 4 - - - - - * * *\n2: * - - - - - - - - - - - - * *\n1: * * - - - - - - - 1 - - - - *\n0: * * * - - - - - - - - 6 20 45 84\n---------------------------------------------------------------------------------\nchi: * * * 70 36 15 4 - - 1 - 6 * * *\n\njulia> R, x = polynomial_ring(QQ, :x => 1:5);\n\njulia> S, _ = grade(R);\n\njulia> F = graded_free_module(S, 1);\n\njulia> sheaf_cohomology(F, -8, 3, algorithm = :loccoh)\ntwist: -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3\n------------------------------------------------------\n4: 35 15 5 1 - - - - - - - -\n3: - - - - - - - - - - - -\n2: - - - - - - - - - - - -\n1: - - - - - - - - - - - -\n0: - - - - - - - - 1 5 15 35\n------------------------------------------------------\nchi: 35 15 5 1 - - - - 1 5 15 35\n\n\n\n\n\n","category":"method"},{"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!, 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 = add(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 add 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 (and the existence of a specialized method), add 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, add 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, 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/#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 AbsSimpleNumFieldElem type:","category":"page"},{"location":"Nemo/developer/topics/","page":"Specific topics","title":"Specific topics","text":"mul_red!(z::AbsSimpleNumFieldElem, x::AbsSimpleNumFieldElem, y::AbsSimpleNumFieldElem, 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::AbsSimpleNumFieldElem)","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 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 add! where delayed reduction or addmul! are not available.","category":"page"},{"location":"Experimental/AlgebraicStatistics/graphical_models/","page":"Graphical Models","title":"Graphical Models","text":"CurrentModule = Oscar\nDocTestSetup = Oscar.doctestsetup()","category":"page"},{"location":"Experimental/AlgebraicStatistics/graphical_models/#Graphical-Models","page":"Graphical Models","title":"Graphical Models","text":"","category":"section"},{"location":"Experimental/AlgebraicStatistics/graphical_models/","page":"Graphical Models","title":"Graphical Models","text":"The OSCAR type for graphical models is of parametrized form GraphicalModel{G, T} where T represents the type of ring in which the vanishing ideal of the model belongs and G represents the associated graph. This parametrized typing allows the user to easily build upon the existing functionality to work with newer variations on graphical models such as those with colours or hidden variables. ","category":"page"},{"location":"Experimental/AlgebraicStatistics/graphical_models/","page":"Graphical Models","title":"Graphical Models","text":"Many basic functions are defined for all graphical models M such as","category":"page"},{"location":"Experimental/AlgebraicStatistics/graphical_models/","page":"Graphical Models","title":"Graphical Models","text":"graph(M) refers to the associated graph\nring(M) to the multivariate polynomial ring where the model resides\nparam_ring to the multivariate polynomial ring where the parameters reside\nparam_gens to the parameters of the model which are ring variables stored typically stored in a hash table for convienent indexing","category":"page"},{"location":"Experimental/AlgebraicStatistics/graphical_models/","page":"Graphical Models","title":"Graphical Models","text":"This part of OSCAR also includes some basic graph functionality such as finding the vertices of a graph or its set of maximal cliques. Lastly, while many methods for graphical models depend heavily on whether or not they are discrete/Gaussian or directed/undirected some funcionality is independent of this and thus implemented simulataneously for all graphical models. For example, the vanishing ideal of the model:","category":"page"},{"location":"Experimental/AlgebraicStatistics/graphical_models/","page":"Graphical Models","title":"Graphical Models","text":"vanishing_ideal(M::GraphicalModel)","category":"page"},{"location":"Experimental/AlgebraicStatistics/graphical_models/#vanishing_ideal-Tuple{GraphicalModel}","page":"Graphical Models","title":"vanishing_ideal","text":"vanishing_ideal(M::GraphicalModel)\n\nComputes the vanishing ideal for a graphical model M. This is done by computing the kernel of the parametrization.\n\nExamples\n\njulia> M = graphical_model(graph_from_edges(Directed, [[1,2], [2,3]]), gaussian_ring(3))\nGaussian graphical model on a directed graph with edges:\n(1, 2), (2, 3)\n\njulia> vanishing_ideal(M)\nIdeal generated by\n -s[1, 2]*s[2, 3] + s[1, 3]*s[2, 2]\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Groups/tom/","page":"Tables of Marks","title":"Tables of Marks","text":"CurrentModule = Oscar\nDocTestSetup = Oscar.doctestsetup()","category":"page"},{"location":"Groups/tom/#Tables-of-Marks","page":"Tables of Marks","title":"Tables of Marks","text":"","category":"section"},{"location":"Groups/tom/","page":"Tables of Marks","title":"Tables of Marks","text":"The concept of a Table of Marks was introduced by W. Burnside in his book Theory of Groups of Finite Order [Bur55]. Therefore a table of marks is sometimes called a Burnside matrix. The table of marks of a finite group G is a matrix whose rows and columns are labelled by the conjugacy classes of subgroups of G and where for two subgroups H and K the (H K)-entry is the number of fixed points of K in the transitive action of G on the cosets of H in G. So the table of marks characterizes the set of all permutation representations of G. Moreover, the table of marks gives a compact description of the subgroup lattice of G, since from the numbers of fixed points the numbers of conjugates of a subgroup K contained in a subgroup H can be derived.","category":"page"},{"location":"Groups/tom/","page":"Tables of Marks","title":"Tables of Marks","text":"For small groups the table of marks of G can be constructed directly by first computing the entire subgroup lattice of G, see table_of_marks(G::Union{GAPGroup, FinGenAbGroup}). Besides that, the Table of Marks library [MNP24] provides access to several hundred tables of marks of simple groups and maximal subgroups of simple groups. These tables of marks can be fetched via the names of these groups, which coincide with the names of the character tables of these groups in the Character Table Library, see table_of_marks(id::String).","category":"page"},{"location":"Groups/tom/","page":"Tables of Marks","title":"Tables of Marks","text":"Like the library of character tables, the library of tables of marks can be used similar to group libraries (see Group libraries) in the sense that all_table_of_marks_names returns descriptions of all those available tables of marks that have certain properties.","category":"page"},{"location":"Groups/tom/#Construct-tables-of-marks","page":"Tables of Marks","title":"Construct tables of marks","text":"","category":"section"},{"location":"Groups/tom/","page":"Tables of Marks","title":"Tables of Marks","text":"GAPGroupTableOfMarks\ntable_of_marks(G::Union{GAPGroup, FinGenAbGroup})\ntable_of_marks(id::String)\nBase.show(io::IO, ::MIME\"text/plain\", tom::GAPGroupTableOfMarks)\nall_table_of_marks_names\nis_table_of_marks_name","category":"page"},{"location":"Groups/tom/#GAPGroupTableOfMarks","page":"Tables of Marks","title":"GAPGroupTableOfMarks","text":"GAPGroupTableOfMarks <: GroupTableOfMarks\n\nThis is the type of tables of marks that can delegate tasks to an underlying table of marks object in the GAP system (field GAPTable).\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 GAPGroupTableOfMarks support get_attribute.\n\n\n\n\n\n","category":"type"},{"location":"Groups/tom/#table_of_marks-Tuple{Union{FinGenAbGroup, Oscar.GAPGroup}}","page":"Tables of Marks","title":"table_of_marks","text":"table_of_marks(G::GAPGroup)\n\nReturn the table of marks of the finite group G.\n\nExamples\n\njulia> show(stdout, MIME(\"text/plain\"), table_of_marks(symmetric_group(3)))\nTable of marks of Sym(3)\n\n1: 6 \n2: 3 1 \n3: 2 . 2 \n4: 1 1 1 1\n\n\n\n\n\n","category":"method"},{"location":"Groups/tom/#table_of_marks-Tuple{String}","page":"Tables of Marks","title":"table_of_marks","text":"table_of_marks(id::String)\n\nReturn the table of marks for which id is an admissible name in GAP's library of tables of marks. If no such table is available then nothing is returned.\n\nExamples\n\njulia> println(table_of_marks(\"A5\"))\ntable of marks of A5\n\njulia> println(table_of_marks(\"J5\"))\nnothing\n\n\n\n\n\n","category":"method"},{"location":"Groups/tom/#show-Tuple{IO, MIME{Symbol(\"text/plain\")}, Oscar.GAPGroupTableOfMarks}","page":"Tables of Marks","title":"show","text":"Base.show(io::IO, ::MIME\"text/plain\", tom::GAPGroupTableOfMarks)\n\nDisplay the marks of tom and context information as a two-dimensional array.\n\nFirst a header is shown. If tom stores a group then the header describes this group, otherwise it is equal to the identifier(tom::GAPGroupTableOfMarks) value of tom.\nThen the matrix of marks of tom is shown in column portions that fit on the screen, together with row labels (the number i for the i-th row) on the left of each portion.\n\nOutput in LaTeX syntax can be created by calling show with second argument MIME(\"text/latex\").\n\nExamples\n\njulia> tom = table_of_marks(\"A5\");\n\njulia> show(stdout, MIME(\"text/plain\"), tom)\nA5\n\n1: 60 \n2: 30 2 \n3: 20 . 2 \n4: 15 3 . 3 \n5: 12 . . . 2 \n6: 10 2 1 . . 1 \n7: 6 2 . . 1 . 1 \n8: 5 1 2 1 . . . 1 \n9: 1 1 1 1 1 1 1 1 1\n\n\n\n\n\n","category":"method"},{"location":"Groups/tom/#all_table_of_marks_names","page":"Tables of Marks","title":"all_table_of_marks_names","text":"all_table_of_marks_names(L...; ordered_by = nothing)\n\nReturn a vector of strings that contains an admissible name of each table of marks in the library of tables of marks that satisfies the conditions in the vector L.\n\nThe supported conditions in L are the same as for all_character_table_names, and the returned vector contains the subset of those names returned by all_character_table_names with the same input for which a table of marks is available in the library.\n\nExamples\n\njulia> spor_names = all_table_of_marks_names(is_sporadic_simple => true);\n\njulia> println(spor_names[1:5])\n[\"Co3\", \"HS\", \"He\", \"J1\", \"J2\"]\n\njulia> spor_names = all_table_of_marks_names(is_sporadic_simple;\n ordered_by = order);\n\njulia> println(spor_names[1:5])\n[\"M11\", \"M12\", \"J1\", \"M22\", \"J2\"]\n\njulia> length(all_table_of_marks_names(number_of_conjugacy_classes => 5))\n4\n\n\n\n\n\n","category":"function"},{"location":"Groups/tom/#is_table_of_marks_name","page":"Tables of Marks","title":"is_table_of_marks_name","text":"is_table_of_marks_name(name::String)\n\nReturn true if table_of_marks(name) returns a table of marks, and false otherwise\n\nExamples\n\njulia> is_table_of_marks_name(\"J1\")\ntrue\n\njulia> is_table_of_marks_name(\"J4\")\nfalse\n\n\n\n\n\n","category":"function"},{"location":"Groups/tom/#Attributes-and-operations-for-tables-of-marks","page":"Tables of Marks","title":"Attributes and operations for tables of marks","text":"","category":"section"},{"location":"Groups/tom/","page":"Tables of Marks","title":"Tables of Marks","text":"class_lengths(tom::GAPGroupTableOfMarks)\nidentifier(tom::GAPGroupTableOfMarks)\norder(tom::GAPGroupTableOfMarks)\norders_class_representatives(tom::GAPGroupTableOfMarks)\nrepresentative(tom::GAPGroupTableOfMarks, i::Int)","category":"page"},{"location":"Groups/tom/#class_lengths-Tuple{Oscar.GAPGroupTableOfMarks}","page":"Tables of Marks","title":"class_lengths","text":"class_lengths(tom::GAPGroupTableOfMarks)\n\nReturn the vector of the lengths of the conjugacy classes of subgroups for tom.\n\nExamples\n\njulia> println(class_lengths(table_of_marks(\"A5\")))\nZZRingElem[1, 15, 10, 5, 6, 10, 6, 5, 1]\n\n\n\n\n\n","category":"method"},{"location":"Groups/tom/#identifier-Tuple{Oscar.GAPGroupTableOfMarks}","page":"Tables of Marks","title":"identifier","text":"identifier(tom::GAPGroupTableOfMarks)\n\nReturn a string that identifies tom if tom belongs to the library of tables of marks, and an empty string otherwise.\n\nExamples\n\njulia> identifier(table_of_marks(\"A5\"))\n\"A5\"\n\njulia> identifier(table_of_marks(symmetric_group(3)))\n\"\"\n\nwarning: Note:\nThe identifier of a table of marks from the library is equal to the identifier of the corresponding library character table. In a few cases, this value differs from the GAP.Globals.Identifier value of the underlying GapObj of the table of marks.\n\n\n\n\n\n","category":"method"},{"location":"Groups/tom/#order-Tuple{Oscar.GAPGroupTableOfMarks}","page":"Tables of Marks","title":"order","text":"order(::Type{T} = ZZRingElem, tom::GAPGroupTableOfMarks) where T <: IntegerUnion\n\nReturn the order of the group for which tom is the table of marks, as an instance of T.\n\nExamples\n\njulia> order(table_of_marks(symmetric_group(4)))\n24\n\n\n\n\n\n","category":"method"},{"location":"Groups/tom/#orders_class_representatives-Tuple{Oscar.GAPGroupTableOfMarks}","page":"Tables of Marks","title":"orders_class_representatives","text":"orders_class_representatives(tom::GAPGroupTableOfMarks)\n\nReturn the vector of the orders of conjugacy class representatives for tom, ordered according to the rows and columns of tom.\n\nExamples\n\njulia> println(orders_class_representatives(table_of_marks(\"A5\")))\nZZRingElem[1, 2, 3, 4, 5, 6, 10, 12, 60]\n\n\n\n\n\n","category":"method"},{"location":"Groups/tom/#representative-Tuple{Oscar.GAPGroupTableOfMarks, Int64}","page":"Tables of Marks","title":"representative","text":"representative(tom::GAPGroupTableOfMarks, i::Int)\n\nReturn a representative from the i-th class of subgroups of tom.\n\nAn exception is thrown if tom does not store a group, or if i is larger than length(tom).\n\nExamples\n\njulia> representative(table_of_marks(\"A5\"), 2)\nPermutation group of degree 5 and order 2\n\n\n\n\n\n","category":"method"},{"location":"Groups/tom/#Marks-vectors","page":"Tables of Marks","title":"Marks vectors","text":"","category":"section"},{"location":"Groups/tom/","page":"Tables of Marks","title":"Tables of Marks","text":"The mathbb Z-linear combinations of the rows of the table of marks of the group G can be interpreted as elements of the integral Burnside ring of G: The rows of the table represent the isomorphism classes of transitive G-sets, the sum of two rows represents the isomorphism class of the disjoint union of the two G-sets, and the pointwise product of two rows represents the isomorphism class of the Cartesian product of the two G-sets. The coefficients of the decomposition of a linear combination of rows can be computed by coordinates(chi::GAPGroupMarksVector).","category":"page"},{"location":"Groups/tom/","page":"Tables of Marks","title":"Tables of Marks","text":"The rows of a table of marks and their mathbb Z-linear combinations are implemented as marks vector objects, with parent the table of marks.","category":"page"},{"location":"Groups/tom/","page":"Tables of Marks","title":"Tables of Marks","text":"length and iteration:","category":"page"},{"location":"Groups/tom/","page":"Tables of Marks","title":"Tables of Marks","text":"The length of a marks vector is the number of columns of the table of marks. iteration is defined w.r.t. the ordering of columns.","category":"page"},{"location":"Groups/tom/","page":"Tables of Marks","title":"Tables of Marks","text":"arithmetic operations:","category":"page"},{"location":"Groups/tom/","page":"Tables of Marks","title":"Tables of Marks","text":"chi == psi: two marks vectors are equal if and only if they belong to the same table of marks and have the same values,\nchi + psi and chi - psi are the pointwise sum and difference, respectively, of the two marks vectors chi, psi,\nn * chi is the pointwise n-fold sum of chi, for an integer n,\nchi * psi is the pointwise product of chi and psi,\nzero(chi) is the marks vector that is zero on all classes,\none(chi) is the all-one marks vector, corresponding to the G-set that consists of one point,\nchi^n is the n-th power of chi, for positive integers n.","category":"page"},{"location":"Groups/tom/","page":"Tables of Marks","title":"Tables of Marks","text":"coordinates(chi::GAPGroupMarksVector)\nrestrict(chi::GAPGroupMarksVector, tbl::GAPGroupCharacterTable)","category":"page"},{"location":"Groups/tom/#coordinates-Tuple{Oscar.GAPGroupMarksVector}","page":"Tables of Marks","title":"coordinates","text":"coordinates(::Type{T} = ZZRingElem, chi::GAPGroupMarksVector)\n where T <: Union{IntegerUnion, QQFieldElem}\n\nReturn the vector a_1 a_2 ldots a_n such that chi is equal to sum_i=1^n a_i ti where t is parent(chi).\n\nThe result is an instance of Vector{T}. Note that the result can be shorter than ncols(parent(chi)).\n\nExamples\n\njulia> tom = table_of_marks(symmetric_group(4));\n\njulia> chi = tom[3] * tom[6]\nmarks_vector(table of marks of Sym(4), ZZRingElem[72, 0, 4])\n\njulia> println(coordinates(Int, chi))\n[2, 0, 2]\n\n\n\n\n\n","category":"method"},{"location":"Groups/tom/#restrict-Tuple{Oscar.GAPGroupMarksVector, Oscar.GAPGroupCharacterTable}","page":"Tables of Marks","title":"restrict","text":"restrict(chi::GAPGroupMarksVector, tbl::GAPGroupCharacterTable)\n\nReturn the class function with parent tbl that is the restriction of chi. For that, parent(chi) and tbl must belong to the same group G.\n\nIf chi is the i-th row in the table of marks parent(chi) then the result is the permutation character of the action of G on the right cosets of its subgroup representative(parent(chi), i).\n\nExamples\n\njulia> tom = table_of_marks(\"A5\"); tbl = character_table(tom);\n\njulia> chi = tom[5]\nmarks_vector(table of marks of A5, ZZRingElem[12, 0, 0, 0, 2])\n\njulia> println(values(restrict(chi, tbl)))\nQQAbFieldElem{AbsSimpleNumFieldElem}[12, 0, 0, 2, 2]\n\n\n\n\n\n","category":"method"},{"location":"Groups/tom/#The-interface-between-tables-of-marks-and-character-tables","page":"Tables of Marks","title":"The interface between tables of marks and character tables","text":"","category":"section"},{"location":"Groups/tom/","page":"Tables of Marks","title":"Tables of Marks","text":"character_table(tom::GAPGroupTableOfMarks)\ntable_of_marks(tbl::GAPGroupCharacterTable)","category":"page"},{"location":"Groups/tom/#character_table-Tuple{Oscar.GAPGroupTableOfMarks}","page":"Tables of Marks","title":"character_table","text":"character_table(tom::GAPGroupTableOfMarks)\n\nReturn the character table of the group of tom. If tom belongs to the library of tables of marks then the corresponding character table from the library of character tables is returned, otherwise the character table of group(tom).\n\nExamples\n\njulia> g = symmetric_group(3); tom = table_of_marks(g);\n\njulia> character_table(tom) == character_table(g)\ntrue\n\n\n\n\n\n","category":"method"},{"location":"Groups/tom/#table_of_marks-Tuple{Oscar.GAPGroupCharacterTable}","page":"Tables of Marks","title":"table_of_marks","text":"table_of_marks(tbl::GAPGroupCharacterTable)\n\nReturn the table of marks of the group of tbl. If tbl does not store a group and if the library of tables of marks contains the table of marks corresponding to tbl then this is returned, otherwise nothing.\n\nExamples\n\njulia> g = symmetric_group(3); tbl = character_table(g);\n\njulia> table_of_marks(tbl) == table_of_marks(g)\ntrue\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.FracFieldElem{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 even lattices with isometry of finite order with at most two prime divisors. This is the content of [BH23] which has been implemented. We guide the user here to the global aspects of the available theory, and we refer to the paper [BH23] 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 some cases, C can be obtained as a primitive extension A oplus 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 [BH23]).","category":"page"},{"location":"Experimental/QuadFormAndIsom/enumeration/","page":"Enumeration of isometries","title":"Enumeration of isometries","text":"We say that a triple (G_A G_B G_C) of genus symbols for integer lattices is p-admissible if there are some lattices A in G_A, B in G_B and C in G_C 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 [BH23] 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; pA::Int = -1,\n nA::Int = -1,\n pB::Int = -1,\n nB::Int = -1,\n b::Int = 0)\n -> 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\nOne can choose the positive signatures for the genera A and B in output respectively by setting pA and pB to the desired values. Similarly with the negative signatures nA and nB. The function returns an error if the choice of these values is inconsistent.\n\nIf b is set to 0, we allow in output the trivial pair, i.e. when B is the genus of rank 0 lattices. Otherwise, if b is set to 1, the trivial pair is discarded.\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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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 [BH23].","category":"page"},{"location":"Experimental/QuadFormAndIsom/enumeration/#The-hermitian-case","page":"Enumeration of isometries","title":"The hermitian case","text":"","category":"section"},{"location":"Experimental/QuadFormAndIsom/enumeration/","page":"Enumeration of isometries","title":"Enumeration of isometries","text":"For an irreducible reciprocal polynomial chi and a genus symbol G of integral integer lattices, if the equation order mathbbZchi is maximal, one can compute representatives of isomorphism classes of lattices with isometry (L f) such that Lin G and chi(f) = 0.","category":"page"},{"location":"Experimental/QuadFormAndIsom/enumeration/","page":"Enumeration of isometries","title":"Enumeration of isometries","text":"representatives_of_hermitian_type(::Union{ZZLat, ZZGenus}, ::Union{ZZPolyRingElem, QQPolyRingElem}, ::Bool)","category":"page"},{"location":"Experimental/QuadFormAndIsom/enumeration/#representatives_of_hermitian_type-Tuple{Union{ZZGenus, ZZLat}, Union{QQPolyRingElem, ZZPolyRingElem}, Bool}","page":"Enumeration of isometries","title":"representatives_of_hermitian_type","text":"representatives_of_hermitian_type(G::ZZGenus, chi::Union{ZZPolyRingElem, QQPolyRingElem}; first::Bool=false)\nrepresentatives_of_hermitian_type(L::ZZLat, chi::Union{ZZPolyRingElem, QQPolyRingElem}; first::Bool=false)\n -> Vector{ZZLatWithIsom}\n\nGiven a non-empty genus of integer lattices G and a polynomial chi irreducible over mathbb Q, such that the equation order of the associated number field is maximal, return a list of representatives of isomorphism classes of pairs (M g) consiting of a lattice M in G and g in O(M) is an isometry of minimal polynomial chi.\n\nOne can also provide a representative L of G instead.\n\nIf first is set to true, only return the first representative computed.\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/enumeration/","page":"Enumeration of isometries","title":"Enumeration of isometries","text":"In the case of finite order isometries, when chi is cyclotomic, one can use as a shortcut the following function instead:","category":"page"},{"location":"Experimental/QuadFormAndIsom/enumeration/","page":"Enumeration of isometries","title":"Enumeration of isometries","text":"representatives_of_hermitian_type(::Union{ZZGenus, ZZLat}, ::Int, ::Bool)","category":"page"},{"location":"Experimental/QuadFormAndIsom/enumeration/#representatives_of_hermitian_type-Tuple{Union{ZZGenus, ZZLat}, Int64, Bool}","page":"Enumeration of isometries","title":"representatives_of_hermitian_type","text":"representatives_of_hermitian_type(G::ZZGenus, m::Int; first::Bool=false)\nrepresentatives_of_hermitian_type(L::ZZLat, m::Int; first::Bool=false)\n -> Vector{ZZLatWithIsom}\n\nGiven a non-empty genus of integer lattices G, return a list of representatives of isomorphism classes of pairs (M g) consisting of a lattice M in G and g in O(M) is an isometry of minimal polynomial Phi_m(X), the m-th cyclotomic polynomial.\n\nIf m = 12, this goes back to enumerate G as a genus of integer lattices.\n\nOne can also provide a representative L of G instead.\n\nIf first is set to true, only return the first representative computed.\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/enumeration/#Orders-with-two-prime-divisors","page":"Enumeration of isometries","title":"Orders with two prime divisors","text":"","category":"section"},{"location":"Experimental/QuadFormAndIsom/enumeration/","page":"Enumeration of isometries","title":"Enumeration of isometries","text":"As we will see later, the algorithms from [BH23] 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)\nenumerate_prime_power_isometries(::ZZLat, ::IntegerUnion, ::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 even 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 even 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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/enumeration/#enumerate_prime_power_isometries-Tuple{ZZLat, Union{Integer, ZZRingElem}, Union{Integer, ZZRingElem}}","page":"Enumeration of isometries","title":"enumerate_prime_power_isometries","text":"enumerate_prime_power_isometries(L::ZZLat, q::IntegerUnion, vq::IntegerUnion) -> Vector{ZZLatWithIsom}\nenumerate_prime_power_isometries(G::ZZGenus, q::IntegerUnion, vq::IntegerUnion) -> Vector{ZZLatWithIsom}\n\nGiven a genus G of even integer lattices, or a representative L of G, return representatives of isomorphism classes of lattices with isometry (M g) where M is a lattice in G and g has order q^vq.\n\nq must be a prime number and vq must be a positive integer.\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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 [BH23] used previously to enumerate lattices with isometry. The following correspond respectively to Algorithms 3, 4, 5, 6 and 7 of the aforementioned paper:","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 finite 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 (M g) of finite hermitian type such that the type of (M g^m) is equal to the type of (L f).\n\nNote 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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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 an even 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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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 an even 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 has 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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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 an even 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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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 an even lattice with isometry (L f) and a prime number p such that f has 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 has order p^d+1q^e.\n\nNote that d and e can be both 0.\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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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 [BH23] 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_extensions (Algorithm 2 in [BH23]) 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 = Oscar.doctestsetup()","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)\ncanonical_injection(G::DirectProductGroup, j::Int)\ncanonical_injections(G::DirectProductGroup)\ncanonical_projection(G::DirectProductGroup, j::Int)\ncanonical_projections(G::DirectProductGroup)\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(3)\n\njulia> K = symmetric_group(2)\nSym(2)\n\njulia> G = direct_product(H,K)\nDirect product of\n Sym(3)\n Sym(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,3,2)\n (1,3,2)(4,5)\n (1,3)\n (1,3)(4,5)\n (1,2,3)\n (1,2,3)(4,5)\n (1,2)\n (1,2)(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, SubPcGroup, FPGroup, SubFPGroup.\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/#canonical_injection-Tuple{DirectProductGroup, Int64}","page":"Products of groups","title":"canonical_injection","text":"canonical_injection(G::DirectProductGroup, j::Int)\n\nReturn the injection of the j-th component of G into G, for j = 1,...,#factors of G. It is not defined for proper subgroups of direct products.\n\nExamples\n\njulia> H = symmetric_group(3)\nSym(3)\n\njulia> K = symmetric_group(2)\nSym(2)\n\njulia> G = direct_product(H, K)\nDirect product of\n Sym(3)\n Sym(2)\n\njulia> inj1 = canonical_injection(G, 1)\nGroup homomorphism\n from Sym(3)\n to direct product of\n Sym(3)\n Sym(2)\n\njulia> h = perm(H, [2,3,1])\n(1,2,3)\n\njulia> inj1(h)\n(1,2,3)\n\njulia> inj2 = canonical_injection(G, 2)\nGroup homomorphism\n from Sym(2)\n to direct product of\n Sym(3)\n Sym(2)\n\njulia> k = perm(K, [2,1])\n(1,2)\n\njulia> inj2(k)\n(4,5)\n\njulia> inj1(h)*inj2(k)\n(1,2,3)(4,5)\n\n\n\n\n\n","category":"method"},{"location":"Groups/products/#canonical_injections-Tuple{DirectProductGroup}","page":"Products of groups","title":"canonical_injections","text":"canonical_injections(G::DirectProductGroup)\n\nReturn the injection of the j-th component of G into G, for all j = 1,...,#factors of G. It is not defined for proper subgroups of direct products.\n\n\n\n\n\n","category":"method"},{"location":"Groups/products/#canonical_projection-Tuple{DirectProductGroup, Int64}","page":"Products of groups","title":"canonical_projection","text":"canonical_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(3)\n\njulia> K = symmetric_group(2)\nSym(2)\n\njulia> G = direct_product(H, K)\nDirect product of\n Sym(3)\n Sym(2)\n\njulia> proj1 = canonical_projection(G, 1)\nGroup homomorphism\n from direct product of\n Sym(3)\n Sym(2)\n to Sym(3)\n\njulia> proj2 = canonical_projection(G, 2)\nGroup homomorphism\n from direct product of\n Sym(3)\n Sym(2)\n to Sym(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/#canonical_projections-Tuple{DirectProductGroup}","page":"Products of groups","title":"canonical_projections","text":"canonical_projection(G::DirectProductGroup)\n\nReturn the projection of G into the j-th component of G, for all j = 1,...,#factors of G.\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)\ncanonical_injection(G::SemidirectProductGroup, n::Int)\ncanonical_projection(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/#canonical_injection-Tuple{SemidirectProductGroup, Int64}","page":"Products of groups","title":"canonical_injection","text":"canonical_injection(G::SemidirectProductGroup, n::Int)\n\nReturn the injection 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/#canonical_projection-Tuple{SemidirectProductGroup}","page":"Products of groups","title":"canonical_projection","text":"canonical_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)\ncanonical_projection(W::WreathProductGroup)\ncanonical_injection(W::WreathProductGroup, n::Int)\ncanonical_injections(W::WreathProductGroup)","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\nW(g_1,...,g_n, h).\n\nExamples\n\njulia> G = cyclic_group(3)\nPc group of order 3\n\njulia> H = symmetric_group(2)\nSym(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)\nPc group of order 3\n\njulia> H = symmetric_group(2)\nSym(2)\n\njulia> W = wreath_product(G,H)\n\n\njulia> normal_subgroup(W)\nPc group of order 3\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)\nPc group of order 3\n\njulia> H = symmetric_group(2)\nSym(2)\n\njulia> W = wreath_product(G,H)\n\n\njulia> acting_subgroup(W)\nSym(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/#canonical_projection-Tuple{WreathProductGroup}","page":"Products of groups","title":"canonical_projection","text":"canonical_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/#canonical_injection-Tuple{WreathProductGroup, Int64}","page":"Products of groups","title":"canonical_injection","text":"canonical_injection(G::WreathProductGroup, n::Int)\n\nReturn the injection of the n-th component of G into G. It is not defined for proper subgroups of wreath products.\n\n\n\n\n\n","category":"method"},{"location":"Groups/products/#canonical_injections-Tuple{WreathProductGroup}","page":"Products of groups","title":"canonical_injections","text":"canonical_injections(G::WreathProductGroup)\n\nReturn the injection of the n-th component of G into G for all n. It is not defined for proper subgroups of wreath products.\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":"flag_pluecker_ideal\ngrassmann_pluecker_ideal","category":"page"},{"location":"AlgebraicGeometry/Miscellaneous/miscellaneous/#flag_pluecker_ideal","page":"Some Special Ideals","title":"flag_pluecker_ideal","text":"flag_pluecker_ideal(F::Union{Field, MPolyRing}, dimensions::Vector{Int}, n::Int; minimal::Bool=true)\n\nReturns the generators of the defining ideal for the complete flag variety textFl(mathbbF (d_1dotsd_k) n), where (d_1dotsd_k) =dimensions, with d_jleq n-1, denotes the rank. That is, the vanishing set of this ideal corresponds to the space of k-step flags of linear subspaces V_1subsetdotssubset V_k in mathbbF^n, where textdim(V_j) = d_j. You can obtain the generators for the complete flag variety of mathbbF^n by taking dimensions =(1dotsn-1) and n=n. We remark that evaluating for F = QQ yields the same set of generators as any field of characteristic 0.\n\nThe first parameter can either be mathbbF, or a polynomial ring over mathbbF, with sum^k_j=1nchoose d_j variables. The parameter dimensions needs to be a vector of distinct increasing entries. Evaluating this function with the parameter minimal = true returns the reduced Gröbner basis for the flag Plücker ideal with respect to the degree reverse lexicographical order. For more details, see Theorem 14.6 [MS05]\n\nExamples\n\nComplete flag variety textFl(mathbbQ (123) 4). \n\njulia> flag_pluecker_ideal(QQ,[1,2,3],4)\nIdeal generated by\n x[[2, 4]]*x[[1, 2, 3]] - x[[2, 3]]*x[[1, 2, 4]] + x[[1, 2]]*x[[2, 3, 4]]\n x[[1, 4]]*x[[1, 2, 3]] - x[[1, 3]]*x[[1, 2, 4]] + x[[1, 2]]*x[[1, 3, 4]]\n -x[[3, 4]]*x[[1, 2, 3]] - x[[1, 3]]*x[[2, 3, 4]] + x[[2, 3]]*x[[1, 3, 4]]\n -x[[1, 4]]*x[[2, 3, 4]] + x[[2, 4]]*x[[1, 3, 4]] - x[[3, 4]]*x[[1, 2, 4]]\n -x[[1]]*x[[2, 3, 4]] + x[[2]]*x[[1, 3, 4]] - x[[3]]*x[[1, 2, 4]] + x[[4]]*x[[1, 2, 3]]\n -x[[1, 4]]*x[[2, 3]] + x[[2, 4]]*x[[1, 3]] - x[[3, 4]]*x[[1, 2]]\n -x[[1]]*x[[2, 3]] + x[[2]]*x[[1, 3]] - x[[3]]*x[[1, 2]]\n -x[[2]]*x[[3, 4]] + x[[3]]*x[[2, 4]] - x[[4]]*x[[2, 3]]\n -x[[1]]*x[[3, 4]] + x[[3]]*x[[1, 4]] - x[[4]]*x[[1, 3]]\n -x[[1]]*x[[2, 4]] + x[[2]]*x[[1, 4]] - x[[4]]*x[[1, 2]]\n\n\nFlag variety textFl(mathbbQ(13)4).\n\njulia> flag_pluecker_ideal(QQ,[1,3],4)\nIdeal generated by\n -x[[1]]*x[[2, 3, 4]] + x[[2]]*x[[1, 3, 4]] - x[[3]]*x[[1, 2, 4]] + x[[4]]*x[[1, 2, 3]]\n\nAn example with a custom ring as input.\n\njulia> R, _ = polynomial_ring(QQ, 8)\n(Multivariate polynomial ring in 8 variables over QQ, QQMPolyRingElem[x1, x2, x3, x4, x5, x6, x7, x8])\n\njulia> flag_pluecker_ideal(R, [1,3], 4; minimal=false)\nIdeal generated by\n x1*x6 - x2*x5 + x3*x7 - x4*x8\n\n\n\n\n\n","category":"function"},{"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 (possibly graded) ring, an ambient dimension n and a subspace dimension d, return the ideal in the ring generated by the Plücker relations. If the input ring is not graded, return the ideal in the ring with the standard grading. If the ring is not specified return the ideal in a multivariate polynomial ring over the rationals with variables indexed by elements of nchoose d with the standard grading.\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 [Stu93].\n\nExamples\n\njulia> grassmann_pluecker_ideal(2, 4)\nIdeal generated by\n x[[1, 2]]*x[[3, 4]] - x[[1, 3]]*x[[2, 4]] + x[[1, 4]]*x[[2, 3]]\n\njulia> R, x = polynomial_ring(residue_ring(ZZ, 7)[1], :x => (1:2, 1:3))\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 generated by\n x[1, 1]*x[2, 3] + 6*x[2, 1]*x[1, 3] + x[1, 2]*x[2, 2]\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":"Groups/permgroup/","page":"Permutation groups","title":"Permutation groups","text":"CurrentModule = Oscar\nDocTestSetup = Oscar.doctestsetup()","category":"page"},{"location":"Groups/permgroup/#Permutation-groups","page":"Permutation groups","title":"Permutation groups","text":"","category":"section"},{"location":"Groups/permgroup/#Constructing-permutation-groups","page":"Permutation groups","title":"Constructing 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\nalternating_group\npermutation_group\n@permutation_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(5)\n\njulia> x=cperm([1,2,3])\n(1,2,3)\n\njulia> parent(x)\nSym(3)\n\njulia> y=G(x)\n(1,2,3)\n\njulia> parent(y)\nSym(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(6)\n\njulia> x = G([2,4,6,1,3,5])\n(1,2,4)(3,6,5)\n\njulia> parent(x)\nSym(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(5)\n\njulia> order(G)\n120\n\n\n\n\n\n\n","category":"function"},{"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(5)\n\njulia> order(G)\n60\n\n\n\n\n\n\n","category":"function"},{"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])\nPermutation group of degree 5\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))\nPermutation group of degree 7\n\njulia> degree(g)\n7\n\n\n\n\n\n","category":"macro"},{"location":"Groups/permgroup/","page":"Permutation groups","title":"Permutation groups","text":"projective_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/#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)\nPermutation group of degree 4 and order 24\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)\nPermutation group of degree 4 and order 12\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)\nPermutation group of degree 4 and order 12\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)\nPermutation group of degree 10 and order 24\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)\nPermutation group of degree 10 and order 12\n\njulia> order(g)\n12\n\n\n\n\n\n","category":"function"},{"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":"All operations, properties and attributes for general groups described in the previous sections are supported for permutation groups. In addition there are some specific to permutation groups.","category":"page"},{"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)\nsmaller_degree_permutation_representation(G::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.\nOne can use the syntax G(H) in order to get a group that consists of the same permutations as H but has the same degree as G, provided that the elements of H move only points up to degree(G).\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> s4 = symmetric_group(4);\n\njulia> degree(s4)\n4\n\njulia> t4 = trivial_subgroup(symmetric_group(4))[1];\n\njulia> degree(t4)\n4\n\njulia> t5 = trivial_subgroup(symmetric_group(5))[1];\n\njulia> t4 == t5\nfalse\n\njulia> t4 == s4(t5)\ntrue\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/#smaller_degree_permutation_representation-Tuple{PermGroup}","page":"Permutation groups","title":"smaller_degree_permutation_representation","text":"smaller_degree_permutation_representation(G::PermGroup) -> PermGroup, map\n\nReturn an isomorphic permutation group of smaller or equal degree and the isomorphism from G to that group.\n\nExamples\n\njulia> g = symmetric_group(4);\n\njulia> s, _ = sylow_subgroup(g, 3);\n\njulia> rho = smaller_degree_permutation_representation(s)\n(Permutation group of degree 3 and order 3, Hom: s -> permutation group)\n\n\n\n\n\n","category":"method"},{"location":"Groups/permgroup/","page":"Permutation groups","title":"Permutation groups","text":"The following functions deal with the natural action of a given permutation group G.","category":"page"},{"location":"Groups/permgroup/","page":"Permutation groups","title":"Permutation groups","text":"is_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/#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","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, map(representative, maximal_subgroup_classes(G)))\n3-element Vector{PermGroup}:\n Permutation group of degree 6 and order 24\n Permutation group of degree 6 and order 36\n Permutation group of degree 6 and order 60\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","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]\nPermutation group of degree 6\n\njulia> is_regular(H)\ntrue\n\njulia> is_regular(G)\nfalse\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]\nPermutation group of degree 6\n\njulia> is_semiregular(H)\ntrue\n\njulia> is_regular(H)\nfalse\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 [Cam99] 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]\nPermutation group of degree 4 and order 8\n\njulia> rank_action(H) # not 2-transitive\n3\n\njulia> K = stabilizer(G, 1)[1]\nPermutation group of degree 4 and order 6\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]\nPermutation group of degree 4 and order 8\n\njulia> collect(blocks(g))\n2-element Vector{Vector{Int64}}:\n [1, 2]\n [3, 4]\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)\nPermutation group of degree 8\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","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)\nPermutation group of degree 8\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","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)\nPermutation group of degree 8\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","category":"method"},{"location":"Groups/permgroup/","page":"Permutation groups","title":"Permutation groups","text":"The following functions allow efficiently \"recognizing\" certain permutation groups as alternating or symmetric groups.","category":"page"},{"location":"Groups/permgroup/","page":"Permutation groups","title":"Permutation groups","text":"is_natural_symmetric_group(G::GAPGroup)\nis_isomorphic_to_symmetric_group(G::GAPGroup)\nis_natural_alternating_group(G::GAPGroup)\nis_isomorphic_to_alternating_group(G::GAPGroup)","category":"page"},{"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_to_symmetric_group-Tuple{Oscar.GAPGroup}","page":"Permutation groups","title":"is_isomorphic_to_symmetric_group","text":"is_isomorphic_to_symmetric_group(G::GAPGroup)\n\nReturn true if G is isomorphic to a symmetric group, and false otherwise.\n\n\n\n\n\n","category":"method"},{"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_to_alternating_group-Tuple{Oscar.GAPGroup}","page":"Permutation groups","title":"is_isomorphic_to_alternating_group","text":"is_isomorphic_to_alternating_group(G::GAPGroup)\n\nReturn true if G is isomorphic to an alternating group, and false otherwise.\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(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(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(5)\n\njulia> x = cperm(G,[[1,2],[3,4]])\n(1,2)(3,4)\n\njulia> parent(x)\nSym(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(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(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)\ncycles(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/#cycles-Tuple{PermGroupElem}","page":"Permutation groups","title":"cycles","text":"cycles(g::PermGroupElem)\n\nReturn all cycles (including trivial ones) of the permutation g as a sorted list of integer vectors.\n\nExamples\n\njulia> g = cperm(1:3, 6:7, 8:10, 11:15)\n(1,2,3)(6,7)(8,9,10)(11,12,13,14,15)\n\njulia> cycles(g)\n6-element Vector{Vector{Int64}}:\n [1, 2, 3]\n [4]\n [5]\n [6, 7]\n [8, 9, 10]\n [11, 12, 13, 14, 15]\n\njulia> g = cperm()\n()\n\njulia> cycles(g)\n1-element Vector{Vector{Int64}}:\n [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/#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":"Groups/permgroup/","page":"Permutation groups","title":"Permutation groups","text":"cycle_structures(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":"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.FracFieldElem{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, m::ZZRingElem)\nreconstruct(a::ZZRingElem, m::Integer)\nreconstruct(a::Integer, m::ZZRingElem)\nreconstruct(a::Integer, m::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/","page":"Fraction fields","title":"Fraction fields","text":"reconstruct(::ZZRingElem, ::ZZRingElem, ::ZZRingElem, ::ZZRingElem)","category":"page"},{"location":"Nemo/fraction/#reconstruct-NTuple{4, ZZRingElem}","page":"Fraction fields","title":"reconstruct","text":"reconstruct(a::ZZRingElem, m::ZZRingElem, N::ZZRingElem, D::ZZRingElem)\n\nAttempt to return a rational number nd such that 0 leq n leq N and 0 d leq D such that 2 N D m, gcd(n d) = 1, and a equiv nd^-1 pmodm.\n\nReturns a tuple (success, n/d), where success signals the success of reconstruction.\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 non-negative 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 non-negative 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 non-negative 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":"TropicalGeometry/variety/#Tropical-varieties","page":"Tropical varieties","title":"Tropical varieties","text":"","category":"section"},{"location":"TropicalGeometry/variety/#Introduction","page":"Tropical varieties","title":"Introduction","text":"","category":"section"},{"location":"TropicalGeometry/variety/","page":"Tropical varieties","title":"Tropical varieties","text":"Tropial varieties (in OSCAR) are weighted polyhedral complexes. They may arise as tropicalizations of polynomial ideals or from operations on the more specialized types of tropical varieties, such as the stable intersection of tropical hypersurfaces. For more on the first, see","category":"page"},{"location":"TropicalGeometry/variety/","page":"Tropical varieties","title":"Tropical varieties","text":"Chapter 3 in [MS15]\nChapter 2.8 in [Jos21]","category":"page"},{"location":"TropicalGeometry/variety/#Note:","page":"Tropical varieties","title":"Note:","text":"","category":"section"},{"location":"TropicalGeometry/variety/","page":"Tropical varieties","title":"Tropical varieties","text":"Objects of type TropicalVariety need to be embedded, abstract tropical varieties are currently not supported.\nThe type TropicalVariety can be thought of as supertype of TropicalHypersurface, TropicalCurve, and TropicalLinearSpace in the sense that the latter three should have all properties and features of the former.\nEmbedded tropical varieties are polyhedral complexes with multiplicities and should have all properties of polyhedral complexes","category":"page"},{"location":"TropicalGeometry/variety/#Constructor","page":"Tropical varieties","title":"Constructor","text":"","category":"section"},{"location":"TropicalGeometry/variety/","page":"Tropical varieties","title":"Tropical varieties","text":"Objects of type TropicalVariety can be constructed as follows:","category":"page"},{"location":"TropicalGeometry/variety/","page":"Tropical varieties","title":"Tropical varieties","text":"tropical_variety(Sigma::PolyhedralComplex, mult::Vector{ZZRingElem}, minOrMax::Union{typeof(min),typeof(max)}=min)","category":"page"},{"location":"TropicalGeometry/variety/#tropical_variety","page":"Tropical varieties","title":"tropical_variety","text":"tropical_variety(Sigma::PolyhedralComplex, mult, minOrMax::Union{typeof(min),typeof(max)}=min)\n\nReturn the TropicalVariety whose polyhedral complex is Sigma with multiplicities mult and convention minOrMax. Here, mult is optional can be specified as a Vector{ZZRingElem} which represents a list of multiplicities on the maximal polyhedra in the order of maximal_polyhedra(Sigma). If mult is unspecified, then all multiplicities are set to one.\n\nExamples\n\njulia> Sigma = polyhedral_complex(incidence_matrix([[1],[2]]), [[0],[1]])\nPolyhedral complex in ambient dimension 1\n\njulia> tropical_variety(Sigma)\nMin tropical variety\n\njulia> mult = ones(ZZRingElem, n_maximal_polyhedra(Sigma))\n2-element Vector{ZZRingElem}:\n 1\n 1\n\njulia> tropical_variety(Sigma,mult,min)\nMin tropical variety\n\njulia> mult = ZZ.([1,2])\n2-element Vector{ZZRingElem}:\n 1\n 2\n\njulia> tropical_variety(Sigma,mult,max)\nMax tropical variety\n\n\n\n\n\n\n","category":"function"},{"location":"TropicalGeometry/variety/#Properties","page":"Tropical varieties","title":"Properties","text":"","category":"section"},{"location":"TropicalGeometry/variety/","page":"Tropical varieties","title":"Tropical varieties","text":"Objects of type TropicalVariety (and TropicalHypersurface, TropicalCurve, TropicalLinearSpace) have the following properties:","category":"page"},{"location":"TropicalGeometry/variety/","page":"Tropical varieties","title":"Tropical varieties","text":"polyhedral_complex(TropV::TropicalVariety)\nambient_dim(TropV::TropicalVariety)\ncodim(TropV::TropicalVariety)\ndim(TropV::TropicalVariety)\nf_vector(TropV::TropicalVariety)\nlineality_dim(TropV::TropicalVariety)\nlineality_space(TropV::TropicalVariety)\nmaximal_polyhedra(TropV::TropicalVariety)\nmaximal_polyhedra_and_multiplicities(TropV::TropicalVariety)\nminimal_faces(TropV::TropicalVariety)\nmultiplicities(TropV::TropicalVariety)\nn_maximal_polyhedra(TropV::TropicalVariety)\nn_polyhedra(TropV::TropicalVariety)\nn_vertices(TropV::TropicalVariety)\nis_pure(TropV::TropicalVariety)\nis_simplicial(TropV::TropicalVariety)\nrays(TropV::TropicalVariety)\nrays_modulo_lineality(TropV::TropicalVariety)\nvertices_and_rays(TropV::TropicalVariety)\nvertices(TropV::TropicalVariety)\nvisualize(TropV::TropicalVariety)","category":"page"},{"location":"TropicalGeometry/variety/#polyhedral_complex-Tuple{TropicalVariety}","page":"Tropical varieties","title":"polyhedral_complex","text":"polyhedral_complex(TropV::TropicalVariety)\n\nReturn the polyhedral complex of a tropical variety.\n\n\n\n\n\n","category":"method"},{"location":"TropicalGeometry/variety/#ambient_dim-Tuple{TropicalVariety}","page":"Tropical varieties","title":"ambient_dim","text":"ambient_dim(TropV::TropicalVariety)\n\nSee ambient_dim(::PolyhedralComplex).\n\n\n\n\n\n","category":"method"},{"location":"TropicalGeometry/variety/#codim-Tuple{TropicalVariety}","page":"Tropical varieties","title":"codim","text":"codim(TropV::TropicalVariety)\n\nSee codim(::PolyhedralComplex).\n\n\n\n\n\n","category":"method"},{"location":"TropicalGeometry/variety/#dim-Tuple{TropicalVariety}","page":"Tropical varieties","title":"dim","text":"dim(TropV::TropicalVariety)\n\nSee dim(::PolyhedralComplex).\n\n\n\n\n\n","category":"method"},{"location":"TropicalGeometry/variety/#f_vector-Tuple{TropicalVariety}","page":"Tropical varieties","title":"f_vector","text":"f_vector(TropV::TropicalVariety)\n\nSee f_vector(::PolyhedralComplex).\n\n\n\n\n\n","category":"method"},{"location":"TropicalGeometry/variety/#lineality_dim-Tuple{TropicalVariety}","page":"Tropical varieties","title":"lineality_dim","text":"lineality_dim(TropV::TropicalVariety)\n\nSee lineality_dim(::PolyhedralComplex).\n\n\n\n\n\n","category":"method"},{"location":"TropicalGeometry/variety/#lineality_space-Tuple{TropicalVariety}","page":"Tropical varieties","title":"lineality_space","text":"lineality_space(TropV::TropicalVariety)\n\nSee lineality_space(::PolyhedralComplex).\n\n\n\n\n\n","category":"method"},{"location":"TropicalGeometry/variety/#maximal_polyhedra-Tuple{TropicalVariety}","page":"Tropical varieties","title":"maximal_polyhedra","text":"maximal_polyhedra(TropV::TropicalVariety)\n\nSee maximal_polyhedra(::PolyhedralComplex).\n\n\n\n\n\n","category":"method"},{"location":"TropicalGeometry/variety/#maximal_polyhedra_and_multiplicities-Tuple{TropicalVariety}","page":"Tropical varieties","title":"maximal_polyhedra_and_multiplicities","text":"maximal_polyhedra_and_multiplicities(TropV::TropicalVariety)\n\nReturn the maximal polyhedra and multiplicities of TropV.\n\nExamples\n\njulia> R,(x1,x2) = polynomial_ring(QQ,4);\n\njulia> nu = tropical_semiring_map(QQ,2);\n\njulia> f = 2*x1^2+x1*x2+x2^2+1\n2*x1^2 + x1*x2 + x2^2 + 1\n\njulia> TropH = tropical_hypersurface(f,nu)\nMin tropical hypersurface\n\njulia> maximal_polyhedra_and_multiplicities(TropH)\n5-element Vector{Tuple{Polyhedron{QQFieldElem}, ZZRingElem}}:\n (Polyhedron in ambient dimension 4, 1)\n (Polyhedron in ambient dimension 4, 1)\n (Polyhedron in ambient dimension 4, 2)\n (Polyhedron in ambient dimension 4, 1)\n (Polyhedron in ambient dimension 4, 2)\n\n\n\n\n\n\n","category":"method"},{"location":"TropicalGeometry/variety/#minimal_faces-Tuple{TropicalVariety}","page":"Tropical varieties","title":"minimal_faces","text":"minimal_faces(TropV::TropicalVariety)\n\nSee minimal_faces(::PolyhedralComplex).\n\n\n\n\n\n","category":"method"},{"location":"TropicalGeometry/variety/#multiplicities-Tuple{TropicalVariety}","page":"Tropical varieties","title":"multiplicities","text":"multiplicities(TropV::TropicalVariety)\n\nReturn the multiplicities of TropV. Order is the same as maximal_polyhedra.\n\nExamples\n\njulia> R,(x1,x2) = polynomial_ring(QQ,4);\n\njulia> nu = tropical_semiring_map(QQ,2);\n\njulia> f = 2*x1^2+x1*x2+x2^2+1\n2*x1^2 + x1*x2 + x2^2 + 1\n\njulia> TropH = tropical_hypersurface(f,nu)\nMin tropical hypersurface\n\njulia> multiplicities(TropH)\n5-element Vector{ZZRingElem}:\n 1\n 1\n 2\n 1\n 2\n\n\n\n\n\n\n","category":"method"},{"location":"TropicalGeometry/variety/#n_maximal_polyhedra-Tuple{TropicalVariety}","page":"Tropical varieties","title":"n_maximal_polyhedra","text":"n_maximal_polyhedra(TropV::TropicalVariety)\n\nSee n_maximal_polyhedra(::PolyhedralComplex).\n\n\n\n\n\n","category":"method"},{"location":"TropicalGeometry/variety/#n_polyhedra-Tuple{TropicalVariety}","page":"Tropical varieties","title":"n_polyhedra","text":"n_polyhedra(TropV::TropicalVariety)\n\nSee n_polyhedra(::PolyhedralComplex).\n\n\n\n\n\n","category":"method"},{"location":"TropicalGeometry/variety/#n_vertices-Tuple{TropicalVariety}","page":"Tropical varieties","title":"n_vertices","text":"n_vertices(TropV::TropicalVariety)\n\nSee n_vertices(::PolyhedralComplex).\n\n\n\n\n\n","category":"method"},{"location":"TropicalGeometry/variety/#is_pure-Tuple{TropicalVariety}","page":"Tropical varieties","title":"is_pure","text":"is_pure(TropV::TropicalVariety)\n\nSee is_pure(::PolyhedralComplex).\n\n\n\n\n\n","category":"method"},{"location":"TropicalGeometry/variety/#is_simplicial-Tuple{TropicalVariety}","page":"Tropical varieties","title":"is_simplicial","text":"is_simplicial(TropV::TropicalVariety)\n\nSee is_simplicial(::PolyhedralComplex).\n\n\n\n\n\n","category":"method"},{"location":"TropicalGeometry/variety/#rays-Tuple{TropicalVariety}","page":"Tropical varieties","title":"rays","text":"rays(TropV::TropicalVariety)\n\nSee rays(::PolyhedralComplex).\n\n\n\n\n\n","category":"method"},{"location":"TropicalGeometry/variety/#rays_modulo_lineality-Tuple{TropicalVariety}","page":"Tropical varieties","title":"rays_modulo_lineality","text":"rays_modulo_lineality(TropV::TropicalVariety)\n\nSee rays_modulo_lineality(::PolyhedralComplex).\n\n\n\n\n\n","category":"method"},{"location":"TropicalGeometry/variety/#vertices_and_rays-Tuple{TropicalVariety}","page":"Tropical varieties","title":"vertices_and_rays","text":"vertices_and_rays(TropV::TropicalVariety)\n\nSee vertices_and_rays(::PolyhedralComplex).\n\n\n\n\n\n","category":"method"},{"location":"TropicalGeometry/variety/#vertices-Tuple{TropicalVariety}","page":"Tropical varieties","title":"vertices","text":"vertices(TropV::TropicalVariety)\n\nSee vertices(::PolyhedralComplex).\n\n\n\n\n\n","category":"method"},{"location":"TropicalGeometry/variety/#visualize-Tuple{TropicalVariety}","page":"Tropical varieties","title":"visualize","text":"visualize(TropV::TropicalVariety)\n\nSee visualize(::PolyhedralComplex).\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.","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.)\nThe interactive sessions behave differently.\nWhen an error occurs or when the user hits ctrl-C in a GAP session, usually a break loop is entered, from which one can either try to continue the computations, by entering return, or return to the GAP prompt, by entering quit; in the latter case, some objects may be corrupted afterwards.\nIn a Julia session, one gets automatically back to the Julia prompt when an error occurs or when the user hits ctrl-C, and again some objects may be corrupted afterwards.\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-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":"Experimental/QuadFormAndIsom/primembed/","page":"Nikulin's theory on primitive embeddings","title":"Nikulin's theory on primitive embeddings","text":"CurrentModule = Oscar","category":"page"},{"location":"Experimental/QuadFormAndIsom/primembed/","page":"Nikulin's theory on primitive embeddings","title":"Nikulin's theory on primitive embeddings","text":"We introduce here the necessary definitions and results which lie behind the methods about primitive embeddings. Most of the content is taken from [Nik79].","category":"page"},{"location":"Experimental/QuadFormAndIsom/primembed/#Nikulin's-theory-on-primitive-embeddings","page":"Nikulin's theory on primitive embeddings","title":"Nikulin's theory on primitive embeddings","text":"","category":"section"},{"location":"Experimental/QuadFormAndIsom/primembed/#Primitive-embeddings","page":"Nikulin's theory on primitive embeddings","title":"Primitive embeddings","text":"","category":"section"},{"location":"Experimental/QuadFormAndIsom/primembed/","page":"Nikulin's theory on primitive embeddings","title":"Nikulin's theory on primitive embeddings","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 [Nik79].","category":"page"},{"location":"Experimental/QuadFormAndIsom/primembed/","page":"Nikulin's theory on primitive embeddings","title":"Nikulin's theory on primitive embeddings","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 [Nik79]). More generally, the author also provides methods to compute primitive embeddings of any even lattice into an even lattice of a given genus (see Proposition 1.15.1 in [Nik79]). In the latter proposition, it is explained how to classify such embeddings as isomorphic embeddings or as isomorphic sublattices. Moreover, with enough care, one can generalize the previous results for embeddings in odd lattices.","category":"page"},{"location":"Experimental/QuadFormAndIsom/primembed/","page":"Nikulin's theory on primitive embeddings","title":"Nikulin's theory on primitive embeddings","text":"A general method to compute primitive embeddings between integral lattices 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 made more efficient.","category":"page"},{"location":"Experimental/QuadFormAndIsom/primembed/","page":"Nikulin's theory on primitive embeddings","title":"Nikulin's theory on primitive embeddings","text":"We provide 4 kinds of output:","category":"page"},{"location":"Experimental/QuadFormAndIsom/primembed/","page":"Nikulin's theory on primitive embeddings","title":"Nikulin's theory on primitive embeddings","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":"Nikulin's theory on primitive embeddings","title":"Nikulin's theory on primitive embeddings","text":"primitive_embeddings(::ZZLat, ::ZZLat)","category":"page"},{"location":"Experimental/QuadFormAndIsom/primembed/#primitive_embeddings-Tuple{ZZLat, ZZLat}","page":"Nikulin's theory on primitive embeddings","title":"primitive_embeddings","text":"primitive_embeddings(L::ZZLat, M::ZZLat; classification::Symbol = :sub,\n check::Bool = true)\n -> Bool, Vector{Tuple{ZZLat, ZZLat, ZZLat}}\n\nGiven an integral integer lattice L, which is unique in its genus, and an integral integer lattice M, return whether M embeds primitively in L.\n\nThe first output of the function is a boolean T stating whether M embeds primitively in L. The second output V consists of 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 depends on the value of the symbol classification. There are 4 possibilities:\n\nclassification == :none: V is the empty list;\nclassification == :first: V consists of the first primitive embedding found;\nclassification == :sub: V consists of representatives for all isomorphism classes of primitive embeddings of M in L, up to the actions of O(M) and O(q) where q is the discriminant group of L;\nclassification == :emb: V consists of representatives for all isomorphism classes of primitive embeddings of M in L 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\nWe follow the algorithm described in the proof of Proposition 1.15.1 of [Nik79]. The classification methods for the symbols :sub and :emb correspond to the different classes of primitive embeddings defined in the same proposition: for :sub we classify sublattices of L which are isometric to M, and for :emb we classify the different embeddings of M into L.\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: there exists a unique class of embedding of the root lattice A_4 into the root lattice E_8, and the orthogonal primitive sublattice is isometric to A_4.\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/primembed/","page":"Nikulin's theory on primitive embeddings","title":"Nikulin's theory on primitive embeddings","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":"Nikulin's theory on primitive embeddings","title":"Nikulin's theory on primitive embeddings","text":"primitive_embeddings(::ZZGenus, ::ZZLat)\nprimitive_embeddings(::TorQuadModule, ::Tuple{Int, Int}, ::ZZLat)","category":"page"},{"location":"Experimental/QuadFormAndIsom/primembed/#primitive_embeddings-Tuple{ZZGenus, ZZLat}","page":"Nikulin's theory on primitive embeddings","title":"primitive_embeddings","text":"primitive_embeddings(G::ZZGenus, M::ZZLat; classification::Symbol = :sub)\n -> Bool, Vector{Tuple{ZZLat, ZZLat, ZZLat}}\n\nGiven a genus symbol G for integral integer lattices and an integral integer lattice M, return whether M embeds primitively in a lattice in G.\n\nThe first output of the function is a boolean T stating whether M embeds primitively in a lattice in G. The second output V consists of 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 depends on the value of classification. There are 4 possibilities:\n\nclassification == :none: V is the empty list;\nclassification == :first: V consists of the first primitive embedding found;\nclassification == :sub: V consists of representatives for all isomorphism classes of primitive embeddings of M in lattices in G, up to the actions of O(M) and O(q) where q is the discriminant group of a lattice in G;\nclassification == :emb: V consists of representatives for all isomorphism classes of primitive embeddings of M in of lattices in G, up to the action of O(q) where q is the discriminant group of a lattice in G.\n\nWe follow the algorithm described in the proof of Proposition 1.15.1 of [Nik79]. The classification methods for :sub and :emb correspond to the different classes of primitive embeddings defined in the same proposition: for :sub we classify sublattices of lattices in G which are isometric to M, and for :emb we classify the different embeddings of M into lattices in G.\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/primembed/#primitive_embeddings-Tuple{TorQuadModule, Tuple{Int64, Int64}, ZZLat}","page":"Nikulin's theory on primitive embeddings","title":"primitive_embeddings","text":"primitive_embeddings(q::TorQuadModule, sign::Tuple{Int, Int}, M::ZZLat;\n classification::Symbol = :sub)\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 integral integer lattices, return whether the integral integer lattice M embeds primitively in a lattice in G.\n\nThe first output of the function is a boolean T stating whether M embeds primitively in a lattice in G. The second output V consists of 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 depends on the value of the symbol classification. There are 4 possibilities:\n\nclassification == :none: V is the empty list;\nclassification == :first: V consists of the first primitive embedding found;\nclassification == :sub: V consists of representatives for all isomorphism classes of primitive embeddings of M in lattices in G, up to the actions of O(M) and O(q);\nclassification == :emb: V consists of representatives for all isomorphism classes of primitive embeddings of M in lattices in G G, up to the action of O(q).\n\nIf the pair (q, sign) does not define a non-empty genus for integer lattices, an error is thrown.\n\nWe follow the algorithm described in the proof of Proposition 1.15.1 of [Nik79]. The classification methods for the symbols :sub and :emb correspond to the different classes of primitive embeddings defined in the same proposition: for :sub we classify sublattices of lattices in G which are isometric to M, and for :emb we classify the different embeddings of M into lattices in G.\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/primembed/","page":"Nikulin's theory on primitive embeddings","title":"Nikulin's theory on primitive embeddings","text":"In order to compute such primitive embeddings of a lattice M into a lattice L, we follow the proof of Proposition 1.15.1 of [Nik79].","category":"page"},{"location":"Experimental/QuadFormAndIsom/primembed/","page":"Nikulin's theory on primitive embeddings","title":"Nikulin's theory on primitive embeddings","text":"Note: for the implementation of the algorithm, we construct a lattice T which is unique in its genus, such that D_T and D_M(-1) are isometric and O(T)to O(D_T) is surjective. We then classify all primitive extensions of Moplus T modulo O(D_T) (and modulo O(M) for a classification of primitive sublattices). To classify such primitive extensions, we use Proposition 1.5.1 of [Nik79]:","category":"page"},{"location":"Experimental/QuadFormAndIsom/primembed/","page":"Nikulin's theory on primitive embeddings","title":"Nikulin's theory on primitive embeddings","text":"primitive_extensions(::ZZLat, ::ZZLat)","category":"page"},{"location":"Experimental/QuadFormAndIsom/primembed/#primitive_extensions-Tuple{ZZLat, ZZLat}","page":"Nikulin's theory on primitive embeddings","title":"primitive_extensions","text":"primitive_extensions(M::ZZLat, N::ZZLat; glue_order::Union{IntegerUnion, Nothing} = nothing,\n q::Union{TorQuadModule, Nothing} = nothing,\n even::Bool = is_even(M) && is_even(N),\n classification::Symbol = :subsub)\n -> Bool, Vector{Tuple{ZZLat, ZZLat, ZZLat}}\n\nGiven two integral integer lattices M and N, return a boolean T and a list V of representatives of isomorphism classes of primitive extensions M oplus N subseteq L.\n\nOne can decide to choose the index of L(Moplus N), which should be a positive integer by setting glue_order to the desired value. One can also decide on the isometry class of the discriminant form of the primitive extension by setting q to the desired value. If there are no primitive extensions of M and N satisfying the conditions imposed by the choice of glue_order or q, then T = false and V is the empty list.\n\nOtherwise, T = true and V consists of triple (L M N) such that M is isometric to M, N is isometric to N and L is a primitive extension of Moplus N satisfying conditions glue_order or q if assigned.\n\nThe content of V depends on the value classification. There are 6 possibilities:\n\nclassification == :none: V is the empty list;\nclassification == :first: V consists of the first primitive extension computed;\nclassification == :subsub: V consists of representatives for all isomorphism classes of primitive extensions of Moplus N satisfying the given conditions, up to the actions of O(M) and O(N);\nclassification == :subemb: V consists of representatives for all isomorphism classes of primitive extensions of Moplus N satisfying the given conditions, up to the action of O(M);\nclassification == :embsub: V consists of representatives for all isomorphism classes of primitive extensions of Moplus N satisfying the given conditions, up to the action of O(N);\nclassification == :embemb: V consists of representatives for all isomorphism classes of primitive extensions of Moplus N satisfying the given conditions.\n\nIf even = true, then each primitive extension in output is selected to be even.\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/primembed/","page":"Nikulin's theory on primitive embeddings","title":"Nikulin's theory on primitive embeddings","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 Moplus N such that both M and N embed primitively in L (via the natural embeddings MN to Moplus Nsubseteq L). Such primitive extensions are obtained, and classified, by classifying 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 gluing.","category":"page"},{"location":"Experimental/QuadFormAndIsom/primembed/#Equivariant-primitive-extensions","page":"Nikulin's theory on primitive embeddings","title":"Equivariant primitive extensions","text":"","category":"section"},{"location":"Experimental/QuadFormAndIsom/primembed/","page":"Nikulin's theory on primitive embeddings","title":"Nikulin's theory on primitive embeddings","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 D_f_M and D_f_N stable along a glue map which commutes with these two actions. If such a gluing exists, then the overlattice L of Moplus 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":"Experimental/QuadFormAndIsom/primembed/","page":"Nikulin's theory on primitive embeddings","title":"Nikulin's theory on primitive embeddings","text":"equivariant_primitive_extensions(::Union{ZZLatWithIsom, ZZLat}, ::Union{ZZLatWithIsom, ZZLat})","category":"page"},{"location":"Experimental/QuadFormAndIsom/primembed/#equivariant_primitive_extensions-Tuple{Union{ZZLat, ZZLatWithIsom}, Union{ZZLat, ZZLatWithIsom}}","page":"Nikulin's theory on primitive embeddings","title":"equivariant_primitive_extensions","text":"equivariant_primitive_extensions(M::Union{ZZLat, ZZLatWithIsom},\n N::Union{ZZLat, ZZLatWithIsom};\n glue_order::Union{IntegerUnion, Nothing} = nothing,\n q::Union{IntegerUnion, Nothing} = nothing,\n even::Bool = is_even(M) && is_even(N),\n classification::Symbol = :subsub,\n compute_bar_Gf::Bool = true)\n -> Bool, Vector{Tuple{ZZLatWithIsom,\n ZZLatWithIsom,\n ZZLatWithIsom}}\n\nGiven two integral integer lattices M and N, where at least one of them is equiped with an isometry, return a boolean T and a list V of representatives of isomorphism classes of equivariant primitive extensions (M fM) oplus (N fN) subseteq (L fL). Note that if M (resp N) is not equiped with an isometry, then M (resp. N) has to be definite.\n\nOne can decide to choose the index of L(Moplus N) which should be a positive integer by setting glue_order to the desired value. One can also decide on the isometry class of the discriminant form of a primitive extension by setting q to the desired value. If there are no equivariant primitive extensions of M and N satisfying the conditions imposed by the choice of glue_order or q, then T = false and V is the empty list.\n\nOtherwise, T = true and V consists of triples ((L f_L) (M f_M) (N f_N)) such that M is isometric to M, N is isometric to N and (L f_L) is an equivariant primitive extension of (M f_M)oplus (N f_N) such that L satisfies conditions glue_order or q if assigned. If M (resp. N) is equiped with an isometry f_M (resp. f_N), then (M f_M) and (M f_M) (resp. (N f_N) and (N f_N)) are isomorphic as lattices with isometry.\n\nThe content of V depends on the value of classification. There are 6 possibilities:\n\nclassification == :none: V is empty by default;\nclassification == :first: V consists of the first equivariant primitive extension computed;\nclassification == :subsub: V consists of representatives for all isomorphism classes of equivariant primitive extensions of (M f_M)oplus (N f_N) satisfying the given conditions, up to the actions of O(M f_M) and O(N f_N);\nclassification == :subemb: V consists of representatives for all isomorphism classes of equivariant primitive extensions of (M f_M)oplus (N f_N) satisfying the given conditions, up to the action of O(M f_M);\nclassification == :embsub: V consists of representatives for all isomorphism classes of equivariant primitive extensions of (M f_M)oplus (N f_N) satisfying the given conditions, up to the action of O(N f_N);\nclassification == :embemb: V consists of representatives for all isomorphism classes of equivariant primitive extensions of (M f_M)oplus (N f_N) satisfying the given conditions;\n\nIf M (resp. N) is not equiped with an isometry, then the previous classifications are done modulo the action of O(M) (resp. O(N)) instead of O(M f_M) (resp. O(N f_N)). Moreover, the function extends representatives of conjugacy classes of isometries of M (resp. N) which can be glued equivariantly with f_N (resp. f_M) in a certain coset of O(M) determined by classification. Note that this can be expensive if M (resp. N) as large isometry group.\n\nIf even = true, then each primitive extension in output is selected to be even.\n\nIf compute_bar_Gf is set to true, then for each pair (L f_L) of an output triple in V, the algorithm compute the image of the natural map O(L f_L) to O(D_L D_f_L) (see image_centralizer_in_Oq).\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/primembed/#Admissible-equivariant-primitive-extensions","page":"Nikulin's theory on primitive embeddings","title":"Admissible equivariant primitive extensions","text":"","category":"section"},{"location":"Experimental/QuadFormAndIsom/primembed/","page":"Nikulin's theory on primitive embeddings","title":"Nikulin's theory on primitive embeddings","text":"The following function is a major tool provided by [BH23]. Given a triple of even 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)oplus (B b)to (D d) such that the type of (D d^q) is equal to the type of (C c) (see type(::ZZLatWithIsom)).","category":"page"},{"location":"Experimental/QuadFormAndIsom/primembed/","page":"Nikulin's theory on primitive embeddings","title":"Nikulin's theory on primitive embeddings","text":"admissible_equivariant_primitive_extensions(::ZZLatWithIsom, ::ZZLatWithIsom, ::ZZLatWithIsom, ::IntegerUnion, ::IntegerUnion)","category":"page"},{"location":"Experimental/QuadFormAndIsom/primembed/#admissible_equivariant_primitive_extensions-Tuple{ZZLatWithIsom, ZZLatWithIsom, ZZLatWithIsom, Union{Integer, ZZRingElem}, Union{Integer, ZZRingElem}}","page":"Nikulin's theory on primitive embeddings","title":"admissible_equivariant_primitive_extensions","text":"admissible_equivariant_primitive_extensions(Afa::ZZLatWithIsom,\n Bfb::ZZLatWithIsom,\n Cfc::ZZLatWithIsom,\n p::IntegerUnion,\n q::IntegerUnion = p; check::Bool = true)\n -> Vector{ZZLatWithIsom}\n\nGiven a triple of lattices with isometry (A f_A), (B f_B) and (C f_C), 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 f_A) to O(D_A D_f_A) and O(B f_B) to O(D_B D_f_B);\nS is the set of all primitive extensions A oplus B subseteq C with isometry f_C where pcdot C subseteq Aoplus B and such that the type of (C (f_C)^q) is equal to the type of (C f_C).\n\nIf check == true the input triple is checked to a p-admissible triple of integral lattices (with isometry) with f_A and f_B having relatively coprime irreducible minimal polynomials. Moreover, the function checks that A and B are orthogonal if A, B and C lie in the same ambient quadratic space.\n\nNote moreover that the function computes the image of the natural map O(C f_C) to O(D_C D_f_C) along the primitive extension Aoplus Bsubseteq C (see Algorithm 2, Line 22 of [BH23]).\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Groups/grouplib/","page":"Group libraries","title":"Group libraries","text":"CurrentModule = Oscar\nDocTestSetup = Oscar.doctestsetup()","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":"The functions in this section are wrappers for the GAP library of transitive permutation groups up to degree 48, via the GAP package TransGrp [Hul23].","category":"page"},{"location":"Groups/grouplib/","page":"Group libraries","title":"Group libraries","text":"(The groups of degrees 32 and 48 are currently not automatically available in Oscar, one has to install additional data in order to access them.)","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 [CHM98]. 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_of_transitive_groups\nhas_transitive_group_identification\nhas_transitive_groups\nnumber_of_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\nAs a special case, the first argument may also be one of the following:\n\nintval selects groups whose degree equals intval; this is equivalent to degree => intval\nintlist selects groups whose degree is in intlist; this is equivalent to degree => intlist\n\nThe following functions are currently supported as values for func:\n\ndegree\nis_abelian\nis_almost_simple\nis_cyclic\nis_nilpotent\nis_perfect\nis_primitive\nis_quasisimple\nis_simple\nis_sporadic_simple\nis_solvable\nis_supersolvable\nis_transitive\nnumber_of_conjugacy_classes\nnumber_of_moved_points\norder\ntransitivity\n\nThe type of the returned groups is PermGroup.\n\nExamples\n\njulia> all_transitive_groups(4)\n5-element Vector{PermGroup}:\n Permutation group of degree 4\n Permutation group of degree 4\n Permutation group of degree 4\n Alt(4)\n Sym(4)\n\njulia> all_transitive_groups(degree => 3:5, is_abelian)\n4-element Vector{PermGroup}:\n Alt(3)\n Permutation group of degree 4\n Permutation group of degree 4\n Permutation group of degree 5\n\n\n\n\n\n","category":"function"},{"location":"Groups/grouplib/#has_number_of_transitive_groups","page":"Group libraries","title":"has_number_of_transitive_groups","text":"has_number_of_transitive_groups(deg::Int)\n\nReturn whether the number transitive groups groups of degree deg are available for use via number_of_transitive_groups.\n\nExamples\n\njulia> has_number_of_transitive_groups(30)\ntrue\n\njulia> has_number_of_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_of_transitive_groups","page":"Group libraries","title":"number_of_transitive_groups","text":"number_of_transitive_groups(deg::Int)\n\nReturn the number of transitive groups of degree deg, up to permutation isomorphism.\n\nExamples\n\njulia> number_of_transitive_groups(30)\n5712\n\njulia> number_of_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)\nAlt(5)\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]\nPermutation group of degree 7\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":"The functions in this section are wrappers for the GAP library of primitive permutation groups up to degree 8191, via the GAP package PrimGrp [HRR23]. See the documentation of this package for more information about the source of the data.","category":"page"},{"location":"Groups/grouplib/","page":"Group libraries","title":"Group libraries","text":"all_primitive_groups\nhas_number_of_primitive_groups\nhas_primitive_group_identification\nhas_primitive_groups\nnumber_of_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\nAs a special case, the first argument may also be one of the following:\n\nintval selects groups whose degree equals intval; this is equivalent to degree => intval\nintlist selects groups whose degree is in intlist; this is equivalent to degree => intlist\n\nThe following functions are currently supported as values for func:\n\ndegree\nis_abelian\nis_almost_simple\nis_cyclic\nis_nilpotent\nis_perfect\nis_primitive\nis_quasisimple\nis_simple\nis_sporadic_simple\nis_solvable\nis_supersolvable\nis_transitive\nnumber_of_conjugacy_classes\nnumber_of_moved_points\norder\ntransitivity\n\nThe type of the returned groups is PermGroup.\n\nExamples\n\njulia> all_primitive_groups(4)\n2-element Vector{PermGroup}:\n Alt(4)\n Sym(4)\n\njulia> all_primitive_groups(degree => 3:5, is_abelian)\n2-element Vector{PermGroup}:\n Alt(3)\n Permutation group of degree 5 and order 5\n\n\n\n\n\n","category":"function"},{"location":"Groups/grouplib/#has_number_of_primitive_groups","page":"Group libraries","title":"has_number_of_primitive_groups","text":"has_number_of_primitive_groups(deg::Int)\n\nReturn true if the number of primitive permutation groups of degree deg is available via number_of_primitive_groups, otherwise false.\n\nCurrently the number of primitive permutation groups is available up to degree 4095.\n\nExamples\n\njulia> has_number_of_primitive_groups(50)\ntrue\n\njulia> has_number_of_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_of_primitive_groups","page":"Group libraries","title":"number_of_primitive_groups","text":"number_of_primitive_groups(deg::Int)\n\nReturn the number of primitive permutation groups of degree deg, up to permutation isomorphism.\n\nExamples\n\njulia> number_of_primitive_groups(10)\n9\n\njulia> number_of_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)\nPermutation group of degree 10 and order 60\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]\nPermutation group of degree 7 and order 720\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 [HP89]. For orders 86016, 368640, or 737280 this work only counted the groups (but did not explicitly list them), the groups of orders 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 [HP89] 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 in 2005 by Jack Schmidt. Two groups of order 243000 and one each of orders 729000, 871200, 878460 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, see [Hul22]. 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":"all_perfect_groups\nhas_number_of_perfect_groups\nhas_perfect_group_identification\nhas_perfect_groups\nnumber_of_perfect_groups\norders_perfect_groups\nperfect_group\nperfect_group_identification","category":"page"},{"location":"Groups/grouplib/#all_perfect_groups","page":"Group libraries","title":"all_perfect_groups","text":"all_perfect_groups(L...)\n\nReturn the list of all perfect 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\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\nThe following functions are currently supported as values for func:\n\nis_quasisimple\nis_simple\nis_sporadic_simple\nnumber_of_conjugacy_classes\norder\n\nThe type of the returned groups is PermGroup.\n\nExamples\n\njulia> all_perfect_groups(7200)\n2-element Vector{PermGroup}:\n Permutation group of degree 29 and order 7200\n Permutation group of degree 288 and order 7200\n\njulia> all_perfect_groups(order => 1:200, !is_simple)\n2-element Vector{PermGroup}:\n Permutation group of degree 1 and order 1\n Permutation group of degree 24 and order 120\n\n\n\n\n\n","category":"function"},{"location":"Groups/grouplib/#has_number_of_perfect_groups","page":"Group libraries","title":"has_number_of_perfect_groups","text":"has_number_of_perfect_groups(n::Int)\n\nReturn true if the number of perfect groups of order n are available via number_of_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_of_perfect_groups(7200)\ntrue\n\njulia> has_number_of_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_of_perfect_groups","page":"Group libraries","title":"number_of_perfect_groups","text":"number_of_perfect_groups(n::IntegerUnion)\n\nReturn the number of perfect groups of order n, up to isomorphism.\n\nExamples\n\njulia> number_of_perfect_groups(60)\n1\n\njulia> number_of_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)\nPermutation group of degree 5 and order 60\n\njulia> gens(ans)\n2-element Vector{PermGroupElem}:\n (1,2)(4,5)\n (2,3,4)\n\njulia> perfect_group(FPGroup, 60, 1)\nFinitely presented group of order 60\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":"The functions in this section are wrappers for the GAP library of the following groups.","category":"page"},{"location":"Groups/grouplib/","page":"Group libraries","title":"Group libraries","text":"The GAP package SmallGrp [BEO23] provides","category":"page"},{"location":"Groups/grouplib/","page":"Group libraries","title":"Group libraries","text":"those of order at most 2000 (except those of order 1024),\nthose of cubefree order at most 50000,\nthose of order p^7 for the primes p = 3 5 7 11,\nthose of order p^n for n leq 6 and all primes p,\nthose of order q^n p where q^n divides 2^8, 3^6, 5^5 or 7^4 and p is an arbitrary prime not equal to q,\nthose of squarefree order,\nthose whose order factorises into at most 3 primes.","category":"page"},{"location":"Groups/grouplib/","page":"Group libraries","title":"Group libraries","text":"The GAP package SOTGrps [Pan23] provides","category":"page"},{"location":"Groups/grouplib/","page":"Group libraries","title":"Group libraries","text":"those whose order factorises into at most 4 primes,\nthose of order p^4 q where p and q are distinct primes.","category":"page"},{"location":"Groups/grouplib/","page":"Group libraries","title":"Group libraries","text":"The GAP package SglPPow [VE22] provides","category":"page"},{"location":"Groups/grouplib/","page":"Group libraries","title":"Group libraries","text":"those of order p^7 for primes p 11,\nthose of order 3^8.","category":"page"},{"location":"Groups/grouplib/","page":"Group libraries","title":"Group libraries","text":"all_small_groups\nhas_number_of_small_groups\nhas_small_group_identification\nhas_small_groups\nnumber_of_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\nexponent\nis_abelian\nis_almost_simple\nis_cyclic\nis_nilpotent\nis_perfect\nis_quasisimple\nis_simple\nis_sporadic_simple\nis_solvable\nis_supersolvable\nnumber_of_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 Pc group of order 12\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 Pc group of order 6\n Pc group of order 8\n Pc group of order 8\n Pc group of order 10\n\n\n\n\n\n","category":"function"},{"location":"Groups/grouplib/#has_number_of_small_groups","page":"Group libraries","title":"has_number_of_small_groups","text":"has_number_of_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_of_small_groups(1024)\ntrue\n\njulia> has_number_of_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_of_small_groups","page":"Group libraries","title":"number_of_small_groups","text":"number_of_small_groups(n::IntegerUnion)\n\nReturn the number of groups of order n, up to isomorphism.\n\nExamples\n\njulia> number_of_small_groups(8)\n5\n\njulia> number_of_small_groups(4096)\nERROR: ArgumentError: the number of groups of order 4096 is not available\n\njulia> number_of_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)\nPc group of order 60\n\njulia> small_group(60, 5)\nPermutation group of degree 5 and order 60\n\njulia> small_group(PcGroup, 60, 4)\nPc group of order 60\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 [ATLAS]. 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_of_atlas_groups\nall_atlas_group_infos\natlas_group\natlas_subgroup","category":"page"},{"location":"Groups/grouplib/#number_of_atlas_groups","page":"Group libraries","title":"number_of_atlas_groups","text":"number_of_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_of_atlas_groups(\"A5\")\n18\n\njulia> number_of_atlas_groups(PermGroup, \"A5\")\n3\n\njulia> number_of_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(:constituents => [1, 4], :repname => \"A5G1-p5B0\", :degree => 5, :name => \"A5\")\n Dict(:constituents => [1, 5], :repname => \"A5G1-p6B0\", :degree => 6, :name => \"A5\")\n\njulia> atlas_group(info[1])\nPermutation group of degree 5 and order 60\n\njulia> info = all_atlas_group_infos(\"A5\", dim => 4, characteristic => 3)\n1-element Vector{Dict{Symbol, Any}}:\n Dict(:dim => 4, :constituents => [4], :repname => \"A5G1-f3r4B0\", :name => \"A5\")\n\njulia> atlas_group(info[1])\nMatrix group of degree 4\n over prime field of characteristic 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\nPermutation group of degree 5 and order 60\n\njulia> atlas_group(MatrixGroup, \"A5\")\nMatrix group of degree 4\n over prime field of characteristic 2\n\njulia> atlas_group(\"M11\") # Mathieu group M11\nPermutation group of degree 11 and order 7920\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(:constituents => [1, 4], :repname => \"A5G1-p5B0\", :degree => 5, :name => \"A5\")\n\njulia> atlas_group(info[1])\nPermutation group of degree 5 and order 60\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\nPermutation group of degree 11 and order 720\n\njulia> order(h1) # largest maximal subgroup of M11\n720\n\njulia> h2, emb = atlas_subgroup(\"M11\", 1); h2\nPermutation group of degree 11 and order 720\n\njulia> h3, emb = atlas_subgroup(MatrixGroup, \"M11\", 1 ); h3\nMatrix group of degree 10\n over prime field of characteristic 2\n\njulia> info = all_atlas_group_infos(\"M11\", degree => 11);\n\njulia> h4, emb = atlas_subgroup(info[1], 1); h4\nPermutation group of degree 11 and order 720\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 ring in 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":"number_of_variables(::Generic.AbsMSeriesRing)","category":"page"},{"location":"AbstractAlgebra/mseries/#number_of_variables-Tuple{AbstractAlgebra.Generic.AbsMSeriesRing}","page":"Multivariate series","title":"number_of_variables","text":"number_of_variables(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, S} where S<:MPolyRingElem{T}, AbstractAlgebra.Generic.AbsMSeries{T, S} where S<:MPolyRingElem{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, S} where S<:MPolyRingElem{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, S} where S<:MPolyRingElem{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, S} where S<:MPolyRingElem{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":"Combinatorics/EnumerativeCombinatorics/schur_polynomials/#Schur-polynomials","page":"Schur polynomials","title":"Schur polynomials","text":"","category":"section"},{"location":"Combinatorics/EnumerativeCombinatorics/schur_polynomials/","page":"Schur polynomials","title":"Schur polynomials","text":"Given a partition lambda with n parts, the Schur polynomial is defined to be the polynomial","category":"page"},{"location":"Combinatorics/EnumerativeCombinatorics/schur_polynomials/","page":"Schur polynomials","title":"Schur polynomials","text":"s_lambda = sum x_1^m_1dots x_n^m_n","category":"page"},{"location":"Combinatorics/EnumerativeCombinatorics/schur_polynomials/","page":"Schur polynomials","title":"Schur polynomials","text":"where the sum is taken over all semistandard tableaux T of shape lambda and m_i is the weight of i in T.","category":"page"},{"location":"Combinatorics/EnumerativeCombinatorics/schur_polynomials/","page":"Schur polynomials","title":"Schur polynomials","text":"There are two different algorithms for the computation of a Schur polynomial implemented which are automatically selected depending on the size of the input.","category":"page"},{"location":"Combinatorics/EnumerativeCombinatorics/schur_polynomials/","page":"Schur polynomials","title":"Schur polynomials","text":"For small integers or if ngeq 10, the combinatorial algorithm is used. This algorithm directly applies the above definition.","category":"page"},{"location":"Combinatorics/EnumerativeCombinatorics/schur_polynomials/","page":"Schur polynomials","title":"Schur polynomials","text":"In the other cases, Cauchy's bialternant formula","category":"page"},{"location":"Combinatorics/EnumerativeCombinatorics/schur_polynomials/","page":"Schur polynomials","title":"Schur polynomials","text":"s_lambda(x_1 dots x_n) = prod_1leq i j leq n (x_i - x_j)^-1\nbeginvmatrix\nx_1^lambda_1 + n - 1 x_2^lambda_1 + n - 1 dots x_n^lambda_1 + n - 1 \nx_1^lambda_2 + n - 2 x_2^lambda_2 + n - 2 dots x_n^lambda_2 + n - 2 \nvdots vdots ddots vdots \nx_1^lambda_n x_2^lambda_n dots x_n^lambda_n\nendvmatrix","category":"page"},{"location":"Combinatorics/EnumerativeCombinatorics/schur_polynomials/","page":"Schur polynomials","title":"Schur polynomials","text":"is used.","category":"page"},{"location":"Combinatorics/EnumerativeCombinatorics/schur_polynomials/","page":"Schur polynomials","title":"Schur polynomials","text":"schur_polynomial","category":"page"},{"location":"Combinatorics/EnumerativeCombinatorics/schur_polynomials/#schur_polynomial","page":"Schur polynomials","title":"schur_polynomial","text":"schur_polynomial([R::ZZMPolyRing], lambda::Partition, n::Int = length(lambda))\n\nReturn the Schur polynomial s of the partition lambda in n variables.\n\nThe ambient ring of s may optionally be supplied as a first argument.\n\nExamples\n\njulia> R, _ = 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\n\n\n\n\n","category":"function"},{"location":"TropicalGeometry/semiring_map/#Tropical-semiring-maps","page":"Tropical semiring maps","title":"Tropical semiring maps","text":"","category":"section"},{"location":"TropicalGeometry/semiring_map/#Introduction","page":"Tropical semiring maps","title":"Introduction","text":"","category":"section"},{"location":"TropicalGeometry/semiring_map/","page":"Tropical semiring maps","title":"Tropical semiring maps","text":"In OSCAR, a TropicalSemiringMap is a map nu KtomathbbT from a field K to a tropical semiring mathbbT satisfing","category":"page"},{"location":"TropicalGeometry/semiring_map/","page":"Tropical semiring maps","title":"Tropical semiring maps","text":"finiteness: nu(a)=pminfty if and only if a=0,\nmultiplicativity: nu(acdot b)=nu(a)+nu(b),\nsuperadditivity: nu(acdot b)geqmin(nu(a)nu(b)) (in the order defined in Section 2.7 of [Jos21]).","category":"page"},{"location":"TropicalGeometry/semiring_map/","page":"Tropical semiring maps","title":"Tropical semiring maps","text":"Most commonly, nu(a)=-mathrmval(a) if mathbbT is the min-plus semiring, and nu(a)=+mathrmval(a) if mathbbT is the max-plus semiring, for some valuation mathrmvalK^astrightarrowmathbbR. Essentially, nu captures a valuation on K as well as a choice of min- or max-convention. They are an optional input for most tropical functions over valued fields (the default being the trivial valuation and the min-convention).","category":"page"},{"location":"TropicalGeometry/semiring_map/#Constructor","page":"Tropical semiring maps","title":"Constructor","text":"","category":"section"},{"location":"TropicalGeometry/semiring_map/","page":"Tropical semiring maps","title":"Tropical semiring maps","text":"Tropical semiring maps can be constructed as follows:","category":"page"},{"location":"TropicalGeometry/semiring_map/","page":"Tropical semiring maps","title":"Tropical semiring maps","text":"tropical_semiring_map(K::Field, minOrMax::Union{typeof(min),typeof(max)}=min)\ntropical_semiring_map(K::QQField, p::Union{RingElem,Integer,Rational}, minOrMax::Union{typeof(min),typeof(max)}=min)\ntropical_semiring_map(Kt::Generic.RationalFunctionField, t::Generic.RationalFunctionFieldElem, minOrMax::Union{typeof(min),typeof(max)}=min)","category":"page"},{"location":"TropicalGeometry/semiring_map/#tropical_semiring_map","page":"Tropical semiring maps","title":"tropical_semiring_map","text":"tropical_semiring_map(K::Field, minOrMax::Union{typeof(min),typeof(max)}=min)\n\nReturn a map nu from K to the min (default) or max tropical semiring T such that nu(0)=zero(T) and nu(c)=one(T) for c non-zero. In other words, nu extends the trivial valuation on K.\n\nExample\n\njulia> nu = tropical_semiring_map(QQ) # arbitrary rings possible\nMap into Min tropical semiring encoding the trivial valuation on Rational field\n\njulia> nu(1)\n(0)\n\njulia> nu(0)\ninfty\n\njulia> nu = tropical_semiring_map(QQ,max) # arbitrary rings possible\nMap into Max tropical semiring encoding the trivial valuation on Rational field\n\njulia> nu(1)\n(0)\n\njulia> nu(0)\n-infty\n\n\n\n\n\n\n","category":"function"},{"location":"TropicalGeometry/semiring_map/#tropical_semiring_map-2","page":"Tropical semiring maps","title":"tropical_semiring_map","text":"tropical_semiring_map(QQ::QQField, p::QQFieldElem, minOrMax::Union{typeof(min),typeof(max)}=min)\n\nReturn a map nu from QQ to the min (default) or max tropical semiring T such that nu(0)=zero(T) and nu(c)=+/-val(c) for c non-zero, where val denotes the p-adic valuation. Requires p to be a prime.\n\nExample\n\njulia> nu_2 = tropical_semiring_map(QQ,2)\nMap into Min tropical semiring encoding the 2-adic valuation on Rational field\n\njulia> nu_2(4)\n(2)\n\njulia> nu_2(1//4)\n(-2)\n\njulia> nu_2 = tropical_semiring_map(QQ,2,max);\n\njulia> nu_2(4)\n(-2)\n\njulia> nu_2(1//4)\n(2)\n\n\n\n\n\n\n","category":"function"},{"location":"TropicalGeometry/semiring_map/#tropical_semiring_map-3","page":"Tropical semiring maps","title":"tropical_semiring_map","text":"tropical_semiring_map(Kt::Generic.RationalFunctionField, t::Generic.RationalFunctionFieldElem, minOrMax::Union{typeof(min),typeof(max)}=min)\n\nReturn a map nu from rational function field Kt to the min (default) or max tropical semiring T such that nu(0)=zero(T) and nu(c)=+/-val(c) for c non-zero, where val denotes the t-adic valuation with uniformizer t. Requires t to be non-constant and have denominator 1.\n\nExample\n\njulia> Kt,t = rational_function_field(QQ,\"t\");\n\njulia> nu_t = tropical_semiring_map(Kt,t)\nMap into Min tropical semiring encoding the t-adic valuation on Rational function field over QQ\n\njulia> nu_t(t^2)\n(2)\n\njulia> nu_t(1//t^2)\n(-2)\n\njulia> nu_t = tropical_semiring_map(Kt,t,max)\nMap into Max tropical semiring encoding the t-adic valuation on Rational function field over QQ\n\njulia> nu_t(t^2)\n(-2)\n\njulia> nu_t(1//t^2)\n(2)\n\n\n\n\n\n\n","category":"function"},{"location":"NoncommutativeAlgebra/PBWAlgebras/intro/","page":"Introduction","title":"Introduction","text":"CurrentModule = Oscar\nDocTestSetup = Oscar.doctestsetup()","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 [LS03] 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 mathbbN^n, then set alpha^textop =(alpha_n ldots alpha_1)in mathbbN^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, [DL06]). ","category":"page"},{"location":"Experimental/MatroidRealizationSpaces/introduction/","page":"Matroid Realization Spaces","title":"Matroid Realization Spaces","text":"CurrentModule = Oscar\nDocTestSetup = Oscar.doctestsetup()","category":"page"},{"location":"Experimental/MatroidRealizationSpaces/introduction/#Matroid-Realization-Spaces","page":"Matroid Realization Spaces","title":"Matroid Realization Spaces","text":"","category":"section"},{"location":"Experimental/MatroidRealizationSpaces/introduction/","page":"Matroid Realization Spaces","title":"Matroid Realization Spaces","text":"Let M be a matroid of rank d on a ground set E of size n. Its realization space mathcalR(M) is an affine scheme that parameterizes all hyperplane arrangements that realize the matroid M (up to the action of PGL(r)). We provide functions that determine the affine coordinate ring of mathcalR(M). ","category":"page"},{"location":"Experimental/MatroidRealizationSpaces/introduction/","page":"Matroid Realization Spaces","title":"Matroid Realization Spaces","text":"is_realizable(M::Matroid; char::Union{Int,Nothing}=nothing, q::Union{Int,Nothing}=nothing)\ndefining_ideal(RS::MatroidRealizationSpace)\ninequations(RS::MatroidRealizationSpace)\nambient_ring(RS::MatroidRealizationSpace)\nrealization_space(M::Matroid; B::Union{GroundsetType,Nothing} = nothing, \n F::AbstractAlgebra.Ring = ZZ, saturate::Bool=false, reduce::Bool=true,\n char::Union{Int,Nothing}=nothing, q::Union{Int,Nothing}=nothing)\nrealization(M::Matroid; B::Union{GroundsetType,Nothing} = nothing, \n F::AbstractAlgebra.Ring = ZZ, saturate::Bool=false, reduce::Bool=true,\n char::Union{Int,Nothing}=nothing, q::Union{Int,Nothing}=nothing)\nrealization(RS::MatroidRealizationSpace)","category":"page"},{"location":"Experimental/MatroidRealizationSpaces/introduction/#is_realizable-Tuple{Matroid}","page":"Matroid Realization Spaces","title":"is_realizable","text":"is_realizable(M; char::Union{Int,Nothing}=nothing, q::Union{Int,Nothing}=nothing)\n\nIf char = nothing, then this function determines whether the matroid is realizable over some field.\nIf char == 0, then this function determines whether the matroid is realizable over some field of characteristic 0.\nIf char = p is prime, this function determines whether the matroid is realizable over the finite field GF(p).\nIf char == p and q is a power of p, this function determines whether the matroid is realizable over the finite field GF(q).\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/MatroidRealizationSpaces/introduction/#defining_ideal-Tuple{Oscar.MatroidRealizationSpace}","page":"Matroid Realization Spaces","title":"defining_ideal","text":"defining_ideal(RS::MatroidRealizationSpace)\n\nThe ideal of the matroid realization space RS.\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/MatroidRealizationSpaces/introduction/#inequations-Tuple{Oscar.MatroidRealizationSpace}","page":"Matroid Realization Spaces","title":"inequations","text":"inequations(RS::MatroidRealizationSpace)\n\nGenerators of the localizing semigroup of RS. These are the polynomials that need to be nonzero in any realization.\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/MatroidRealizationSpaces/introduction/#ambient_ring-Tuple{Oscar.MatroidRealizationSpace}","page":"Matroid Realization Spaces","title":"ambient_ring","text":"ambient_ring(RS::MatroidRealizationSpace)\n\nThe polynomial ring containing the ideal defining_ideal(RS) and the polynomials in inequations(RS).\n\n\n\n\n\n","category":"method"},{"location":"Experimental/MatroidRealizationSpaces/introduction/#realization_space-Tuple{Matroid}","page":"Matroid Realization Spaces","title":"realization_space","text":"realization_space(\n M::Matroid;\n B::Union{GroundsetType,Nothing}=nothing,\n saturate::Bool=false,\n simplify::Bool=true,\n char::Union{Int,Nothing}=nothing,\n q::Union{Int,Nothing}=nothing,\n ground_ring::Ring=ZZ\n)::MatroidRealizationSpace\n\nThis function returns the data for the coordinate ring of the matroid realization space of the matroid M as a MatroidRealizationSpace. This function has several optional parameters.\n\nB is a basis of M that specifies which columns of realization_matrix(M) form an identity matrix. The default is nothing, in which case the basis is chosen for you.\nsaturate determines whether defining_ideal(M) should be saturated with respect to the semigroup generated by inequations(M). The default is false. The saturation can be rather slow for large instances.\nsimplify determines whether a reduced realization space is returned which means that the equations are used to eliminate variables as far as possible. The default is true.\nchar specifies the characteristic of the coefficient ring. The returned realization space is then the space of all realizations over fields of characteristic char. The default is nothing.\nq is an integer and assumed to be a prime power q=p^k. The returned realization space is then the space of all realizations over the field GF(p^k). The default is nothing.\nground_ring is a ring and specifies the groundring over which one wants to consider the realization space, e.g. QQ or GF(p). The groudring ZZ means that we compute the space of realizations over all fields. The default is ZZ.\n\nExamples\n\njulia> M = fano_matroid();\n\njulia> RS = realization_space(M)\nThe realization space is\n [0 1 1 1 1 0 0]\n [1 0 1 1 0 1 0]\n [1 0 1 0 1 0 1]\nin the integer ring\nwithin the vanishing set of the ideal\n2ZZ\n\njulia> realization_space(non_fano_matroid())\nThe realization space is\n [1 1 0 0 1 1 0]\n [0 1 1 1 1 0 0]\n [0 1 1 0 0 1 1]\nin the integer ring\navoiding the zero loci of the polynomials\nRingElem[2]\n\njulia> realization_space(pappus_matroid(), char=0)\nThe realization space is\n [1 0 1 0 x2 x2 x2^2 1 0]\n [0 1 1 0 1 1 -x1*x2 + x1 + x2^2 1 1]\n [0 0 0 1 x2 x1 x1*x2 x1 x2]\nin the multivariate polynomial ring in 2 variables over QQ\navoiding the zero loci of the polynomials\nRingElem[x1 - x2, x2, x1, x2 - 1, x1 + x2^2 - x2, x1 - 1, x1*x2 - x1 - x2^2]\n\njulia> realization_space(uniform_matroid(3,6))\nThe realization space is\n [1 0 0 1 1 1]\n [0 1 0 1 x1 x3]\n [0 0 1 1 x2 x4]\nin the multivariate polynomial ring in 4 variables over ZZ\navoiding the zero loci of the polynomials\nRingElem[x1*x4 - x2*x3, x2 - x4, x1 - x3, x1*x4 - x1 - x2*x3 + x2 + x3 - x4, x3 - x4, x4 - 1, x3 - 1, x3, x4, x1 - x2, x2 - 1, x1 - 1, x1, x2]\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/MatroidRealizationSpaces/introduction/#realization-Tuple{Matroid}","page":"Matroid Realization Spaces","title":"realization","text":"realization(M::Matroid; B::Union{GroundsetType,Nothing} = nothing,\n saturate::Bool=false,\n char::Union{Int,Nothing}=nothing, q::Union{Int,Nothing}=nothing\n)::MatroidRealizationSpace\n\nThis function tries to find one realization in the matroid realization space of the matroid M. The output is again a MatroidRealizationSpace.\n\nIf the matroid is only realizable over an extension of the prime field the extension field is specified as a splitting field of an irreducible polynomial. Every root of this polynomial gives an equivalent realization of the matroid.\n\nThis function has several optional parameters. Note that one must input either the characteristic or a specific field of definition for the realization.\n\nB is a basis of M that specifies which columns of realization_matrix(M) form the identity matrix. The default is nothing, in which case the basis is chosen for you.\nchar specifies the characteristic of the coefficient ring, and is used to determine if the matroid is realizable over a field of this characteristic. The default is nothing.\nq is an integer, and when char = p, this input is used to determine whether the matroid is realizable over the finite field GF(p^q). The default is nothing.\nreduce determines whether a reduced realization space is returned which means that the equations are used to eliminate variables as far as possible. The default is true.\nsaturate determines whether defining_ideal(M) should be saturated with respect to the semigroup generated by inequations(M). The default is false. This can be rather slow for large instances.\n\nExamples\n\njulia> realization(pappus_matroid(), char=0)\nOne realization is given by\n [1 0 1 0 2 2 4 1 0]\n [0 1 1 0 1 1 1 1 1]\n [0 0 0 1 2 3 6 3 2]\nin the rational field\n\njulia> realization(pappus_matroid(), q=4)\nOne realization is given by\n [1 0 1 0 x1 + 1 x1 + 1 x1 1 0]\n [0 1 1 0 1 1 1 1 1]\n [0 0 0 1 x1 + 1 x1 1 x1 x1 + 1]\nin the multivariate polynomial ring in 1 variable over GF(2)\nwithin the vanishing set of the ideal\nIdeal (x1^2 + x1 + 1)\n\njulia> realization(uniform_matroid(3,6), char=5)\nOne realization is given by\n [1 0 0 1 1 1]\n [0 1 0 1 4 3]\n [0 0 1 1 3 2]\nin the prime field of characteristic 5\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/MatroidRealizationSpaces/introduction/#realization-Tuple{Oscar.MatroidRealizationSpace}","page":"Matroid Realization Spaces","title":"realization","text":"realization(RS::MatroidRealizationSpace)\n\nThis function tries to find one realization in the matroid realization RS. The output is again a MatroidRealizationSpace.\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/MatroidRealizationSpaces/introduction/","page":"Matroid Realization Spaces","title":"Matroid Realization Spaces","text":"If B is the polynomial ring ambient_ring(RS), I the ideal defining_ideal(RS), and U the multiplicative semigroup generated by inequations(RS), then the coordinate ring of the realization space mathcalR(M) is isomorphic to U^-1BI. ","category":"page"},{"location":"Experimental/MatroidRealizationSpaces/introduction/#Matroid-realization-spaces-as-affine-schemes","page":"Matroid Realization Spaces","title":"Matroid realization spaces as affine schemes","text":"","category":"section"},{"location":"Experimental/MatroidRealizationSpaces/introduction/","page":"Matroid Realization Spaces","title":"Matroid Realization Spaces","text":"Every MatroidRealizationSpace is an instance of an affine scheme. For those cases where implementations exist, the entire functionality provided for AbsAffineSchemes applies to matroid realization spaces. For example:","category":"page"},{"location":"Experimental/MatroidRealizationSpaces/introduction/","page":"Matroid Realization Spaces","title":"Matroid Realization Spaces","text":"julia> RM = realization_space(pappus_matroid(), ground_ring=QQ)\nThe realization space is\n [1 0 1 0 x2 x2 x2^2 1 0]\n [0 1 1 0 1 1 -x1*x2 + x1 + x2^2 1 1]\n [0 0 0 1 x2 x1 x1*x2 x1 x2]\nin the multivariate polynomial ring in 2 variables over QQ\navoiding the zero loci of the polynomials\nRingElem[x1 - x2, x2, x1, x2 - 1, x1 + x2^2 - x2, x1 - 1, x1*x2 - x1 - x2^2]\n\njulia> OO(RM)\nLocalization\n of quotient\n of multivariate polynomial ring in 2 variables x1, x2\n over rational field\n by ideal (0)\n at products of (x1 - x2, x2, x1, x2 - 1, x1 + x2^2 - x2, x1 - 1, x1*x2 - x1 - x2^2)\n\njulia> is_smooth(RM) # Calls the generic routine implemented for schemes\ntrue\n\njulia> x, y = gens(OO(RM)); I = ideal(OO(RM), [x - 4, y^2 - 8]);\n\njulia> pr = blow_up(RM, I)\nBlowup\n of scheme over QQ covered with 1 patch\n 1b: [x1, x2] scheme(0) \\ scheme((x1 - x2)*x2*x1*(x2 - 1)*(x1 + x2^2 - x2)*(x1 - 1)*(x1*x2 - x1 - x2^2))\n in sheaf of ideals with restriction\n 1b: Ideal (x1 - 4, x2^2 - 8)\nwith domain\n scheme over QQ covered with 2 patches\n 1a: [(s1//s0), x1, x2] scheme(-(s1//s0)*x1 + 4*(s1//s0) + x2^2 - 8) \\ scheme((x1 - x2)*x2*x1*(x2 - 1)*(x1 - 1)*(x1 + x2^2 - x2)*(x1*x2 - x1 - x2^2))\n 2a: [(s0//s1), x2] scheme(0) \\ scheme(((s0//s1)*x2^2 - 8*(s0//s1) - x2 + 4)*x2*((s0//s1)*x2^2 - 8*(s0//s1) + 4)*(x2 - 1)*((s0//s1)*x2^2 - 8*(s0//s1) + 3)*((s0//s1)*x2^2 - 8*(s0//s1) + x2^2 - x2 + 4)*((s0//s1)*x2^3 - (s0//s1)*x2^2 - 8*(s0//s1)*x2 + 8*(s0//s1) - x2^2 + 4*x2 - 4))\nand exceptional divisor\n effective cartier divisor defined by\n sheaf of ideals with restrictions\n 1a: Ideal (x1 - 4)\n 2a: Ideal (x2^2 - 8)\n \njulia> first(affine_charts(codomain(pr))) === RM\ntrue","category":"page"},{"location":"Experimental/MatroidRealizationSpaces/introduction/","page":"Matroid Realization Spaces","title":"Matroid Realization Spaces","text":"Note, however, that there are also cases which are not covered. For instance, one realization of the fano_matroid() is mathrmSpec(mathbb Z2 mathbb Z) which is not (yet) supported by the schemes framework.","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 projects 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/PROJECT_NAME, that have subfolders docs, src, and test. The general structure is","category":"page"},{"location":"Experimental/intro/","page":"Adding new projects to experimental","title":"Adding new projects to experimental","text":"experimental/PROJECT_NAME/\n├── README.md\n├── docs\n│   ├── doc.main\n│   └── src\n│   └── DOCUMENTATION.md\n├── src\n│   └── PROJECT_NAME.jl\n└── test\n └── *.jl","category":"page"},{"location":"Experimental/intro/","page":"Adding new projects to experimental","title":"Adding new projects to experimental","text":"The file src/PROJECT_NAME.jl and at least one .jl file in the test/ directory are mandatory and are used by Oscar.jl to find your code and tests. If there is a test/runtests.jl then only this file is executed during testing, otherwise all .jl files will be run automatically (in a random order).","category":"page"},{"location":"Experimental/intro/","page":"Adding new projects to experimental","title":"Adding new projects to experimental","text":"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/#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=\"\",\n new::Bool=true, timed::Bool=false, ignore=[])\n\nRun the Oscar tests in experimental//test/:\n\nif path is empty then all tests in that module are run, either via runtests.jl or directly.\nif path or path.jl is a file in that directory only this file is run.\n\nThe 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\nWith the optional parameter timed the function will return a dict mapping file names to a named tuple with compilation times and allocations. This only works for new=false.\n\nThe parameter ignore can be used to pass a list of String or Regex patterns. Test files or folders matching these will be skipped. Strings will be compared as suffixes. This only works for new=false.\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":"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(as::Type{PointVector{T}}, P::Polyhedron{T}) where {T<:scalar_types}\nrays(as::Type{RayVector{T}}, P::Polyhedron{T}) where {T<:scalar_types}\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 Polytope in ambient dimension 3\n Polytope in ambient dimension 3\n Polytope in ambient dimension 3\n Polytope in ambient dimension 3\n Polytope in ambient dimension 3\n Polytope 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 <= 1\nx_1 <= 1\n-x_2 <= 1\nx_2 <= 1\n-x_3 <= 1\nx_3 <= 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 <= 1\nx_1 <= 1\n-x_2 <= 1\nx_2 <= 1\n-x_3 <= 1\nx_3 <= 1\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/Polyhedra/auxiliary/#vertices-Union{Tuple{T}, Tuple{Type{PointVector{T}}, Polyhedron{T}}} where T<:Union{Float64, FieldElem}","page":"Auxiliary functions","title":"vertices","text":"vertices([as::Type{T} = PointVector,] P::Polyhedron)\n\nReturn an iterator over the vertices of P in the format defined by as. The vertices are defined to be the zero-dimensional faces, so if P has lineality, there are no vertices, only minimal faces.\n\nSee also minimal_faces and rays.\n\nOptional arguments for as include\n\nPointVector.\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(PointVector, P)\n5-element SubObjectIterator{PointVector{QQFieldElem}}:\n [-1, -1]\n [2, -1]\n [2, 1]\n [-1, 2]\n [1, 2]\n\njulia> point_matrix(vertices(P))\n[-1 -1]\n[ 2 -1]\n[ 2 1]\n[-1 2]\n[ 1 2]\n\nA half-space (here in 3-space) has no vertices:\n\njulia> UH = polyhedron([-1 0 0], [0])\nPolyhedron in ambient dimension 3\n\njulia> vertices(UH)\n0-element SubObjectIterator{PointVector{QQFieldElem}}\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/Polyhedra/auxiliary/#rays-Union{Tuple{T}, Tuple{Type{RayVector{T}}, Polyhedron{T}}} where T<:Union{Float64, FieldElem}","page":"Auxiliary functions","title":"rays","text":"rays([as::Type{T} = RayVector,] P::Polyhedron)\n\nReturn a minimal set of generators of the cone of unbounded directions of P (i.e. its rays) in the format defined by as. The rays are defined to be the one-dimensional faces of the recession cone, so if P has lineality, there are no rays.\n\nSee also rays_modulo_lineality, recession_cone and vertices.\n\nOptional arguments for as include\n\nRayVector.\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(RayVector, PO)\n2-element SubObjectIterator{RayVector{QQFieldElem}}:\n [1, 0]\n [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\nA half-space has no rays:\n\njulia> UH = polyhedron([-1 0 0], [0])\nPolyhedron in ambient dimension 3\n\njulia> rays(UH)\n0-element SubObjectIterator{RayVector{QQFieldElem}}\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\nSee also rays and lineality_space.\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\nSee also vertices and lineality_space.\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_3 = 2\nx_4 = 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)\nPolytope in ambient dimension 3\n\njulia> is_lattice_polytope(c)\ntrue\n\njulia> c = cube(3, 0, 4//3)\nPolytope 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)\nPolytope 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":"n_facets(P::Polyhedron)\nn_vertices(P::Polyhedron)\nf_vector(P::Polyhedron)\nfacet_sizes(P::Polyhedron)\ng_vector(P::Polyhedron)\nh_vector(P::Polyhedron)\nvertex_sizes(P::Polyhedron)","category":"page"},{"location":"PolyhedralGeometry/Polyhedra/auxiliary/#n_facets-Tuple{Polyhedron}","page":"Auxiliary functions","title":"n_facets","text":"n_facets(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> n_facets(cross_polytope(5))\n32\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/Polyhedra/auxiliary/#n_vertices-Tuple{Polyhedron}","page":"Auxiliary functions","title":"n_vertices","text":"n_vertices(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> n_vertices(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/#facet_sizes-Tuple{Polyhedron}","page":"Auxiliary functions","title":"facet_sizes","text":"facet_sizes(P::Polyhedron{T})\n\nNumber of vertices in each facet. \n\nExample\n\njulia> p = johnson_solid(4) \nPolytope in ambient dimension 3 with EmbeddedAbsSimpleNumFieldElem type coefficients\n\njulia> facet_sizes(p)\n10-element Vector{Int64}:\n 8\n 4\n 3\n 4\n 4\n 3\n 4\n 3\n 3\n 4\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/#vertex_sizes-Tuple{Polyhedron}","page":"Auxiliary functions","title":"vertex_sizes","text":"vertex_sizes(P::Polyhedron{T})\n\nNumber of incident facets for each vertex.\n\nExample\n\njulia> vertex_sizes(bipyramid(simplex(2)))\n5-element Vector{Int64}:\n 4\n 4\n 4\n 3\n 3\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)\nPolytope in ambient dimension 3\n\njulia> G = linear_symmetries(c)\nPermutation group of degree 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)\nPermutation group of degree 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)\nPermutation group of degree 4\n\njulia> order(G)\n8\n\njulia> G = linear_symmetries(quad)\nPermutation group of degree 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)\nPolytope 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)\nPolytope 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})\nis_archimedean_solid(P::Polyhedron)\nis_johnson_solid(P::Polyhedron)\nis_platonic_solid(P::Polyhedron)\nlattice_points(P::Polyhedron{QQFieldElem})\nlattice_volume(P::Polyhedron{QQFieldElem})\nnormalized_volume(P::Polyhedron)\npolarize(P::Polyhedron{T}) where T<:scalar_types\nproject_full(P::Polyhedron{T}) where T<:scalar_types\nprint_constraints(io::IO, A::AnyVecOrMat, b::AbstractVector; trivial::Bool = false, numbered::Bool = false, cmp = :lte)\nprint_constraints(io::IO, P::Polyhedron; trivial::Bool = false, numbered::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)\nPolytope 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)\nPolytope 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)\n\nReturn the integer points contained in the boundary of the bounded polyhedron P.\n\nExamples\n\njulia> c = polarize(cube(3))\nPolytope 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)\nPolytope in ambient dimension 3\n\njulia> Q = cube(3,-1,2)\nPolytope 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)\nPolytope 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)\nPolytope 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)\nPolytope 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)\nPolytope 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)\n\nReturn the integer points contained in the interior of the bounded polyhedron P.\n\nExamples\n\njulia> c = cube(3)\nPolytope 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)\nPolytope 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)\nPolytope 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)\nPolytope 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/#is_archimedean_solid-Tuple{Polyhedron}","page":"Auxiliary functions","title":"is_archimedean_solid","text":"is_archimedean_solid(P::Polyhedron)\n\nCheck whether P is an Archimedean solid, i.e., a 3-dimensional vertex transitive polytope with regular facets, but not a prism or antiprism.\n\nSee also archimedean_solid.\n\nnote: Note\nThis will only recognize algebraically precise solids, i.e. no solids with approximate coordinates.\n\nExamples\n\njulia> TO = archimedean_solid(\"truncated_octahedron\")\nPolytope in ambient dimension 3\n\njulia> is_archimedean_solid(TO)\ntrue\n\njulia> T = tetrahedron()\nPolytope in ambient dimension 3\n\njulia> is_archimedean_solid(T)\nfalse\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/Polyhedra/auxiliary/#is_johnson_solid-Tuple{Polyhedron}","page":"Auxiliary functions","title":"is_johnson_solid","text":"is_johnson_solid(P::Polyhedron)\n\nCheck whether P is a Johnson solid, i.e., a 3-dimensional polytope with regular faces that is not vertex transitive.\n\nSee also johnson_solid.\n\nnote: Note\nThis will only recognize algebraically precise solids, i.e. no solids with approximate coordinates.\n\nExamples\n\njulia> J = johnson_solid(37)\nPolytope in ambient dimension 3 with EmbeddedAbsSimpleNumFieldElem type coefficients\n\njulia> is_johnson_solid(J)\ntrue\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/Polyhedra/auxiliary/#is_platonic_solid-Tuple{Polyhedron}","page":"Auxiliary functions","title":"is_platonic_solid","text":"is_platonic_solid(P::Polyhedron)\n\nCheck whether P is a Platonic solid.\n\nSee also platonic_solid.\n\nnote: Note\nThis will only recognize algebraically precise solids, i.e. no solids with approximate coordinates.\n\nExamples\n\njulia> is_platonic_solid(cube(3))\ntrue\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)\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-Tuple{Polyhedron}","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)\nPolytope in ambient dimension 2\n\njulia> P = polarize(square)\nPolytope 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{IO, Union{MatElem, AbstractVecOrMat}, AbstractVector}","page":"Auxiliary functions","title":"print_constraints","text":"print_constraints([io = stdout,] A::AnyVecOrMat, b::AbstractVector; trivial = false, numbered = false, cmp = :lte)\n\nPretty print the constraints given by P(Ab) = x Ax b .\n\nOptional & Keyword Arguments\n\nio::IO: Target IO where the constraints are printed to.\ntrivial::Bool: If true, include trivial inequalities.\nnumbered::Bool: If true, the each constraint is printed with the index corresponding to the input AnyVecOrMat.\ncmp::Symbol: Defines the string used for the comparison sign; supports :lte (less than or equal) and :eq (equal).\n\nTrivial inequalities are always counted for numbering, even when omitted.\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_1 + 4*x_3 + 5*x_4 <= 0\n2: 4*x_1 + 4*x_2 + 4*x_3 + 3*x_4 <= 1\n3: x_1 <= 2\n5: 0 <= -4\n6: 9*x_1 + 9*x_2 + 9*x_3 + 9*x_4 <= 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_1 + 4*x_3 + 5*x_4 <= 0\n4*x_1 + 4*x_2 + 4*x_3 + 3*x_4 <= 1\nx_1 <= 2\n0 <= 3\n0 <= -4\n9*x_1 + 9*x_2 + 9*x_3 + 9*x_4 <= 5\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/Polyhedra/auxiliary/#print_constraints-Tuple{IO, Polyhedron}","page":"Auxiliary functions","title":"print_constraints","text":"print_constraints([io = stdout,] P::Polyhedron; trivial = false, numbered = false)\n\nPretty print the constraints given by P(Ab) = x Ax b .\n\nOptional & Keyword Arguments\n\nio::IO: Target IO where the constraints are printed to.\ntrivial::Bool: If true, include trivial inequalities.\nnumbered::Bool: If true, the each constraint is printed with the index corresponding to the input AnyVecOrMat.\n\nTrivial inequalities are always counted for numbering, even when omitted.\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 <= 1\nx_1 <= 1\n-x_2 <= 1\nx_2 <= 1\n-x_3 <= 1\nx_3 <= 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)\nPolytope 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)\nPolytope 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)\nPolytope 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)\nPolytope 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)\nPolytope in ambient dimension 3\n\njulia> sc = secondary_polytope(c)\nPolytope 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. The solutions are the (transposed) rows of the output.\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. 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> it = solve_mixed(SubObjectIterator{PointVector{ZZRingElem}}, A, b, C);\n\njulia> typeof(it)\nSubObjectIterator{PointVector{ZZRingElem}}\n\njulia> for x in it\n print(A*x,\" \")\n end\n[7] [7] [7] [7] [7] [7] [7] [7] \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. The solutions are the (transposed) rows of the output.\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. 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> it = solve_mixed(SubObjectIterator{PointVector{ZZRingElem}}, A, b, C);\n\njulia> typeof(it)\nSubObjectIterator{PointVector{ZZRingElem}}\n\njulia> for x in it\n print(A*x,\" \")\n end\n[3] [3] [3] [3] \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::QQField; sparse::Bool = false)\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{AbsSimpleNumField})\natlas_irrationality\natlas_description","category":"page"},{"location":"NumberTheory/abelian_closure/#gen-Tuple{QQAbField{AbsSimpleNumField}}","page":"Abelian closure of the rationals","title":"gen","text":"gen(K::QQAbField)\n\nReturn the generator of the abelian closure K that can be used to construct primitive roots of unity.\n\n\n\n\n\n","category":"method"},{"location":"NumberTheory/abelian_closure/#atlas_irrationality","page":"Abelian closure of the rationals","title":"atlas_irrationality","text":"atlas_irrationality([F::AbsSimpleNumField, ]description::String)\n\nReturn the value encoded by description. If F is given and is a cyclotomic field that contains the value then the result is in F, if F is not given then the result has type QQAbFieldElem.\n\ndescription is assumed to have the format defined in [CCNPW85], Chapter 6, Section 10.\n\nExamples\n\njulia> Oscar.with_unicode() do\n show(atlas_irrationality(\"r5\"))\n end;\n-2*ζ(5)^3 - 2*ζ(5)^2 - 1\n\njulia> atlas_irrationality(cyclotomic_field(5)[1], \"r5\")\n-2*z_5^3 - 2*z_5^2 - 1\n\njulia> Oscar.with_unicode() do\n show(atlas_irrationality(\"i\"))\n end;\nζ(4)\n\njulia> Oscar.with_unicode() do\n show(atlas_irrationality(\"b7*3\"))\n end;\n-ζ(7)^4 - ζ(7)^2 - ζ(7) - 1\n\njulia> Oscar.with_unicode() do\n show(atlas_irrationality(\"3y'''24*13-2&5\"))\n end;\n-5*ζ(24)^7 - 2*ζ(24)^5 + 2*ζ(24)^3 - 3*ζ(24)\n\n\n\n\n\n","category":"function"},{"location":"NumberTheory/abelian_closure/#atlas_description","page":"Abelian closure of the rationals","title":"atlas_description","text":"atlas_description(val::QQAbFieldElem)\n\nReturn a string in the format defined in [CCNPW85], Chapter 6, Section 10, describing val. Applying atlas_irrationality to the result yields val.\n\nExamples\n\njulia> K, z = abelian_closure(QQ);\n\njulia> val = z(5) + z(5)^4;\n\njulia> str = Oscar.atlas_description(val)\n\"b5\"\n\njulia> val == atlas_irrationality(str)\ntrue\n\n\n\n\n\n","category":"function"},{"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::QQAbFieldElem, F::FinField)","category":"page"},{"location":"NumberTheory/abelian_closure/#reduce-Tuple{QQAbFieldElem, FinField}","page":"Abelian closure of the rationals","title":"reduce","text":"reduce(val::QQAbFieldElem, 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 [CLS11], 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-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(domain::NormalToricVarietyType, mapping_matrix::ZZMatrix, codomain::NormalToricVarietyType; check=true)\ntoric_morphism(domain::NormalToricVarietyType, grid_morphism::FinGenAbGroupHom, codomain::NormalToricVarietyType; check=true)","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/ToricMorphisms/#toric_morphism-Tuple{Union{AffineNormalToricVariety, CyclicQuotientSingularity, NormalToricVariety}, ZZMatrix, Union{AffineNormalToricVariety, CyclicQuotientSingularity, NormalToricVariety}}","page":"ToricMorphisms","title":"toric_morphism","text":"toric_morphism(domain::NormalToricVarietyType, mapping_matrix::ZZMatrix, codomain::NormalToricVarietyType; check=true)\n\nConstruct the toric morphism with given domain and associated to the lattice morphism given by the mapping_matrix.\n\nIf the codomain is left out, it will be determined whether the image of the domain fan is itself a polyhedral fan. In that case the codomain is assumed to be the associated toric variety.\n\nAll checks can be disabled with check=false.\n\nExamples\n\njulia> domain = projective_space(NormalToricVariety, 1)\nNormal toric variety\n\njulia> codomain = hirzebruch_surface(NormalToricVariety, 2)\nNormal toric variety\n\njulia> mapping_matrix = matrix(ZZ, [0 1])\n[0 1]\n\njulia> toric_morphism(domain, mapping_matrix, codomain)\nToric morphism\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/ToricMorphisms/#toric_morphism-Tuple{Union{AffineNormalToricVariety, CyclicQuotientSingularity, NormalToricVariety}, FinGenAbGroupHom, Union{AffineNormalToricVariety, CyclicQuotientSingularity, NormalToricVariety}}","page":"ToricMorphisms","title":"toric_morphism","text":"toric_morphism(domain::NormalToricVarietyType, grid_morphism::FinGenAbGroupHom, codomain::NormalToricVarietyType; check=true)\n\nConstruct the toric morphism from the domain to the codomain with map given by the grid_morphism.\n\nIf the codomain is left out, it will be determined whether the image of the domain fan is itself a polyhedral fan. In that case the codomain is assumed to be the associated toric variety.\n\nAll checks can be disabled with check=false.\n\nExamples\n\njulia> domain = projective_space(NormalToricVariety, 1)\nNormal toric variety\n\njulia> codomain = hirzebruch_surface(NormalToricVariety, 2)\nNormal toric variety\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\n from Z\n to Z^2\n\njulia> toric_morphism(domain, grid_morphism, codomain)\nToric 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::NormalToricVarietyType)","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/ToricMorphisms/#toric_identity_morphism-Tuple{Union{AffineNormalToricVariety, CyclicQuotientSingularity, NormalToricVariety}}","page":"ToricMorphisms","title":"toric_identity_morphism","text":"toric_identity_morphism(variety::NormalToricVarietyType)\n\nConstruct the toric identity morphism from variety to variety.\n\nExamples\n\njulia> toric_identity_morphism(hirzebruch_surface(NormalToricVariety, 2))\nToric 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)\ncovering_morphism(f::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 toric variety\n\njulia> domain(toric_identity_morphism(F4))\nNormal toric variety\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/ToricMorphisms/#image-Tuple{ToricMorphism}","page":"ToricMorphisms","title":"image","text":"image(F::FreeMod{R}, A::MatElem{R}) where R\n\nReturn the image of A as an object of type SubquoModule with ambient free module F.\n\nExamples\n\njulia> R, (x,y,z) = polynomial_ring(QQ, [:x, :y, :z]);\n\njulia> F = free_module(R, 2)\nFree module of rank 2 over R\n\njulia> A = R[x y; 2*x^2 3*y^2]\n[ x y]\n[2*x^2 3*y^2]\n \njulia> M = image(F, A)\nSubmodule with 2 generators\n1 -> x*e[1] + y*e[2]\n2 -> 2*x^2*e[1] + 3*y^2*e[2]\nrepresented as subquotient with no relations.\n\njulia> ambient_free_module(M) === F\ntrue\n\njulia> Rg, (x, y, z) = graded_polynomial_ring(QQ, [:x, :y, :z]);\n\njulia> F = graded_free_module(Rg, [8,8])\nGraded free module Rg^2([-8]) of rank 2 over Rg\n\njulia> A = Rg[x y; 2*x^2 3*y^2]\n[ x y]\n[2*x^2 3*y^2]\n \njulia> M = image(F, A)\nGraded submodule of F\n1 -> x*e[1] + y*e[2]\n2 -> 2*x^2*e[1] + 3*y^2*e[2]\nrepresented as subquotient with no relations\n\njulia> ambient_free_module(M) === F\ntrue\n\njulia> degrees_of_generators(M)\n2-element Vector{FinGenAbGroupElem}:\n [9]\n [10]\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 toric variety\n\njulia> codomain(toric_identity_morphism(F4))\nNormal toric variety\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 toric variety\n\njulia> grid_morphism(toric_identity_morphism(F4))\nMap\n from Z^2\n to 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 toric variety\n\njulia> morphism_on_torusinvariant_weil_divisor_group(toric_identity_morphism(F4))\nMap\n from Z^4\n to 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 toric variety\n\njulia> morphism_on_torusinvariant_cartier_divisor_group(toric_identity_morphism(F4))\nMap\n from Z^4\n to 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 toric variety\n\njulia> morphism_on_class_group(toric_identity_morphism(F4))\nMap\n from Z^2\n to 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 toric variety\n\njulia> morphism_on_picard_group(toric_identity_morphism(F4))\nMap\n from Z^2\n to Z^2\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/ToricMorphisms/#covering_morphism-Tuple{ToricMorphism}","page":"ToricMorphisms","title":"covering_morphism","text":"covering_morphism(f::ToricMorphism)\n\nFor a given toric morphism tm, we can compute the corresponding morphism of covered schemes. The following demonstrates this for the blow-up morphism of a blow-up of the projective space.\n\nExamples\n\njulia> IP2 = projective_space(NormalToricVariety, 2)\nNormal toric variety\n\njulia> bl = blow_up(IP2, [1, 1]);\n\njulia> cov_bl = covering_morphism(bl);\n\njulia> domain(cov_bl)\nCovering\n described by patches\n 1: normal toric variety\n 2: normal toric variety\n 3: normal toric variety\n 4: normal toric variety\n in the coordinate(s)\n 1: [x_1_1, x_2_1]\n 2: [x_1_2, x_2_2]\n 3: [x_1_3, x_2_3]\n 4: [x_1_4, x_2_4]\n\njulia> codomain(cov_bl)\nCovering\n described by patches\n 1: normal toric variety\n 2: normal toric variety\n 3: normal toric variety\n in the coordinate(s)\n 1: [x_1_1, x_2_1]\n 2: [x_1_2, x_2_2]\n 3: [x_1_3, x_2_3]\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::NormalToricVarietyType)\ncox_variety(variety::NormalToricVarietyType)","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/ToricMorphisms/#morphism_from_cox_variety-Tuple{Union{AffineNormalToricVariety, CyclicQuotientSingularity, NormalToricVariety}}","page":"ToricMorphisms","title":"morphism_from_cox_variety","text":"morphism_from_cox_variety(variety::NormalToricVarietyType)\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 toric variety\n\njulia> morphism_from_cox_variety(F4)\nToric morphism\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/ToricMorphisms/#cox_variety-Tuple{Union{AffineNormalToricVariety, CyclicQuotientSingularity, NormalToricVariety}}","page":"ToricMorphisms","title":"cox_variety","text":"cox_variety(variety::NormalToricVarietyType)\n\nReturn the Cox variety of the toric variety in question.\n\nExamples\n\njulia> F4 = hirzebruch_surface(NormalToricVariety, 4)\nNormal toric variety\n\njulia> cox_variety(F4)\nNormal toric variety\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/quad_forms/introduction/#Introduction","page":"Introduction","title":"Introduction","text":"","category":"section"},{"location":"Hecke/manual/quad_forms/introduction/","page":"Introduction","title":"Introduction","text":"CurrentModule = Hecke","category":"page"},{"location":"Hecke/manual/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/manual/quad_forms/introduction/#Definitions-and-vocabulary","page":"Introduction","title":"Definitions and vocabulary","text":"","category":"section"},{"location":"Hecke/manual/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/manual/quad_forms/introduction/#Quadratic-and-hermitian-spaces","page":"Introduction","title":"Quadratic and hermitian spaces","text":"","category":"section"},{"location":"Hecke/manual/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/manual/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/manual/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/manual/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/manual/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/manual/quad_forms/introduction/#Quadratic-and-hermitian-lattices","page":"Introduction","title":"Quadratic and hermitian lattices","text":"","category":"section"},{"location":"Hecke/manual/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/manual/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/manual/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/manual/quad_forms/introduction/#References","page":"Introduction","title":"References","text":"","category":"section"},{"location":"Hecke/manual/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/manual/quad_forms/introduction/","page":"Introduction","title":"Introduction","text":"Most of the definitions and results are taken from:","category":"page"},{"location":"Hecke/manual/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/manual/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":"Hecke/manual/elliptic_curves/basics/#Basics","page":"Basics","title":"Basics","text":"","category":"section"},{"location":"Hecke/manual/elliptic_curves/basics/","page":"Basics","title":"Basics","text":"CurrentModule = Hecke\nDocTestSetup = quote\n using Hecke\nend\n","category":"page"},{"location":"Hecke/manual/elliptic_curves/basics/#Creation","page":"Basics","title":"Creation","text":"","category":"section"},{"location":"Hecke/manual/elliptic_curves/basics/","page":"Basics","title":"Basics","text":"elliptic_curve\nelliptic_curve_from_j_invariant","category":"page"},{"location":"Hecke/manual/elliptic_curves/basics/#elliptic_curve","page":"Basics","title":"elliptic_curve","text":"elliptic_curve([K::Field], x::Vector; check::Bool = true) -> EllipticCurve\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/manual/elliptic_curves/basics/#elliptic_curve_from_j_invariant","page":"Basics","title":"elliptic_curve_from_j_invariant","text":"elliptic_curve_from_j_invariant(j::FieldElem) -> EllipticCurve\n\nReturn an elliptic curve with the given j-invariant.\n\nExamples\n\njulia> K = GF(3)\nPrime 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/manual/elliptic_curves/basics/#Basic-properties","page":"Basics","title":"Basic properties","text":"","category":"section"},{"location":"Hecke/manual/elliptic_curves/basics/","page":"Basics","title":"Basics","text":"base_field(::EllipticCurve)\nbase_change(::Field, ::EllipticCurve)\nbase_change(::Any, ::EllipticCurve)\ncoefficients(::EllipticCurve)\na_invariants(::EllipticCurve)\nb_invariants(::EllipticCurve)\nc_invariants(::EllipticCurve)\ndiscriminant(::EllipticCurve)\nj_invariant(::EllipticCurve)\nequation(::EllipticCurve)\nhyperelliptic_polynomials(::EllipticCurve)","category":"page"},{"location":"Hecke/manual/elliptic_curves/basics/#base_field-Tuple{EllipticCurve}","page":"Basics","title":"base_field","text":"base_field(E::EllipticCurve) -> 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/manual/elliptic_curves/basics/#base_change-Tuple{Field, EllipticCurve}","page":"Basics","title":"base_change","text":"base_change(K::Field, E::EllipticCurve) -> EllipticCurve\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/manual/elliptic_curves/basics/#base_change-Tuple{Any, EllipticCurve}","page":"Basics","title":"base_change","text":"base_change(f, E::EllipticCurve) -> EllipticCurve\n\nReturn the base change of the elliptic curve E using the map f.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/elliptic_curves/basics/#coefficients-Tuple{EllipticCurve}","page":"Basics","title":"coefficients","text":"coefficients(E::EllipticCurve{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/manual/elliptic_curves/basics/#a_invariants-Tuple{EllipticCurve}","page":"Basics","title":"a_invariants","text":"a_invariants(E::EllipticCurve{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/manual/elliptic_curves/basics/#b_invariants-Tuple{EllipticCurve}","page":"Basics","title":"b_invariants","text":"b_invariants(E::EllipticCurve{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/manual/elliptic_curves/basics/#c_invariants-Tuple{EllipticCurve}","page":"Basics","title":"c_invariants","text":"c_invariants(E::EllipticCurve{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/manual/elliptic_curves/basics/#discriminant-Tuple{EllipticCurve}","page":"Basics","title":"discriminant","text":"discriminant(E::EllipticCurve) -> 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/manual/elliptic_curves/basics/#j_invariant-Tuple{EllipticCurve}","page":"Basics","title":"j_invariant","text":"j_invariant(E::EllipticCurve) -> FieldElem\n\nCompute the j-invariant of E.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/elliptic_curves/basics/#equation-Tuple{EllipticCurve}","page":"Basics","title":"equation","text":"equation([R::MPolyRing,] E::EllipticCurve) -> MPolyRingElem\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/manual/elliptic_curves/basics/#hyperelliptic_polynomials-Tuple{EllipticCurve}","page":"Basics","title":"hyperelliptic_polynomials","text":"hyperelliptic_polynomials([R::PolyRing,] E::EllipticCurve) -> PolyRingElem, PolyRingElem\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/manual/elliptic_curves/basics/#Points","page":"Basics","title":"Points","text":"","category":"section"},{"location":"Hecke/manual/elliptic_curves/basics/","page":"Basics","title":"Basics","text":" (E::EllipticCurve)(coords::Vector; check::Bool = true)","category":"page"},{"location":"Hecke/manual/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/manual/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/manual/elliptic_curves/basics/#Examples","page":"Basics","title":"Examples","text":"","category":"section"},{"location":"Hecke/manual/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/manual/elliptic_curves/basics/","page":"Basics","title":"Basics","text":"infinity(::EllipticCurve)\nparent(::EllipticCurvePoint)\nis_on_curve(::EllipticCurve, ::Vector)\n+(P::EllipticCurvePoint{T}, Q::EllipticCurvePoint{T}) where {T}\ndivision_points(::EllipticCurvePoint, ::Int)","category":"page"},{"location":"Hecke/manual/elliptic_curves/basics/#infinity-Tuple{EllipticCurve}","page":"Basics","title":"infinity","text":"infinity(E::EllipticCurve) -> EllipticCurvePoint\n\nReturn the point at infinity with project coordinates 0 1 0.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/elliptic_curves/basics/#parent-Tuple{EllipticCurvePoint}","page":"Basics","title":"parent","text":"parent(P::EllipticCurvePoint) -> EllipticCurve\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/manual/elliptic_curves/basics/#is_on_curve-Tuple{EllipticCurve, Vector}","page":"Basics","title":"is_on_curve","text":"is_on_curve(E::EllipticCurve, 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/manual/elliptic_curves/basics/#+-Union{Tuple{T}, Tuple{EllipticCurvePoint{T}, EllipticCurvePoint{T}}} where T","page":"Basics","title":"+","text":"+(P::EllipticCurvePoint, Q::EllipticCurvePoint) -> EllipticCurvePoint\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/manual/elliptic_curves/basics/#division_points-Tuple{EllipticCurvePoint, Int64}","page":"Basics","title":"division_points","text":"division_points(P::EllipticCurvePoint, m::Int) -> EllipticCurvePoint\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{EllipticCurvePoint{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":"TropicalGeometry/curve/#Tropical-curves","page":"Tropical curves","title":"Tropical curves","text":"","category":"section"},{"location":"TropicalGeometry/curve/#Introduction","page":"Tropical curves","title":"Introduction","text":"","category":"section"},{"location":"TropicalGeometry/curve/","page":"Tropical curves","title":"Tropical curves","text":"A tropical curve is a graph with multiplicities on its edges. If embedded, it is a polyhedral complex of dimension (at most) one.","category":"page"},{"location":"TropicalGeometry/curve/#Note:","page":"Tropical curves","title":"Note:","text":"","category":"section"},{"location":"TropicalGeometry/curve/","page":"Tropical curves","title":"Tropical curves","text":"The type TropicalCurve can be thought of as subtype of TropicalVariety in the sense that it should have all properties and features of the latter.","category":"page"},{"location":"TropicalGeometry/curve/#Construction","page":"Tropical curves","title":"Construction","text":"","category":"section"},{"location":"TropicalGeometry/curve/","page":"Tropical curves","title":"Tropical curves","text":"In addition to converting from TropicalVariety, objects of type TropicalCurve can be constructed from:","category":"page"},{"location":"TropicalGeometry/curve/","page":"Tropical curves","title":"Tropical curves","text":"","category":"page"},{"location":"TropicalGeometry/curve/#Properties","page":"Tropical curves","title":"Properties","text":"","category":"section"},{"location":"TropicalGeometry/curve/","page":"Tropical curves","title":"Tropical curves","text":"In addition to the properties inherited from TropicalVariety, objects of type TropicalCurve have the following exclusive properties:","category":"page"},{"location":"TropicalGeometry/curve/","page":"Tropical curves","title":"Tropical curves","text":"graph(tc::TropicalCurve)","category":"page"},{"location":"TropicalGeometry/curve/#graph-Tuple{TropicalCurve}","page":"Tropical curves","title":"graph","text":"graph(f::AbsAffineSchemeMor)\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 x1, x2, x3\n over rational field\n by ideal (x1)\n\njulia> f = inclusion_morphism(X, Y)\nAffine scheme morphism\n from [x1, x2, x3] scheme(x1)\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> graph(f)\n(scheme(x1, -x1, x2 - x2, x3 - x3), Hom: scheme(x1, -x1, x2 - x2, x3 - x3) -> scheme(x1), Hom: scheme(x1, -x1, x2 - x2, x3 - x3) -> affine 3-space over QQ with coordinates [x1, x2, x3])\n\n\n\n\n\ngraph(TropC::TropicalCurve{minOrMax,false})\n\nReturn the graph of an abstract tropical curve TropC. Same as polyhedral_complex(tc).\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. [BJRR10*1]),\nvanishing sets of line bundle cohomology (cf. Appendix B of [Bie18]),\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 [CLS11]. 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 [CLS11].\nProvide support for coherent sheaves and their sheaf cohomologies. In particular, the existing algorithms in ToricVarieties_project (based on [Bie18]) 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":"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::NormalToricVarietyType, picard_class::FinGenAbGroupElem)\ntoric_line_bundle(v::NormalToricVarietyType, picard_class::Vector{T}) where {T <: IntegerUnion}\ntoric_line_bundle(v::NormalToricVarietyType, d::ToricDivisor)\ntoric_line_bundle(d::ToricDivisor)\ntoric_line_bundle(v::NormalToricVarietyType, dc::ToricDivisorClass)\ntoric_line_bundle(dc::ToricDivisorClass)","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/ToricLineBundles/#toric_line_bundle-Tuple{Union{AffineNormalToricVariety, CyclicQuotientSingularity, NormalToricVariety}, FinGenAbGroupElem}","page":"Toric Line Bundles","title":"toric_line_bundle","text":"toric_line_bundle(v::NormalToricVarietyType, picard_class::FinGenAbGroupElem)\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 toric variety\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{Union{AffineNormalToricVariety, CyclicQuotientSingularity, NormalToricVariety}, Vector{T}}} where T<:Union{Integer, ZZRingElem}","page":"Toric Line Bundles","title":"toric_line_bundle","text":"toric_line_bundle(v::NormalToricVarietyType, 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 toric variety\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{Union{AffineNormalToricVariety, CyclicQuotientSingularity, NormalToricVariety}, ToricDivisor}","page":"Toric Line Bundles","title":"toric_line_bundle","text":"toric_line_bundle(v::NormalToricVarietyType, 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 toric variety\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 toric variety\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{Union{AffineNormalToricVariety, CyclicQuotientSingularity, NormalToricVariety}, ToricDivisorClass}","page":"Toric Line Bundles","title":"toric_line_bundle","text":"toric_line_bundle(v::NormalToricVarietyType, 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 toric variety\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 toric variety\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::NormalToricVarietyType)\ncanonical_bundle(v::NormalToricVarietyType)\nstructure_sheaf(v::NormalToricVarietyType)\ntrivial_line_bundle(v::NormalToricVarietyType)","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/ToricLineBundles/#anticanonical_bundle-Tuple{Union{AffineNormalToricVariety, CyclicQuotientSingularity, NormalToricVariety}}","page":"Toric Line Bundles","title":"anticanonical_bundle","text":"anticanonical_bundle(v::NormalToricVarietyType)\n\nConstruct the anticanonical bundle of a normal toric variety.\n\nExamples\n\njulia> v = projective_space(NormalToricVariety, 2)\nNormal toric variety\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{Union{AffineNormalToricVariety, CyclicQuotientSingularity, NormalToricVariety}}","page":"Toric Line Bundles","title":"canonical_bundle","text":"canonical_bundle(v::NormalToricVarietyType)\n\nConstruct the canonical bundle of a normal toric variety.\n\nExamples\n\njulia> v = projective_space(NormalToricVariety, 2)\nNormal toric variety\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{Union{AffineNormalToricVariety, CyclicQuotientSingularity, NormalToricVariety}}","page":"Toric Line Bundles","title":"structure_sheaf","text":"structure_sheaf(v::NormalToricVarietyType)\n\nConstruct the structure sheaf of a normal toric variety.\n\nExamples\n\njulia> v = projective_space(NormalToricVariety, 2)\nNormal toric variety\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/#trivial_line_bundle-Tuple{Union{AffineNormalToricVariety, CyclicQuotientSingularity, NormalToricVariety}}","page":"Toric Line Bundles","title":"trivial_line_bundle","text":"trivial_line_bundle(v::NormalToricVarietyType)\n\nConstruct the trivial line bundle on a normal toric variety.\n\nExamples\n\njulia> v = projective_space(NormalToricVariety, 2)\nNormal toric variety\n\njulia> l = trivial_line_bundle(v)\nToric line bundle on a normal toric variety\n\njulia> is_trivial(l)\ntrue\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_ample(l::ToricLineBundle)\nis_basepoint_free(l::ToricLineBundle)\nis_immaculate(l::ToricLineBundle)\nis_very_ample(l::ToricLineBundle)","category":"page"},{"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 toric variety\n\njulia> is_ample(toric_line_bundle(F4, [1,0]))\nfalse\n\n\n\n\n\n","category":"method"},{"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 toric variety\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_immaculate-Tuple{ToricLineBundle}","page":"Toric Line Bundles","title":"is_immaculate","text":"is_immaculate(l::ToricLineBundle)\n\nReturn true if all sheaf cohomologies of l are trivial and false otherwise.\n\nExamples\n\njulia> F4 = hirzebruch_surface(NormalToricVariety, 4)\nNormal toric variety\n\njulia> l = toric_line_bundle(F4, [1,0])\nToric line bundle on a normal toric variety\n\njulia> is_immaculate(toric_line_bundle(F4, [1,0]))\nfalse\n\njulia> all_cohomologies(l)\n3-element Vector{ZZRingElem}:\n 2\n 0\n 0\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 toric variety\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 toric variety\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 toric variety\n\njulia> l = toric_line_bundle(v, [ZZRingElem(2)])\nToric line bundle on a normal toric variety\n\njulia> picard_class(l)\nAbelian group element [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 toric variety\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 toric variety\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 toric variety\n\njulia> l = toric_line_bundle(v, [ZZRingElem(2)])\nToric line bundle on a normal toric variety\n\njulia> toric_variety(l)\nNormal 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)\ngeneric_section(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 toric variety\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 toric variety\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/ToricLineBundles/#generic_section-Tuple{ToricLineBundle}","page":"Toric Line Bundles","title":"generic_section","text":"generic_section(l::ToricLineBundle)\n\nReturn a generic section of the toric line bundle l, that is return the sum of all elements basis_of_global_sections(l), each multiplied by a random integer.\n\nThe optional keyword argument range can be used to set the range of the random integers, e.g., generic_section(l, range = -100:100)\n\nExamples\n\njulia> v = projective_space(NormalToricVariety, 2)\nNormal toric variety\n\njulia> l = toric_line_bundle(v, [ZZRingElem(2)])\nToric line bundle on a normal toric variety\n\njulia> s = generic_section(l);\n\njulia> parent(s) == cox_ring(toric_variety(l))\ntrue\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::NormalToricVarietyType, p::MPolyQuoRingElem)\ncohomology_class(d::ToricDivisor)\ncohomology_class(c::ToricDivisorClass)\ncohomology_class(l::ToricLineBundle)","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/CohomologyClasses/#cohomology_class-Tuple{Union{AffineNormalToricVariety, CyclicQuotientSingularity, NormalToricVariety}, MPolyQuoRingElem}","page":"Cohomology Classes","title":"cohomology_class","text":"cohomology_class(v::NormalToricVarietyType, 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 toric variety\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 toric variety\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 toric variety\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 toric variety\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 toric variety\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, simplicial, complete toric variety\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 toric variety\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 toric variety\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 toric variety\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 toric variety\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 generated by\n x1*x3\n x1*x5\n x2*x4\n x2*x5\n x3*x4\n x1 + x2 - x5\n 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 x1, x2, x3, x4, x5\n over rational field\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; check::Bool = true)","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/CohomologyClasses/#integrate-Tuple{CohomologyClass}","page":"Cohomology Classes","title":"integrate","text":"integrate(c::CohomologyClass; check::Bool = true)\n\nIntegrate the cohomolgy class c over the normal toric variety toric_variety(c).\n\nThe theory underlying this method requires that the toric variety in question is simplicial and complete. The check of completeness may take a long time to complete. If desired, this can be switched off by setting the optional argument check to the value false.\n\nExamples\n\njulia> dP3 = del_pezzo_surface(NormalToricVariety, 3)\nNormal toric variety\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 toric variety\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 = incidence_matrix([[1,3,4], [1,3,5], [1,4,5], [2,3,4], [2,3,5], [2,4,5]]);\n\njulia> X = normal_toric_variety(max_cones, ray_generators; 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 multivariate polynomial ring in 5 variables over QQ graded by\n x1 -> [1]\n x2 -> [1]\n x3 -> [1]\n x4 -> [1]\n x5 -> [1]\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::NormalToricVarietyType; check::Bool = true)\nvolume_form(v::NormalToricVariety)\nintersection_form(v::NormalToricVariety)\nchern_class(v::NormalToricVariety, k::Int; check::Bool = true)\nchern_classes(v::NormalToricVariety; check::Bool = true)","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/CohomologyClasses/#cohomology_ring-Tuple{Union{AffineNormalToricVariety, CyclicQuotientSingularity, NormalToricVariety}}","page":"Cohomology Classes","title":"cohomology_ring","text":"cohomology_ring(v::NormalToricVarietyType; check::Bool = true)\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 toric variety\n\njulia> length(intersection_form(F3))\n10\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/CohomologyClasses/#chern_class-Tuple{NormalToricVariety, Int64}","page":"Cohomology Classes","title":"chern_class","text":"chern_class(v::NormalToricVariety, k::Int; check::Bool = true)\n\nComputes the k-th Chern class of the tangent bundle of a normal toric variety that is both smooth and complete. Since these checks can be computationally very demanding, we provide an optional argument check. Once set to false, this method skips those tests.\n\nThe implemented algorithm uses proposition 13.1.2 in [CLS11].\n\nExamples\n\njulia> F3 = hirzebruch_surface(NormalToricVariety, 3)\nNormal toric variety\n\njulia> chern_class(F3, 0)\nCohomology class on a normal toric variety given by 1\n\njulia> chern_class(F3, 1, check = false)\nCohomology class on a normal toric variety given by t1 + x1 + t2 + x2\n\njulia> integrate(chern_class(F3, 2), check = false)\n4\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/CohomologyClasses/#chern_classes-Tuple{NormalToricVariety}","page":"Cohomology Classes","title":"chern_classes","text":"chern_classes(v::NormalToricVariety; check::Bool = true)\n\nComputes all Chern classes of the tangent bundle of a normal toric variety, which is smooth and complete. Since those checks can be computationally very demanding, the optional argument check can be set to false to skip those tests.\n\nExamples\n\njulia> F3 = hirzebruch_surface(NormalToricVariety, 3)\nNormal toric variety\n\njulia> cs = chern_classes(F3)\n3-element Vector{CohomologyClass}:\n Cohomology class on a normal toric variety given by 1\n Cohomology class on a normal toric variety given by t1 + x1 + t2 + x2\n Cohomology class on a normal toric variety given by 4//3*x2^2\n\njulia> integrate(cs[3])\n4\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::FPModule{T}, gens::Vector{<: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 = free_module(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 = vector_space(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 = free_module(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 = vector_space(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":"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":"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 = free_module(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":"Experimental/AlgebraicStatistics/phylogenetics/","page":"Algebraic Phylogenetics","title":"Algebraic Phylogenetics","text":"CurrentModule = Oscar\nDocTestSetup = Oscar.doctestsetup()","category":"page"},{"location":"Experimental/AlgebraicStatistics/phylogenetics/#Algebraic-Phylogenetics","page":"Algebraic Phylogenetics","title":"Algebraic Phylogenetics","text":"","category":"section"},{"location":"Experimental/AlgebraicStatistics/phylogenetics/","page":"Algebraic Phylogenetics","title":"Algebraic Phylogenetics","text":"The Algebraic Phylogenetics part of OSCAR provides functionality for","category":"page"},{"location":"Experimental/AlgebraicStatistics/phylogenetics/","page":"Algebraic Phylogenetics","title":"Algebraic Phylogenetics","text":"specifying phylogenetic models\nparametrizing such models\ncalculating their algebraic invariants","category":"page"},{"location":"Experimental/AlgebraicStatistics/phylogenetics/#Models","page":"Algebraic Phylogenetics","title":"Models","text":"","category":"section"},{"location":"Experimental/AlgebraicStatistics/phylogenetics/","page":"Algebraic Phylogenetics","title":"Algebraic Phylogenetics","text":"The five most common models in algebraic phylogenetics can automatically be specified by calling the below functions, each taking a tree as input and attaching transition matrices to its edges as defined by Jukes Cantor, Kimura, etc., respectively, returning a structure PhylogeneticModel or GroupBasedPhylogeneticModel.","category":"page"},{"location":"Experimental/AlgebraicStatistics/phylogenetics/","page":"Algebraic Phylogenetics","title":"Algebraic Phylogenetics","text":"cavender_farris_neyman_model(graph::Graph{Directed})\njukes_cantor_model(graph::Graph{Directed})\nkimura2_model(graph::Graph{Directed})\nkimura3_model(graph::Graph{Directed})\ngeneral_markov_model(graph::Graph{Directed})","category":"page"},{"location":"Experimental/AlgebraicStatistics/phylogenetics/#cavender_farris_neyman_model-Tuple{Graph{Directed}}","page":"Algebraic Phylogenetics","title":"cavender_farris_neyman_model","text":"cavender_farris_neyman_model(graph::Graph{Directed})\n\nCreates a PhylogeneticModel based on graph whose transition matrices are of type Cavender-Farris-Neyman. \n\nExamples\n\njulia> cavender_farris_neyman_model(graph_from_edges(Directed,[[4,1],[4,2],[4,3]]))\nGroup-based phylogenetic model on a tree with 3 leaves and 3 edges \n with distribution at the root [1//2, 1//2]. \n The transition matrix associated to edge i is of the form \n [a[i] b[i];\n b[i] a[i]], \n and the Fourier parameters are [x[i, 1] x[i, 2]].\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/AlgebraicStatistics/phylogenetics/#jukes_cantor_model-Tuple{Graph{Directed}}","page":"Algebraic Phylogenetics","title":"jukes_cantor_model","text":"jukes_cantor_model(graph::Graph{Directed})\n\nCreates a PhylogeneticModel based on graph whose transition matrices are Jukes Cantor matrices. \n\nExamples\n\njulia> jukes_cantor_model(graph_from_edges(Directed,[[4,1],[4,2],[4,3]]))\nGroup-based phylogenetic model on a tree with 3 leaves and 3 edges \n with distribution at the root [1//4, 1//4, 1//4, 1//4]. \n The transition matrix associated to edge i is of the form \n [a[i] b[i] b[i] b[i];\n b[i] a[i] b[i] b[i];\n b[i] b[i] a[i] b[i];\n b[i] b[i] b[i] a[i]], \n and the Fourier parameters are [x[i, 1] x[i, 2] x[i, 2] x[i, 2]].\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/AlgebraicStatistics/phylogenetics/#kimura2_model-Tuple{Graph{Directed}}","page":"Algebraic Phylogenetics","title":"kimura2_model","text":"kimura2_model(graph::Graph{Directed})\n\nCreates a PhylogeneticModel based on graph whose transition matrices are Kimura 2-parameter matrices. \n\nExamples\n\njulia> kimura2_model(graph_from_edges(Directed,[[4,1],[4,2],[4,3]]))\nGroup-based phylogenetic model on a tree with 3 leaves and 3 edges\n with distribution at the root [1//4, 1//4, 1//4, 1//4]. \n The transition matrix associated to edge i is of the form \n [a[i] b[i] c[i] b[i];\n b[i] a[i] b[i] c[i];\n c[i] b[i] a[i] b[i];\n b[i] c[i] b[i] a[i]], \n and the Fourier parameters are [x[i, 1] x[i, 3] x[i, 2] x[i, 2]].\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/AlgebraicStatistics/phylogenetics/#kimura3_model-Tuple{Graph{Directed}}","page":"Algebraic Phylogenetics","title":"kimura3_model","text":"kimura3_model(graph::Graph{Directed})\n\nCreates a PhylogeneticModel based on graph whose transition matrices are Kimura 3-parameter matrices. \n\nExamples\n\njulia> kimura3_model(graph_from_edges(Directed,[[4,1],[4,2],[4,3]]))\nGroup-based phylogenetic model on a tree with 3 leaves and 3 edges \n with distribution at the root [1//4, 1//4, 1//4, 1//4]. \n The transition matrix associated to edge i is of the form \n [a[i] b[i] c[i] d[i];\n b[i] a[i] d[i] c[i];\n c[i] d[i] a[i] b[i];\n d[i] c[i] b[i] a[i]], \n and the Fourier parameters are [x[i, 1] x[i, 2] x[i, 3] x[i, 4]].\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/AlgebraicStatistics/phylogenetics/#general_markov_model-Tuple{Graph{Directed}}","page":"Algebraic Phylogenetics","title":"general_markov_model","text":"general_markov_model(graph::Graph{Directed})\n\nCreates a PhylogeneticModel based on graph whose transition matrices are stochastic with no further constraints. \n\nExamples\n\njulia> general_markov_model(graph_from_edges(Directed,[[4,1],[4,2],[4,3]]))\nPhylogenetic model on a tree with 3 leaves and 3 edges \n with distribution at the root [π[1], π[2], π[3], π[4]] \n and transition matrix associated to edge i of the form \n [m[i, 1, 1] m[i, 1, 2] m[i, 1, 3] m[i, 1, 4];\n m[i, 2, 1] m[i, 2, 2] m[i, 2, 3] m[i, 2, 4];\n m[i, 3, 1] m[i, 3, 2] m[i, 3, 3] m[i, 3, 4];\n m[i, 4, 1] m[i, 4, 2] m[i, 4, 3] m[i, 4, 4]].\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/AlgebraicStatistics/phylogenetics/","page":"Algebraic Phylogenetics","title":"Algebraic Phylogenetics","text":"The models are by default in projective space. For their affine versions, call","category":"page"},{"location":"Experimental/AlgebraicStatistics/phylogenetics/","page":"Algebraic Phylogenetics","title":"Algebraic Phylogenetics","text":"affine_phylogenetic_model!(pm::PhylogeneticModel)","category":"page"},{"location":"Experimental/AlgebraicStatistics/phylogenetics/#affine_phylogenetic_model!-Tuple{PhylogeneticModel}","page":"Algebraic Phylogenetics","title":"affine_phylogenetic_model!","text":"affine_phylogenetic_model!(pm::PhylogeneticModel)\n\nMoves a PhylogeneticModel or GroupBasedPhylogeneticModel from projective into affine space.\n\nExamples\n\njulia> pm = jukes_cantor_model(graph_from_edges(Directed,[[4,1],[4,2],[4,3]]));\n\njulia> affine_phylogenetic_model!(pm)\nGroup-based phylogenetic model on a tree with 3 leaves and 3 edges\n with distribution at the root [1//4, 1//4, 1//4, 1//4].\n The transition matrix associated to edge i is of the form\n [-3*b[i]+1 b[i] b[i] b[i];\n b[i] -3*b[i]+1 b[i] b[i];\n b[i] b[i] -3*b[i]+1 b[i];\n b[i] b[i] b[i] -3*b[i]+1],\n and the Fourier parameters are [1 x[i, 2] x[i, 2] x[i, 2]].\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/AlgebraicStatistics/phylogenetics/#Components-of-a-model","page":"Algebraic Phylogenetics","title":"Components of a model","text":"","category":"section"},{"location":"Experimental/AlgebraicStatistics/phylogenetics/","page":"Algebraic Phylogenetics","title":"Algebraic Phylogenetics","text":"PhylogeneticModel specifies any phylogenetic tree model in probability coordinates and GroupBasedPhylogeneticModel can specify group-based, e.g. Fourier, coordinates. For any model, we can call its graph, transition matrices attached to the graph's edges, the number of states of each vertex random variable, and the corresponding polynomial rings. For instance for Jukes Cantor on the star with three leaves:","category":"page"},{"location":"Experimental/AlgebraicStatistics/phylogenetics/","page":"Algebraic Phylogenetics","title":"Algebraic Phylogenetics","text":"graph(pm::PhylogeneticModel)\ntransition_matrices(pm::PhylogeneticModel)\nnumber_states(pm::PhylogeneticModel)\nprobability_ring(pm::PhylogeneticModel)\nfourier_ring(pm::GroupBasedPhylogeneticModel)\nfourier_parameters(pm::GroupBasedPhylogeneticModel)\ngroup_of_model(pm::GroupBasedPhylogeneticModel)","category":"page"},{"location":"Experimental/AlgebraicStatistics/phylogenetics/#graph-Tuple{PhylogeneticModel}","page":"Algebraic Phylogenetics","title":"graph","text":"graph(pm::PhylogeneticModel)\n\nReturn the graph of a PhylogeneticModel pm.\n\nExamples\n\njulia> pm = jukes_cantor_model(graph_from_edges(Directed,[[4,1],[4,2],[4,3]]));\n\njulia> graph(pm)\nDirected graph with 4 nodes and the following edges:\n(4, 1)(4, 2)(4, 3)\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/AlgebraicStatistics/phylogenetics/#transition_matrices-Tuple{PhylogeneticModel}","page":"Algebraic Phylogenetics","title":"transition_matrices","text":"transition_matrices(pm::PhylogeneticModel)\n\nReturn a dictionary between the edges of the tree specifying the PhylogeneticModel pm and their attached transition matrices.\n\nExamples\n\njulia> pm = jukes_cantor_model(graph_from_edges(Directed,[[4,1],[4,2],[4,3]]));\n\njulia> transition_matrices(pm)\nDict{Edge, MatElem{QQMPolyRingElem}} with 3 entries:\n Edge(4, 1) => [a[1] b[1] b[1] b[1]; b[1] a[1] b[1] b[1]; b[1] b[1] a[1] b[1];…\n Edge(4, 2) => [a[2] b[2] b[2] b[2]; b[2] a[2] b[2] b[2]; b[2] b[2] a[2] b[2];…\n Edge(4, 3) => [a[3] b[3] b[3] b[3]; b[3] a[3] b[3] b[3]; b[3] b[3] a[3] b[3];…\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/AlgebraicStatistics/phylogenetics/#number_states-Tuple{PhylogeneticModel}","page":"Algebraic Phylogenetics","title":"number_states","text":"number_states(pm::PhylogeneticModel)\n\nReturn the number of states of the PhylogeneticModel pm.\n\nExamples\n\njulia> pm = jukes_cantor_model(graph_from_edges(Directed,[[4,1],[4,2],[4,3]]));\n\njulia> number_states(pm)\n4\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/AlgebraicStatistics/phylogenetics/#probability_ring-Tuple{PhylogeneticModel}","page":"Algebraic Phylogenetics","title":"probability_ring","text":"probability_ring(pm::PhylogeneticModel)\n\nReturn the ring of probability coordinates of the PhylogeneticModel pm.\n\nExamples\n\njulia> pm = jukes_cantor_model(graph_from_edges(Directed,[[4,1],[4,2],[4,3]]));\n\njulia> probability_ring(pm)\nMultivariate polynomial ring in 6 variables a[1], a[2], a[3], b[1], ..., b[3]\n over rational field\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/AlgebraicStatistics/phylogenetics/#fourier_ring-Tuple{GroupBasedPhylogeneticModel}","page":"Algebraic Phylogenetics","title":"fourier_ring","text":"fourier_ring(pm::GroupBasedPhylogeneticModel)\n\nReturn the ring of Fourier coordinates of the PhylogeneticModel pm.\n\nExamples\n\njulia> pm = jukes_cantor_model(graph_from_edges(Directed,[[4,1],[4,2],[4,3]]));\n\njulia> fourier_ring(pm)\nMultivariate polynomial ring in 6 variables x[1, 1], x[2, 1], x[3, 1], x[1, 2], ..., x[3, 2]\n over rational field\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/AlgebraicStatistics/phylogenetics/#fourier_parameters-Tuple{GroupBasedPhylogeneticModel}","page":"Algebraic Phylogenetics","title":"fourier_parameters","text":"fourier_parameters(pm::GroupBasedPhylogeneticModel)\n\nReturn the Fourier parameters of the GroupBasedPhylogeneticModel pm as a vector of eigenvalues of the transition matrices.\n\nExamples\n\njulia> pm = jukes_cantor_model(graph_from_edges(Directed,[[4,1],[4,2],[4,3]]));\n\njulia> fourier_parameters(pm)\nDict{Edge, Vector{QQMPolyRingElem}} with 3 entries:\n Edge(4, 1) => [x[1, 1], x[1, 2], x[1, 2], x[1, 2]]\n Edge(4, 2) => [x[2, 1], x[2, 2], x[2, 2], x[2, 2]]\n Edge(4, 3) => [x[3, 1], x[3, 2], x[3, 2], x[3, 2]]\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/AlgebraicStatistics/phylogenetics/#group_of_model-Tuple{GroupBasedPhylogeneticModel}","page":"Algebraic Phylogenetics","title":"group_of_model","text":"group_of_model(pm::GroupBasedPhylogeneticModel)\n\nReturns the group the GroupBasedPhylogeneticModel pm is based on.\n\nExamples\n\njulia> pm = jukes_cantor_model(graph_from_edges(Directed,[[4,1],[4,2],[4,3]]));\n\njulia> group_of_model(pm)\n4-element Vector{FinGenAbGroupElem}:\n [0, 0]\n [0, 1]\n [1, 0]\n [1, 1]\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/AlgebraicStatistics/phylogenetics/#Parametrization","page":"Algebraic Phylogenetics","title":"Parametrization","text":"","category":"section"},{"location":"Experimental/AlgebraicStatistics/phylogenetics/","page":"Algebraic Phylogenetics","title":"Algebraic Phylogenetics","text":"For each phylogenetic model, we can calculate the parametrization, a map from transition matrices to probabilities, parametrized in probability or Fourier coordinates. For group-based models, we can reparametrize between these and return the transformation matrix, and we can calculate equivalence classes of probabilities with the same parametrization.","category":"page"},{"location":"Experimental/AlgebraicStatistics/phylogenetics/","page":"Algebraic Phylogenetics","title":"Algebraic Phylogenetics","text":"probability_map(pm::PhylogeneticModel)\nfourier_map(pm::GroupBasedPhylogeneticModel)\ncompute_equivalent_classes(parametrization::Dict{Tuple{Vararg{Int64}}, QQMPolyRingElem})\nsum_equivalent_classes(equivalent_classes::NamedTuple{(:parametrization, :classes), Tuple{Dict{Tuple{Vararg{Int64}}, QQMPolyRingElem}, Dict{Tuple{Vararg{Int64}}, Vector{Tuple{Vararg{Int64}}}}}})\nspecialized_fourier_transform(pm::GroupBasedPhylogeneticModel, p_classes::Dict{Tuple{Vararg{Int64}}, Vector{Tuple{Vararg{Int64}}}}, q_classes::Dict{Tuple{Vararg{Int64}}, Vector{Tuple{Vararg{Int64}}}})\ninverse_specialized_fourier_transform(pm::GroupBasedPhylogeneticModel, p_classes::Dict{Tuple{Vararg{Int64}}, Vector{Tuple{Vararg{Int64}}}}, q_classes::Dict{Tuple{Vararg{Int64}}, Vector{Tuple{Vararg{Int64}}}})","category":"page"},{"location":"Experimental/AlgebraicStatistics/phylogenetics/#probability_map-Tuple{PhylogeneticModel}","page":"Algebraic Phylogenetics","title":"probability_map","text":"probability_map(pm::PhylogeneticModel)\n\nCreate a parametrization for a PhylogeneticModel of type Dictionary.\n\nIterate through all possible states of the leaf random variables and calculates their corresponding probabilities using the root distribution and laws of conditional independence. Return a dictionary of polynomials indexed by the states. Use auxiliary function monomial_parametrization(pm::PhylogeneticModel, states::Dict{Int, Int}) and probability_parametrization(pm::PhylogeneticModel, leaves_states::Vector{Int}). \n\nExamples\n\njulia> pm = jukes_cantor_model(graph_from_edges(Directed,[[4,1],[4,2],[4,3]]));\n\njulia> p = probability_map(pm)\nDict{Tuple{Vararg{Int64}}, QQMPolyRingElem} with 64 entries:\n (1, 2, 1) => 1//4*a[1]*a[3]*b[2] + 1//4*a[2]*b[1]*b[3] + 1//2*b[1]*b[2]*b[3]\n (3, 1, 1) => 1//4*a[1]*b[2]*b[3] + 1//4*a[2]*a[3]*b[1] + 1//2*b[1]*b[2]*b[3]\n (4, 4, 2) => 1//4*a[1]*a[2]*b[3] + 1//4*a[3]*b[1]*b[2] + 1//2*b[1]*b[2]*b[3]\n (1, 2, 3) => 1//4*a[1]*b[2]*b[3] + 1//4*a[2]*b[1]*b[3] + 1//4*a[3]*b[1]*b[2] …\n (3, 1, 3) => 1//4*a[1]*a[3]*b[2] + 1//4*a[2]*b[1]*b[3] + 1//2*b[1]*b[2]*b[3]\n (3, 2, 4) => 1//4*a[1]*b[2]*b[3] + 1//4*a[2]*b[1]*b[3] + 1//4*a[3]*b[1]*b[2] …\n (3, 2, 1) => 1//4*a[1]*b[2]*b[3] + 1//4*a[2]*b[1]*b[3] + 1//4*a[3]*b[1]*b[2] …\n (2, 1, 4) => 1//4*a[1]*b[2]*b[3] + 1//4*a[2]*b[1]*b[3] + 1//4*a[3]*b[1]*b[2] …\n (3, 2, 3) => 1//4*a[1]*a[3]*b[2] + 1//4*a[2]*b[1]*b[3] + 1//2*b[1]*b[2]*b[3]\n (2, 1, 1) => 1//4*a[1]*b[2]*b[3] + 1//4*a[2]*a[3]*b[1] + 1//2*b[1]*b[2]*b[3]\n (1, 3, 2) => 1//4*a[1]*b[2]*b[3] + 1//4*a[2]*b[1]*b[3] + 1//4*a[3]*b[1]*b[2] …\n (1, 4, 2) => 1//4*a[1]*b[2]*b[3] + 1//4*a[2]*b[1]*b[3] + 1//4*a[3]*b[1]*b[2] …\n (2, 1, 3) => 1//4*a[1]*b[2]*b[3] + 1//4*a[2]*b[1]*b[3] + 1//4*a[3]*b[1]*b[2] …\n (2, 2, 4) => 1//4*a[1]*a[2]*b[3] + 1//4*a[3]*b[1]*b[2] + 1//2*b[1]*b[2]*b[3]\n (4, 3, 4) => 1//4*a[1]*a[3]*b[2] + 1//4*a[2]*b[1]*b[3] + 1//2*b[1]*b[2]*b[3]\n (2, 2, 1) => 1//4*a[1]*a[2]*b[3] + 1//4*a[3]*b[1]*b[2] + 1//2*b[1]*b[2]*b[3]\n (4, 4, 4) => 1//4*a[1]*a[2]*a[3] + 3//4*b[1]*b[2]*b[3]\n (4, 3, 1) => 1//4*a[1]*b[2]*b[3] + 1//4*a[2]*b[1]*b[3] + 1//4*a[3]*b[1]*b[2] …\n (3, 3, 2) => 1//4*a[1]*a[2]*b[3] + 1//4*a[3]*b[1]*b[2] + 1//2*b[1]*b[2]*b[3]\n ⋮ => ⋮\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/AlgebraicStatistics/phylogenetics/#fourier_map-Tuple{GroupBasedPhylogeneticModel}","page":"Algebraic Phylogenetics","title":"fourier_map","text":"fourier_map(pm::GroupBasedPhylogeneticModel)\n\nCreate a parametrization for a GroupBasedPhylogeneticModel of type Dictionary.\n\nIterate through all possible states of the leaf random variables and calculates their corresponding probabilities using group actions and laws of conditional independence. Return a dictionary of polynomials indexed by the states. Use auxiliary function monomial_fourier(pm::GroupBasedPhylogeneticModel, leaves_states::Vector{Int}) and fourier_parametrization(pm::GroupBasedPhylogeneticModel, leaves_states::Vector{Int}). \n\nExamples\n\njulia> pm = jukes_cantor_model(graph_from_edges(Directed,[[4,1],[4,2],[4,3]]));\n\njulia> q = fourier_map(pm)\nDict{Tuple{Vararg{Int64}}, QQMPolyRingElem} with 64 entries:\n (1, 2, 1) => 0\n (3, 1, 1) => 0\n (4, 4, 2) => 0\n (1, 2, 3) => 0\n (3, 1, 3) => x[2, 1]*x[1, 2]*x[3, 2]\n (3, 2, 4) => x[1, 2]*x[2, 2]*x[3, 2]\n (3, 2, 1) => 0\n (2, 1, 4) => 0\n (3, 2, 3) => 0\n (2, 1, 1) => 0\n (1, 3, 2) => 0\n (1, 4, 2) => 0\n (2, 1, 3) => 0\n (2, 2, 4) => 0\n (4, 3, 4) => 0\n (2, 2, 1) => x[3, 1]*x[1, 2]*x[2, 2]\n (4, 4, 4) => 0\n (4, 3, 1) => 0\n (3, 3, 2) => 0\n ⋮ => ⋮\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/AlgebraicStatistics/phylogenetics/#compute_equivalent_classes-Tuple{Dict{Tuple{Vararg{Int64}}, QQMPolyRingElem}}","page":"Algebraic Phylogenetics","title":"compute_equivalent_classes","text":"compute_equivalent_classes(parametrization::Dict{Tuple{Vararg{Int64}}, QQMPolyRingElem})\n\nGiven the parametrization of a PhylogeneticModel, cancel all duplicate entries and return equivalence classes of states which are attached the same probabilities.\n\nExamples\n\njulia> pm = jukes_cantor_model(graph_from_edges(Directed,[[4,1],[4,2],[4,3]]));\n\njulia> p = probability_map(pm);\n\njulia> q = fourier_map(pm);\n\njulia> p_equivclasses = compute_equivalent_classes(p);\n\njulia> p_equivclasses.parametrization\nDict{Tuple{Vararg{Int64}}, QQMPolyRingElem} with 5 entries:\n (1, 2, 1) => 1//4*a[1]*a[3]*b[2] + 1//4*a[2]*b[1]*b[3] + 1//2*b[1]*b[2]*b[3]\n (1, 1, 1) => 1//4*a[1]*a[2]*a[3] + 3//4*b[1]*b[2]*b[3]\n (1, 2, 2) => 1//4*a[1]*b[2]*b[3] + 1//4*a[2]*a[3]*b[1] + 1//2*b[1]*b[2]*b[3]\n (1, 2, 3) => 1//4*a[1]*b[2]*b[3] + 1//4*a[2]*b[1]*b[3] + 1//4*a[3]*b[1]*b[2] …\n (1, 1, 2) => 1//4*a[1]*a[2]*b[3] + 1//4*a[3]*b[1]*b[2] + 1//2*b[1]*b[2]*b[3]\n\njulia> p_equivclasses.classes\nDict{Tuple{Vararg{Int64}}, Vector{Tuple{Vararg{Int64}}}} with 5 entries:\n (1, 2, 1) => [(1, 2, 1), (1, 3, 1), (1, 4, 1), (2, 1, 2), (2, 3, 2), (2, 4, 2…\n (1, 1, 1) => [(1, 1, 1), (2, 2, 2), (3, 3, 3), (4, 4, 4)]\n (1, 2, 2) => [(1, 2, 2), (1, 3, 3), (1, 4, 4), (2, 1, 1), (2, 3, 3), (2, 4, 4…\n (1, 2, 3) => [(1, 2, 3), (1, 2, 4), (1, 3, 2), (1, 3, 4), (1, 4, 2), (1, 4, 3…\n (1, 1, 2) => [(1, 1, 2), (1, 1, 3), (1, 1, 4), (2, 2, 1), (2, 2, 3), (2, 2, 4…\n\njulia> q_equivclasses = compute_equivalent_classes(q);\n\njulia> q_equivclasses.parametrization\nDict{Tuple{Vararg{Int64}}, QQMPolyRingElem} with 5 entries:\n (1, 1, 1) => x[1, 1]*x[2, 1]*x[3, 1]\n (2, 3, 4) => x[1, 2]*x[2, 2]*x[3, 2]\n (2, 2, 1) => x[3, 1]*x[1, 2]*x[2, 2]\n (1, 2, 2) => x[1, 1]*x[2, 2]*x[3, 2]\n (2, 1, 2) => x[2, 1]*x[1, 2]*x[3, 2]\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/AlgebraicStatistics/phylogenetics/#sum_equivalent_classes-Tuple{@NamedTuple{parametrization::Dict{Tuple{Vararg{Int64}}, QQMPolyRingElem}, classes::Dict{Tuple{Vararg{Int64}}, Vector{Tuple{Vararg{Int64}}}}}}","page":"Algebraic Phylogenetics","title":"sum_equivalent_classes","text":"sum_equivalent_classes(equivalent_classes::NamedTuple{(:parametrization, :classes), Tuple{Dict{Tuple{Vararg{Int64}}, QQMPolyRingElem}, Dict{Tuple{Vararg{Int64}}, Vector{Tuple{Vararg{Int64}}}}}})\n\nTake the output of the function compute_equivalent_classes for PhylogeneticModel and multiply by a factor to obtain probabilities as specified on the original small trees database.\n\nExamples\n\njulia> pm = jukes_cantor_model(graph_from_edges(Directed,[[4,1],[4,2],[4,3]]));\n\njulia> p = probability_map(pm);\n\njulia> p_equivclasses = compute_equivalent_classes(p);\n\njulia> sum_equivalent_classes(p_equivclasses)\nDict{Tuple{Int64, Int64, Int64}, QQMPolyRingElem} with 5 entries:\n (1, 2, 1) => 3*a[1]*a[3]*b[2] + 3*a[2]*b[1]*b[3] + 6*b[1]*b[2]*b[3]\n (1, 1, 1) => a[1]*a[2]*a[3] + 3*b[1]*b[2]*b[3]\n (1, 2, 2) => 3*a[1]*b[2]*b[3] + 3*a[2]*a[3]*b[1] + 6*b[1]*b[2]*b[3]\n (1, 2, 3) => 6*a[1]*b[2]*b[3] + 6*a[2]*b[1]*b[3] + 6*a[3]*b[1]*b[2] + 6*b[1]*…\n (1, 1, 2) => 3*a[1]*a[2]*b[3] + 3*a[3]*b[1]*b[2] + 6*b[1]*b[2]*b[3]\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/AlgebraicStatistics/phylogenetics/#specialized_fourier_transform-Tuple{GroupBasedPhylogeneticModel, Dict{Tuple{Vararg{Int64}}, Vector{Tuple{Vararg{Int64}}}}, Dict{Tuple{Vararg{Int64}}, Vector{Tuple{Vararg{Int64}}}}}","page":"Algebraic Phylogenetics","title":"specialized_fourier_transform","text":"specialized_fourier_transform(pm::GroupBasedPhylogeneticModel, p_classes::Dict{Tuple{Vararg{Int64}}, Vector{Tuple{Vararg{Int64}}}}, q_classes::Dict{Tuple{Vararg{Int64}}, Vector{Tuple{Vararg{Int64}}}})\n\nReparametrize between a model specification in terms of probability and Fourier cooordinates. The input of equivalent classes is optional, if they are not entered they will be computed.\n\nExamples\n\njulia> pm = jukes_cantor_model(graph_from_edges(Directed,[[4,1],[4,2],[4,3]]));\n\njulia> p_equivclasses = compute_equivalent_classes(probability_map(pm));\n\njulia> q_equivclasses = compute_equivalent_classes(fourier_map(pm));\n\njulia> specialized_fourier_transform(pm, p_equivclasses.classes, q_equivclasses.classes)\n5×5 Matrix{QQMPolyRingElem}:\n 1 1 1 1 1\n 1 -1//3 -1//3 1 -1//3\n 1 -1//3 1 -1//3 -1//3\n 1 1 -1//3 -1//3 -1//3\n 1 -1//3 -1//3 -1//3 1//3\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/AlgebraicStatistics/phylogenetics/#inverse_specialized_fourier_transform-Tuple{GroupBasedPhylogeneticModel, Dict{Tuple{Vararg{Int64}}, Vector{Tuple{Vararg{Int64}}}}, Dict{Tuple{Vararg{Int64}}, Vector{Tuple{Vararg{Int64}}}}}","page":"Algebraic Phylogenetics","title":"inverse_specialized_fourier_transform","text":"inverse_specialized_fourier_transform(pm::GroupBasedPhylogeneticModel, p_classes::Dict{Tuple{Vararg{Int64}}, Vector{Tuple{Vararg{Int64}}}}, q_classes::Dict{Tuple{Vararg{Int64}}, Vector{Tuple{Vararg{Int64}}}})\n\nReparametrize between a model specification in terms of Fourier and probability cooordinates.\n\nExamples\n\njulia> pm = jukes_cantor_model(graph_from_edges(Directed,[[4,1],[4,2],[4,3]]));\n\njulia> p_equivclasses = compute_equivalent_classes(probability_map(pm));\n\njulia> q_equivclasses = compute_equivalent_classes(fourier_map(pm));\n\njulia> inverse_specialized_fourier_transform(pm, p_equivclasses.classes, q_equivclasses.classes)\n5×5 Matrix{QQMPolyRingElem}:\n 1//16 3//16 3//16 3//16 3//8\n 3//16 -3//16 -3//16 9//16 -3//8\n 3//16 -3//16 9//16 -3//16 -3//8\n 3//16 9//16 -3//16 -3//16 -3//8\n 3//8 -3//8 -3//8 -3//8 3//4\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/AlgebraicStatistics/phylogenetics/#Contact","page":"Algebraic Phylogenetics","title":"Contact","text":"","category":"section"},{"location":"Experimental/AlgebraicStatistics/phylogenetics/","page":"Algebraic Phylogenetics","title":"Algebraic Phylogenetics","text":"Please direct questions about this part of OSCAR to the following people:","category":"page"},{"location":"Experimental/AlgebraicStatistics/phylogenetics/","page":"Algebraic Phylogenetics","title":"Algebraic Phylogenetics","text":"Marina Garrote López,\npossibly others.","category":"page"},{"location":"Experimental/AlgebraicStatistics/phylogenetics/","page":"Algebraic Phylogenetics","title":"Algebraic Phylogenetics","text":"You can ask questions in the OSCAR Slack. Alternatively, you can raise an issue on github.","category":"page"},{"location":"PolyhedralGeometry/linear_programs/","page":"Linear Programs","title":"Linear Programs","text":"CurrentModule = Oscar\nDocTestSetup = Oscar.doctestsetup()","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)\nPolytope 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 in P}\nwhere P is a Polyhedron{QQFieldElem} and\n c=QQFieldElem[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":"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)\nambient_dim(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/#ambient_dim-Tuple{LinearProgram}","page":"Linear Programs","title":"ambient_dim","text":"ambient_dim(LP::LinearProgram)\n\nReturn the ambient dimension of the feasible reagion of LP.\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 or the feasible region is empty, m may be infinity, -infinity, or nothing 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 -infinity or infinity depending on convention, or nothing if the feasible region is empty.\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)\nPolytope in ambient dimension 3\n\njulia> LP=linear_program(C,[1,2,-3]; convention = :min)\nLinear program\n min{c*x + k | x in P}\nwhere P is a Polyhedron{QQFieldElem} and\n c=QQFieldElem[1, 2, -3]\n k=0\n\njulia> optimal_value(LP)\n-6\n\nOptimizing in an unbounded direction yields infinity.\n\njulia> lp = linear_program(convex_hull([0 0], [1 0; 0 1]), [1, 1])\nLinear program\n max{c*x + k | x in P}\nwhere P is a Polyhedron{QQFieldElem} and\n c=QQFieldElem[1, 1]\n k=0\n\njulia> optimal_value(lp)\ninfinity\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)\nPolytope in ambient dimension 3\n\njulia> LP=linear_program(C,[1,2,-3])\nLinear program\n max{c*x + k | x in P}\nwhere P is a Polyhedron{QQFieldElem} and\n c=QQFieldElem[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)\nPolytope 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)\nPolytope 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,","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":"[Har77]\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":"PolyhedralGeometry/cones/","page":"Cones","title":"Cones","text":"CurrentModule = Oscar\nDocTestSetup = Oscar.doctestsetup()","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 non-negative 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(::Oscar.scalar_type_or_field, ::Union{Oscar.MatElem, AbstractMatrix})\ncone_from_inequalities\ncone_from_equations\nsecondary_cone(SOP::SubdivisionOfPoints{T}) where T<:scalar_types","category":"page"},{"location":"PolyhedralGeometry/cones/#positive_hull-Tuple{Union{Field, Type{<:Union{Float64, FieldElem}}}, Union{MatElem, AbstractMatrix}}","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 = incidence_matrix([[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\nfacet_degrees(C::Cone)\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\nn_facets(C::Cone)\nn_rays(C::Cone)\nrays(C::Cone{T}) where T<:scalar_types\nrays_modulo_lineality(C::Cone{T}) where T<:scalar_types\nray_degrees(C::Cone)","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/#facet_degrees-Tuple{Cone}","page":"Cones","title":"facet_degrees","text":"facet_degrees(C::Cone)\n\nFacet degrees of the cone. The degree of a facet is the number of adjacent facets. In particular a general 2-dimensional cone has two facets (rays) that meet at the origin. \n\nExample\n\nProduce the facet degrees of a cone over a square and a cone over a square pyramid. \n\njulia> c = positive_hull([1 1 0; 1 -1 0; 1 0 1; 1 0 -1])\nPolyhedral cone in ambient dimension 3\n\njulia> facet_degrees(c)\n4-element Vector{Int64}:\n 2\n 2\n 2\n 2\n\njulia> c = positive_hull([1 0 1 0; 1 0 -1 0; 1 0 0 1; 1 0 0 -1; 1 1 0 0])\nPolyhedral cone in ambient dimension 4\n\njulia> facet_degrees(c)\n5-element Vector{Int64}:\n 4\n 3\n 3\n 3\n 3\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)\nPolytope 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/#n_facets-Tuple{Cone}","page":"Cones","title":"n_facets","text":"n_facets(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> n_facets(C)\n4\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/cones/#n_rays-Tuple{Cone}","page":"Cones","title":"n_rays","text":"n_rays(C::Cone)\n\nReturn the number of rays of C.\n\nExamples\n\nHere a cone is constructed from three rays. Calling number_of_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> n_rays(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([as::Type{T} = RayVector,] C::Cone)\n\nReturn the rays of C in the format defined by as. The rays are defined to be the one-dimensional faces, so if C has lineality, there are no rays.\n\nSee also rays_modulo_lineality.\n\nOptional arguments for as include\n\nRayVector.\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(RayVector, P))\n[1 0]\n[1 3//2]\n\njulia> matrix(ZZ, rays(P))\n[1 0]\n[2 3]\n\nA half-space has no rays:\n\njulia> UH = cone_from_inequalities([-1 0 0])\nPolyhedral cone in ambient dimension 3\n\njulia> rays(UH)\n0-element SubObjectIterator{RayVector{QQFieldElem}}\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\nSee also rays and lineality_space.\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":"PolyhedralGeometry/cones/#ray_degrees-Tuple{Cone}","page":"Cones","title":"ray_degrees","text":"ray_degrees(C::Cone)\n\nRay degrees of the cone. If the cone has lineality, the output is empty since there are no rays that are also faces. \n\nExamples\n\njulia> c = cone_from_inequalities([-1 0 0; 0 -1 0])\nPolyhedral cone in ambient dimension 3\n\njulia> ray_degrees(c)\nInt64[]\n\njulia> c = positive_hull([1 0 1 0; 1 0 -1 0; 1 0 0 1; 1 0 0 -1; 1 1 0 0])\nPolyhedral cone in ambient dimension 4\n\njulia> ray_degrees(c) \n5-element Vector{Int64}:\n 3\n 3\n 3\n 3\n 4\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 = finite_field(7, 11, \"x\")\n(Finite field of degree 11 and characteristic 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)\n(Residue ring of univariate polynomial ring modulo y^3 + 3*x*y + 1, Map: univariate polynomial ring -> residue ring)\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 the FLINT C library which is installed using binaries by default. With Julia version >= 1.3, the use of this binary 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\"","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":"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":"is_associated(a::BigInt, b::BigInt)","category":"page"},{"location":"AbstractAlgebra/integer/#is_associated-Tuple{BigInt, BigInt}","page":"Integer ring","title":"is_associated","text":"is_associated(a::Integer, b::Integer)\n\nReturn true if a and b are associated, i.e. if there exists a unit c such that a = bc. For integers, this reduces to checking if a and b differ by a factor of 1 or -1.\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::T, n::Int) where T <: Integer","category":"page"},{"location":"AbstractAlgebra/integer/#is_power-Union{Tuple{T}, Tuple{T, Int64}} where T<:Integer","page":"Integer ring","title":"is_power","text":"is_power(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\nReturn a pair (cd) such that a=c*d and c = gcd(a b^infty) if aneq 0, and c=b, d=0 if a=0.\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":"Hecke/manual/misc/pmat/#PMatLink","page":"Pseudo-matrices","title":"Pseudo-matrices","text":"","category":"section"},{"location":"Hecke/manual/misc/pmat/","page":"Pseudo-matrices","title":"Pseudo-matrices","text":"CurrentModule = Hecke","category":"page"},{"location":"Hecke/manual/misc/pmat/","page":"Pseudo-matrices","title":"Pseudo-matrices","text":"This chapter deals with pseudo-matrices. We follow the common terminology and conventions introduced in [Coh00], however, we operate on rows, not on columns.","category":"page"},{"location":"Hecke/manual/misc/pmat/","page":"Pseudo-matrices","title":"Pseudo-matrices","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/manual/misc/pmat/","page":"Pseudo-matrices","title":"Pseudo-matrices","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/manual/misc/pmat/","page":"Pseudo-matrices","title":"Pseudo-matrices","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/manual/misc/pmat/","page":"Pseudo-matrices","title":"Pseudo-matrices","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/manual/misc/pmat/","page":"Pseudo-matrices","title":"Pseudo-matrices","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/manual/misc/pmat/#Creation","page":"Pseudo-matrices","title":"Creation","text":"","category":"section"},{"location":"Hecke/manual/misc/pmat/","page":"Pseudo-matrices","title":"Pseudo-matrices","text":"In general to create a PMat one has to specify a matrix and a vector of ideals:","category":"page"},{"location":"Hecke/manual/misc/pmat/","page":"Pseudo-matrices","title":"Pseudo-matrices","text":"pseudo_matrix(m::AbstractAlgebra.MatElem{AbsSimpleNumFieldElem}, c::Vector{AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}})\npseudo_matrix(m::Generic.Mat{AbsSimpleNumFieldOrderElem}, c::Vector{AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}})\npseudo_matrix(m::Generic.Mat{AbsSimpleNumFieldElem})","category":"page"},{"location":"Hecke/manual/misc/pmat/#pseudo_matrix-Tuple{MatElem{AbsSimpleNumFieldElem}, Vector{AbsSimpleNumFieldOrderIdeal}}","page":"Pseudo-matrices","title":"pseudo_matrix","text":"pseudo_matrix(m::Generic.Mat{AbsSimpleNumFieldElem}, c::Vector{AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}}) -> PMat{AbsSimpleNumFieldElem, AbsSimpleNumFieldOrderFractionalIdeal}\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/manual/misc/pmat/#pseudo_matrix-Tuple{AbstractAlgebra.Generic.Mat{AbsSimpleNumFieldOrderElem}, Vector{AbsSimpleNumFieldOrderIdeal}}","page":"Pseudo-matrices","title":"pseudo_matrix","text":"pseudo_matrix(m::Generic.Mat{AbsSimpleNumFieldOrderElem}, c::Vector{AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}}) -> PMat{AbsSimpleNumFieldElem, AbsSimpleNumFieldOrderFractionalIdeal}\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/manual/misc/pmat/#pseudo_matrix-Tuple{AbstractAlgebra.Generic.Mat{AbsSimpleNumFieldElem}}","page":"Pseudo-matrices","title":"pseudo_matrix","text":"pseudo_matrix(m::Generic.Mat{AbsSimpleNumFieldOrderElem}) -> PMat{AbsSimpleNumFieldElem, AbsSimpleNumFieldOrderFractionalIdeal}\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/manual/misc/pmat/","page":"Pseudo-matrices","title":"Pseudo-matrices","text":"(Those functions are also available as pseudo_matrix)","category":"page"},{"location":"Hecke/manual/misc/pmat/#Operations","page":"Pseudo-matrices","title":"Operations","text":"","category":"section"},{"location":"Hecke/manual/misc/pmat/","page":"Pseudo-matrices","title":"Pseudo-matrices","text":"coefficient_ideals(M::PMat)\nmatrix(M::PMat)\nbase_ring(M::PMat)\npseudo_hnf(P::PMat{AbsSimpleNumFieldElem, AbsSimpleNumFieldOrderFractionalIdeal})\npseudo_hnf_with_transform(P::PMat{AbsSimpleNumFieldElem, AbsSimpleNumFieldOrderFractionalIdeal})","category":"page"},{"location":"Hecke/manual/misc/pmat/#coefficient_ideals-Tuple{Hecke.PMat}","page":"Pseudo-matrices","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/manual/misc/pmat/#matrix-Tuple{Hecke.PMat}","page":"Pseudo-matrices","title":"matrix","text":"matrix(M::PMat)\n\nReturns the matrix part of the PMat.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/misc/pmat/#base_ring-Tuple{Hecke.PMat}","page":"Pseudo-matrices","title":"base_ring","text":"base_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\nbase_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 generated by\n x^2\n x*y\n 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::AbsAffineScheme)\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\n","category":"method"},{"location":"Hecke/manual/misc/pmat/#pseudo_hnf-Tuple{Hecke.PMat{AbsSimpleNumFieldElem, AbsSimpleNumFieldOrderFractionalIdeal}}","page":"Pseudo-matrices","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/manual/misc/pmat/#pseudo_hnf_with_transform-Tuple{Hecke.PMat{AbsSimpleNumFieldElem, AbsSimpleNumFieldOrderFractionalIdeal}}","page":"Pseudo-matrices","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/manual/misc/pmat/#Examples","page":"Pseudo-matrices","title":"Examples","text":"","category":"section"},{"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, rho G to textGL(V)cong textGL_n(K) will be a rational representation of G, and G will act on KVcong Kx_1 dots x_n by linear substitution: If rho(pi) = (a_i j), then ","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) = fbigl(sum_j a_1 jx_j dots sum_j a_n jx_jbigr)","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 is explicitly known, generators of invariant rings of linearly reductive groups can be found in two steps using Derksen's algorithm, see [Der99] :","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 [DK15] and [DJ98].","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/#How-Linearly-Reductive-Groups-and-Their-Representations-are-Given","page":"Invariants of Linearly Reductive Groups","title":"How Linearly Reductive Groups and Their Representations are Given","text":"","category":"section"},{"location":"InvariantTheory/reductive_groups/","page":"Invariants of Linearly Reductive Groups","title":"Invariants of Linearly Reductive Groups","text":"For the computation of invariant rings in the above setting, 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":"note: Note\nProceeding as above is not a problem: Derksen's algorithms relies on Gröbner bases techniques and means to compute Reynolds operators. It does, thus, not change the initial ground field k. That is, all computations are performed over k and computations over any extension field of k would lead to the same results.","category":"page"},{"location":"InvariantTheory/reductive_groups/","page":"Invariants of Linearly Reductive Groups","title":"Invariants of Linearly Reductive Groups","text":"In OSCAR, the basic set-up for a linearly reductive group in the context of Derksen's algorithm is provided by the function linearly_reductive_group. At current state, this only supports rational actions of the special linear group (in characteristic zero). For the action of this group by linear substitution on, say, n-ary forms of degree d, an explicit Reynolds operator is given by Cayley's Omega-process. We show this at work later in this section.","category":"page"},{"location":"InvariantTheory/reductive_groups/","page":"Invariants of Linearly Reductive Groups","title":"Invariants of Linearly Reductive Groups","text":"linearly_reductive_group(sym::Symbol, m::Int, K::Field)","category":"page"},{"location":"InvariantTheory/reductive_groups/#linearly_reductive_group-Tuple{Symbol, Int64, Field}","page":"Invariants of Linearly Reductive Groups","title":"linearly_reductive_group","text":"linearly_reductive_group(sym::Symbol, m::Int, K::Field)\n\nReturn the linearly reductive group indicated by sym.\n\nCurrently, the supported options for sym are:\n\n:SL, corresponding to the special linear group (of degree m over the field K).\n\nExamples\n\njulia> G = linearly_reductive_group(:SL, 2, QQ)\nReductive group SL2\n over QQ\n\njulia> group_ideal(G)\nIdeal generated by\n z[1, 1]*z[2, 2] - z[2, 1]*z[1, 2] - 1\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"InvariantTheory/reductive_groups/","page":"Invariants of Linearly Reductive Groups","title":"Invariants of Linearly Reductive Groups","text":"linearly_reductive_group(sym::Symbol, m::Int, R::MPolyRing)","category":"page"},{"location":"InvariantTheory/reductive_groups/#linearly_reductive_group-Tuple{Symbol, Int64, MPolyRing}","page":"Invariants of Linearly Reductive Groups","title":"linearly_reductive_group","text":"linearly_reductive_group(sym::Symbol, m::Int, R::MPolyRing)\n\nReturn the linearly reductive group indicated by sym.\n\nCurrently, the supported options for sym are:\n\n:SL, corresponding to the special linear group (of degree m over the base field K of R, where R is the polynomial ring in which the defining ideal of SL(m K) lives).\n\nExamples\n\njulia> S, z = polynomial_ring(QQ, :c=> (1:2, 1:2));\n\njulia> G = linearly_reductive_group(:SL,2,S)\nReductive group SL2\n over QQ\n\njulia> group_ideal(G)\nIdeal generated by\n c[1, 1]*c[2, 2] - c[2, 1]*c[1, 2] - 1\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"InvariantTheory/reductive_groups/","page":"Invariants of Linearly Reductive Groups","title":"Invariants of Linearly Reductive Groups","text":"representation_on_forms(G::LinearlyReductiveGroup, d::Int)","category":"page"},{"location":"InvariantTheory/reductive_groups/#representation_on_forms-Tuple{LinearlyReductiveGroup, Int64}","page":"Invariants of Linearly Reductive Groups","title":"representation_on_forms","text":"representation_on_forms(G::LinearlyReductiveGroup, d::Int)\n\nIf G is the special linear group acting by linear substitution on, say, n-ary forms of degree d, return the corresponding representation.\n\nnote: Note\nIn accordance with classical papers, an n-ary form of degree d in Kx_1 dots x_n is written as a K-linear combination of the K-basis with elements binomnIx^I. Here, I = (i_1 dots i_n)inmathbb Z_geq 0^n with i_1+dots +i_n =d.\n\nExamples\n\njulia> G = linearly_reductive_group(:SL, 2, QQ);\n\njulia> r = representation_on_forms(G, 2)\nRepresentation of SL2\n on symmetric forms of degree 2\n\njulia> representation_matrix(r)\n[ z[1, 1]^2 2*z[1, 1]*z[2, 1] z[2, 1]^2]\n[z[1, 1]*z[1, 2] z[1, 1]*z[2, 2] + z[2, 1]*z[1, 2] z[2, 1]*z[2, 2]]\n[ z[1, 2]^2 2*z[1, 2]*z[2, 2] z[2, 2]^2]\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"InvariantTheory/reductive_groups/#Constructors-for-Invariant-Rings","page":"Invariants of Linearly Reductive Groups","title":"Constructors for Invariant Rings","text":"","category":"section"},{"location":"InvariantTheory/reductive_groups/","page":"Invariants of Linearly Reductive Groups","title":"Invariants of Linearly Reductive Groups","text":"invariant_ring(r::RepresentationLinearlyReductiveGroup)","category":"page"},{"location":"InvariantTheory/reductive_groups/#invariant_ring-Tuple{RepresentationLinearlyReductiveGroup}","page":"Invariants of Linearly Reductive Groups","title":"invariant_ring","text":"invariant_ring(r::RepresentationLinearlyReductiveGroup)\n\nReturn the invariant ring under the action defined by the representation r on an implicitly generated polynomial ring of appropriate dimension.\n\nExamples\n\njulia> G = linearly_reductive_group(:SL, 2, QQ);\n\njulia> r = representation_on_forms(G, 2);\n\njulia> RG = invariant_ring(r)\nInvariant Ring of\ngraded multivariate polynomial ring in 3 variables over QQ\n under group action of SL2\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"InvariantTheory/reductive_groups/","page":"Invariants of Linearly Reductive Groups","title":"Invariants of Linearly Reductive Groups","text":"invariant_ring(R::MPolyDecRing, r::RepresentationLinearlyReductiveGroup)","category":"page"},{"location":"InvariantTheory/reductive_groups/#invariant_ring-Tuple{MPolyDecRing, RepresentationLinearlyReductiveGroup}","page":"Invariants of Linearly Reductive Groups","title":"invariant_ring","text":"invariant_ring(R::MPolyDecRing, r::RepresentationLinearlyReductiveGroup)\n\nReturn the invariant subring of R under the action induced by the representation of r on R.\n\nExamples\n\njulia> G = linearly_reductive_group(:SL, 3, QQ);\n\njulia> r = representation_on_forms(G, 3);\n\njulia> S, x = graded_polynomial_ring(QQ, :x => 1:10);\n\njulia> RG = invariant_ring(S, r)\nInvariant Ring of\ngraded multivariate polynomial ring in 10 variables over QQ\n under group action of SL3\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"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":"reynolds_operator(R::RedGroupInvarRing, f::MPolyRingElem)","category":"page"},{"location":"InvariantTheory/reductive_groups/#reynolds_operator-Tuple{RedGroupInvarRing, MPolyRingElem}","page":"Invariants of Linearly Reductive Groups","title":"reynolds_operator","text":"reynolds_operator(RG::RedGroupInvarRing, f::MPolyRingElem)\n\nReturn the image of f under the Reynolds operator corresponding to RG.\n\nExamples\n\njulia> G = linearly_reductive_group(:SL, 3, QQ);\n\njulia> r = representation_on_forms(G, 3);\n\njulia> S, x = graded_polynomial_ring(QQ, :x => 1:10);\n\njulia> RG = invariant_ring(S, r);\n\njulia> 75*reynolds_operator(RG, x[5]^4)\nx[1]*x[4]*x[8]*x[10] - x[1]*x[4]*x[9]^2 - x[1]*x[5]*x[7]*x[10] + x[1]*x[5]*x[8]*x[9] + x[1]*x[6]*x[7]*x[9] - x[1]*x[6]*x[8]^2 - x[2]^2*x[8]*x[10] + x[2]^2*x[9]^2 + x[2]*x[3]*x[7]*x[10] - x[2]*x[3]*x[8]*x[9] + x[2]*x[4]*x[5]*x[10] - x[2]*x[4]*x[6]*x[9] - 2*x[2]*x[5]^2*x[9] + 3*x[2]*x[5]*x[6]*x[8] - x[2]*x[6]^2*x[7] - x[3]^2*x[7]*x[9] + x[3]^2*x[8]^2 - x[3]*x[4]^2*x[10] + 3*x[3]*x[4]*x[5]*x[9] - x[3]*x[4]*x[6]*x[8] - 2*x[3]*x[5]^2*x[8] + x[3]*x[5]*x[6]*x[7] + x[4]^2*x[6]^2 - 2*x[4]*x[5]^2*x[6] + x[5]^4\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"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/","page":"Invariants of Linearly Reductive Groups","title":"Invariants of Linearly Reductive Groups","text":"fundamental_invariants(RG::RedGroupInvarRing)","category":"page"},{"location":"InvariantTheory/reductive_groups/#fundamental_invariants-Tuple{RedGroupInvarRing}","page":"Invariants of Linearly Reductive Groups","title":"fundamental_invariants","text":"fundamental_invariants(RG::RedGroupInvarRing)\n\nReturn a system of fundamental invariants for RG.\n\nExamples\n\njulia> G = linearly_reductive_group(:SL, 2, QQ);\n\njulia> r = representation_on_forms(G, 2);\n\njulia> RG = invariant_ring(r);\n\njulia> fundamental_invariants(RG)\n1-element Vector{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}:\n -X[1]*X[3] + X[2]^2\n\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"references/","page":"References","title":"References","text":"","category":"page"},{"location":"references/","page":"References","title":"References","text":"X. Allamigeon, P. Benchimol, S. Gaubert and M. Joswig. Log-barrier interior point methods are not strongly polynomial. SIAM Journal on Applied Algebra and Geometry 2, 140–178 (2018).\n\n\n\nD. Avis, D. Bremner and R. Seidel. How good are convex hull algorithms? Comput. Geom. 7, 265–301 (1997). 11th ACM Symposium on Computational Geometry (Vancouver, BC, 1995).\n\n\n\nI. V. Arzhantsev and S. A. Gaĭfullin. Cox rings, semigroups, and automorphisms of affine varieties. Mat. Sb. 201, 3–24 (2010), arXiv:0810.1148.\n\n\n\nB. Amrhein, O. Gloor and W. Küchlin. Walking faster. In: Design and Implementation of Symbolic Computation Systems, DISCO 1996 (Springer Berlin, Heidelberg, Heidelberg, Germany, 1996); pp. 150–161.\n\n\n\nB. Amrhein, O. Gloor and W. Küchlin. On the walk. Theoretical Computer Science 187, 179–202 (1997).\n\n\n\nK. Adiprasito, J. Huh and E. Katz. Hodge theory for combinatorial geometries. Ann. of Math. (2) 188, 381–452 (2018).\n\n\n\nW. W. Adams and P. Loustaunau. An Introduction to Gröbner Bases. Graduate studies in mathematics (American Mathematical Society, 1994).\n\n\n\nR. A. Wilson, P. Walsh, J. Tripp, I. Suleiman, R. A. Parker, S. P. Norton, S. Nickerson, S. Linton, J. Bray and R. Abbott. ATLAS of Finite Group Representations. Published electronically.\n\n\n\nN. Amenta and G. M. Ziegler. Deformed products and maximal shadows of polytopes. Contemporary Mathematics 223, 57–90 (1999).\n\n\n\nM. Bayer, A. Bruening and J. Stewart. A Combinatorial Study of Multiplexes and Ordinary Polytopes. Discrete & Computational Geometry 27, 49–63 (2002).\n\n\n\nM. Bies, M. Cvetič and M. Liu. Statistics of limit root bundles relevant for exact matter spectra of F-theory MSSMs. Phys. Rev. D 104, L061903 (2021).\n\n\n\nN. Berry, A. Dubickas, N. D. Elkies, B. Poonen and C. Smyth. The conjugate dimension of algebraic numbers. Q. J. Math. 55, 237–252 (2004).\n\n\n\nJ. Böhm, W. Decker, S. Laplagne and G. Pfister. Local to global algorithms for the Gorenstein adjoint ideal of a curve. In: Algorithmic and experimental methods in algebra, geometry, and number theory (Springer, Cham, 2017); pp. 51–96.\n\n\n\nJ. Böhm, W. Decker, S. Laplagne and G. Pfister. Computing integral bases via localization and Hensel lifting. In: MEGA 2019 - International Conference on Effective Methods in Algebraic Geometry (Madrid, Spain, 2019). HAL:hal-02912148.\n\n\n\nJ. Böhm, W. Decker, S. Laplagne, G. Pfister, A. Steenpaß and S. Steidel. Parallel algorithms for normalization. Journal of Symbolic Computation 51, 99–114 (2013). Effective Methods in Algebraic Geometry.\n\n\n\nH. U. Besche, B. Eick and E. O'Brien. SmallGrp, The GAP Small Groups Library, Version 1.5.3 (May 2023). GAP package.\n\n\n\nJ. Berthomieu, C. Eder and M. 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 (Association for Computing Machinery, New York, NY, USA, 2021); pp. 51–58.\n\n\n\nS. Backman, C. Eur and C. Simpson. Simplicial generation of Chow rings of matroids (2019), arXiv:1905.07114 [math.CO].\n\n\n\nJ. L. Bueso, J. Gómez-Torrecillas and A. Verschoren. Algorithmic methods in non-commutative algebra. Applications to quantum groups. Vol. 17 of Math. Model.: Theory Appl. (Dordrecht: Kluwer Academic Publishers, 2003).\n\n\n\nW. Bruns and J. Herzog. Cohen-Macaulay rings. Vol. 39 of Cambridge Studies in Advanced Mathematics (Cambridge University Press, Cambridge, 2009). 2nd edition.\n\n\n\nS. Brandhorst and T. Hofmann. Finite subgroups of automorphisms of K3 surfaces. Forum of Mathematics, Sigma 11, e54 1–57 (2023).\n\n\n\nT. Braden, J. Huh, J. P. Matherne, N. Proudfoot and B. Wang. A semi-small decomposition of the Chow ring of a matroid (2020), arXiv:2002.03341 [math.AG].\n\n\n\nW. P. Barth, K. Hulek, C. A. Peters and A. Van de Ven. Compact complex surfaces. 2nd enlarged ed. Edition, Vol. 4 of Ergeb. Math. Grenzgeb., 3. Folge (Berlin: Springer, 2004).\n\n\n\nR. Blumenhagen, B. Jurke, T. Rahn and H. Roschy. Cohomology of line bundles: A computational algorithm. Journal of Mathematical Physics 51, 103525 (2010).\n\n\n\nR. Blumenhagen, B. Jurke, T. Rahn and H. Roschy, cohomCalg package. Published electronically on GitHub (2010). High-performance line bundle cohomology computation based on BJRR10.\n\n\n\nR. Blumenhagen, B. Jurke, T. Rahn and H. Roschy. Cohomology of line bundles: Applications. Journal of Mathematical Physics 53, 012302 (2012).\n\n\n\nT. Bogart, A. N. Jensen, D. Speyer, B. Sturmfels and R. R. Thomas. Computing tropical varieties. J. Symb. Comput. 42, 54–73 (2007).\n\n\n\nJ. Böhm, S. Keicher and Y. Ren. Computing GIT-fans with symmetry and the Mori chamber decomposition of overline M_06. Math. Comp. 89, 3003–3021 (2020).\n\n\n\nL. J. Billera and C. W. Lee. A proof of the sufficiency of McMullen's conditions for f-vectors of simplicial convex polytopes. J. Combin. Theory Ser. A 31, 237–255 (1981).\n\n\n\nM. Baker and S. Norine. Riemann-Roch and Abel-Jacobi theory on a finite graph. Adv. Math. 215, 766–788 (2007).\n\n\n\nT. Banica and R. Speicher. Liberation of orthogonal Lie groups. Advances in Mathematics 222, 1461–1501 (2009).\n\n\n\nD. J. Benson. Polynomial invariants of finite groups. Vol. 190 of London Mathematical Society Lecture Note Series (Cambridge University Press, Cambridge, 1993).\n\n\n\nJ. Böhm. Parametrisierung rationaler Kurven. Diploma Thesis, Universität Bayreuth (1999).\n\n\n\nM. Bies. Cohomologies of coherent sheaves and massless spectra in F-theory. Ph.D. Thesis, Heidelberg U. (Feb 2018).\n\n\n\nM. Bies. Root bundles: Applications to F-theory Standard Models. Proc. Symp. Pure Math. 107, 17–44 (2024), arXiv:2303.08144 [hep-th].\n\n\n\nT. Bisztriczky. On a class of generalized simplices. Mathematika 43, 274–285 (1996).\n\n\n\nW. Burnside. Theory of groups of finite order (Dover Publications, Inc., New York, 1955); p. xxiv+512. 2d ed.\n\n\n\nJ. L. Cisneros Molina, D. T. Le and J. Seade. Handbook of Geometry and Topology of Singularities I (Springer-Verlag, Cham, 2020); p. xviii+601.\n\n\n\nJ. L. Cisneros Molina, D. T. Le and J. Seade. Handbook of Geometry and Topology of Singularities II (Springer-Verlag, Cham, 2021); p. xii+578.\n\n\n\nJ. H. Conway, R. T. Curtis, S. P. Norton, R. A. Parker and R. A. Wilson. Atlas of finite groups (Oxford University Press, Eynsham, 1985); p. xxxiv+252. Maximal subgroups and ordinary characters for simple groups, With computational assistance from J. G. Thackray.\n\n\n\nM. Cvetič, J. Halverson, L. Lin, M. Liu and J. Tian. Quadrillion F-Theory Compactifications with the Exact Chiral Spectrum of the Standard Model. Phys. Rev. Lett. 123, 101601 (2019), arXiv:1903.00009 [hep-th].\n\n\n\nJ. H. Conway, A. Hulpke and J. McKay. On transitive permutation groups. LMS J. Comput. Math. 1, 1–8 (1998).\n\n\n\nS. Collart, M. Kalkbrener and D. Mall. Converting Bases with the Gröbner Walk. Journal of Symbolic Computation 24, 465–469 (1997).\n\n\n\nD. A. Cox, J. Little and D. O'Shea. Using Algebraic Geometry. Vol. 185 of Graduate Texts in Mathematics (Springer-Verlag, 2005).\n\n\n\nD. A. Cox, J. B. Little and H. K. Schenck. Toric varieties. Vol. 124 of Graduate Studies in Mathematics (Providence, RI: American Mathematical Society (AMS), 2011); p. xxiv+841.\n\n\n\nB. Collins, J. A. Mingo, P. Śniady and R. Speicher. Second order freeness and fluctuations of random matrices. III: Higher order freeness and free cumulants. Documenta Mathematica 12, 1–70 (2007).\n\n\n\nA. M. Cohen, S. H. Murray and D. E. Taylor. Computing in groups of Lie type. Math. Comp. 73, 1477–1498 (2004).\n\n\n\nJ. H. Conway and N. J. Sloane. Sphere packings, lattices and groups. Third Edition, Vol. 290 of Grundlehren der mathematischen Wissenschaften [Fundamental Principles of Mathematical Sciences] (Springer-Verlag, New York, 1999); p. lxxiv+703. 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.\n\n\n\nC. Ceballos, F. Santos and G. M. Ziegler. Many non-equivalent realizations of the associahedron. Combinatorica 35, 513–551 (2015).\n\n\n\nG. Cébron and M. Weber. Quantum groups based on spatial partitions (2016), arXiv:1609.02321 [math.QA].\n\n\n\nP. J. Cameron. Permutation groups. Vol. 45 of London Mathematical Society Student Texts (Cambridge University Press, Cambridge, 1999); p. x+220.\n\n\n\nJ. A. 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), Vol. 1462 of Lecture Notes in Math. (Springer, Berlin, 1991); pp. 81–92.\n\n\n\nH. Cohen. Advanced topics in computational number theory. Vol. 193 of Graduate Texts in Mathematics (Springer-Verlag, New York, 2000); p. xvi+578.\n\n\n\nH. Cohen. A course in computational algebraic number theory. Vol. 138 of Graduate Texts in Mathematics (Springer-Verlag, Berlin, 1993); p. xii+534.\n\n\n\nD. Corey. Initial degenerations of Grassmannians. Sel. Math. New Ser. 27 (2021).\n\n\n\nW. Decker and D. Eisenbud. Sheaf algorithms using the exterior algebra. In: Computations in algebraic geometry with Macaulay 2 (Berlin: Springer, 2002); pp. 215–249.\n\n\n\nW. Decker, L. Ein and F.-O. Schreyer. Construction of surfaces in mathbb P^4. J. Algebr. Geom. 2, 185–237 (1993).\n\n\n\nG. De Franceschi. Centralizers and conjugacy classes in finite classical groups (2020), arXiv:2008.12651 [math.GR].\n\n\n\nA. S. Detinko, D. L. Flannery and E. A. O'Brien. Recognizing finite matrix groups over infinite fields. J. Symbolic Comput. 50, 100–109 (2013).\n\n\n\nW. Decker, G.-M. Greuel and G. Pfister. Primary decomposition: algorithms and comparisons. In: Algorithmic algebra and number theory. Selected papers from a conference, Heidelberg, Germany, October 1997 (Springer, Berlin, 1999); pp. 187–220.\n\n\n\nM. Domokos and P. Hegedűs. Noether's bound for polynomial invariants of finite groups. Arch. Math. (Basel) 74, 161–167 (2000).\n\n\n\nW. Decker, A. E. Heydtmann and F.-O. Schreyer. Generating a Noetherian normalization of the invariant ring of a finite group. J. Symbolic Comput. 25, 727–731 (1998).\n\n\n\nW. Decker and T. 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, Vol. 251 of London Math. Soc. Lecture Note Ser. (Cambridge Univ. Press, Cambridge, 1998); pp. 61–89.\n\n\n\nH. Derksen and G. Kemper. Computational invariant theory. With two appendices by Vladimir L. Popov, and an addendum by Norbert A'Campo and Popov, 2nd enlarged edition, Invariant Theory and Algebraic Transformation Groups, VIII, enlarged Edition, Vol. 130 of Encyclopaedia of Mathematical Sciences (Springer, Heidelberg, 2015); p. xxii+366.\n\n\n\nM. Donten-Bury and S. Keicher. Computing resolutions of quotient singularities. J. Algebra 472, 546–572 (2017).\n\n\n\nW. Decker and C. Lossen. Computing in algebraic geometry. A quick start using SINGULAR. Vol. 16 of Algorithms and Computation in Mathematics (Springer-Verlag, Berlin; Hindustan Book Agency, New Delhi, 2006); p. xvi+327.\n\n\n\nJ. A. De Loera, J. Rambau and F. Santos. Triangulations. Structures for algorithms and applications. Vol. 25 of Algorithms and Computation in Mathematics (Springer-Verlag, Berlin, 2010); p. xiv+535.\n\n\n\nW. Decker and G. Pfister. A first course in computational algebraic geometry. African Institute of Mathematics (AIMS) Library Series (Cambridge University Press, Cambridge, 2013); p. viii+118.\n\n\n\nW. Decker and F.-O. Schreyer. Non-general type surfaces in mathbb P^4: Some remarks on bounds and constructions. J. Symb. Comput. 29, 545–582 (2000).\n\n\n\nM. Drton, B. Sturmfels and S. Sullivant. Lectures on algebraic statistics. Vol. 39 of Oberwolfach Semin. (Basel: Birkhäuser, 2009).\n\n\n\nH. Derksen. Computation of invariants for reductive groups. Adv. Math. 141, 366–384 (1999).\n\n\n\nD. Eisenbud, G. Fløystad and F.-O. Schreyer. Sheaf cohomology and free resolutions over exterior algebras. Trans. Am. Math. Soc. 355, 4397–4426 (2003).\n\n\n\nD. Eisenbud and J. Harris. 3264 and all that. A second course in algebraic geometry (Cambridge: Cambridge University Press, 2016).\n\n\n\nD. Eisenbud, C. Huneke and B. Ulrich. What is the Rees algebra of a module? Proc. Am. Math. Soc. 131, 701–708 (2003).\n\n\n\nD. Eisenbud, C. Huneke and W. Vasconcelos. Direct methods for primary decomposition. Invent. Math. 110, 207–235 (1992).\n\n\n\nZ. S. Eser and L. F. Matusevich. Decompositions of cellular binomial ideals. J. Lond. Math. Soc. (2) 94, 409–426 (2016).\n\n\n\nZ. S. Eser and L. F. Matusevich. Corrigendum: Decompositions of cellular binomial ideals: (J. Lond. Math. Soc. 94 (2016) 409–426). J. Lond. Math. Soc. (2) 100, 717–719 (2019).\n\n\n\nB. Eröcal, O. Motsak, F.-O. Schreyer and A. Steenpaß. Refined algorithms to compute syzygies. J. Symb. Comput. 74, 308–327 (2016).\n\n\n\nD. Eisenbud and B. Sturmfels. Binomial ideals. Duke Math. J. 84, 1–45 (1996).\n\n\n\nD. Eisenbud. Commutative algebra. With a view toward algebraic geometry. Vol. 150 (Berlin: Springer-Verlag, 1995); p. xvi + 785.\n\n\n\nD. Eisenbud. Computing cohomology. A chapter in W. Vasconcelos, Computational methods in commutative algebra and algebraic geometry (Berlin: Springer, 1998); pp. 209–216.\n\n\n\nJ. Faugère, P. Gianni, D. Lazard and T. Mora. Efficient Computation of Zero-dimensional Gröbner Bases by Change of Ordering. Journal of Symbolic Computation 16, 329–344 (1993).\n\n\n\nK. Fukuda, A. N. Jensen, N. Lauritzen and R. Thomas. The generic Gröbner walk. Journal of Symbolic Computation 42, 298–312 (2007).\n\n\n\nH. Fan, T. Jarvis and Y. Ruan. A mathematical theory of the gauged linear sigma model. Geometry & Topology 22, 235–303 (2017).\n\n\n\nK. Fukuda, A. N. Jensen and R. R. Thomas. Computing Groebner Fans. Math. Comp. 76, 2189–2213 (2007).\n\n\n\nW. B. Hart. Fast Library for Number Theory: An Introduction. In: Proceedings of the Third International Congress on Mathematical Software, ICMS'10 (Springer-Verlag, Berlin, Heidelberg, 2010); pp. 88–91, https://flintlib.org.\n\n\n\nE. M. Feichtner and S. Yuzvinsky. Chow rings of toric varieties defined by atomic lattices. Inventiones Mathematicae 155, 515–536 (2004).\n\n\n\nJ.-C. Faugère. A new efficient algorithm for computing Gröbner bases (F4). Journal of Pure and Applied Algebra 139, 61–88 (1999). HAL:hal-01148855.\n\n\n\nW. Fulton. Algebraic curves. An introduction to algebraic geometry. Mathematics Lecture Note Series (W. A. Benjamin, Inc., New York-Amsterdam, 1969); p. xiii+226. Notes written with the collaboration of Richard Weiss.\n\n\n\nW. Fulton. Young tableaux. Vol. 35 of London Mathematical Society Student Texts (Cambridge University Press, Cambridge, 1997); p. x+260. With applications to representation theory and geometry.\n\n\n\nW. Fulton. Intersection theory. Second Edition, Vol. 2 of Ergebnisse der Mathematik und ihrer Grenzgebiete. 3. Folge. A Series of Modern Surveys in Mathematics [Results in Mathematics and Related Areas. 3rd Series. A Series of Modern Surveys in Mathematics] (Springer-Verlag, Berlin, 1998); p. xiv+470.\n\n\n\nT. W. Grimm and H. Hayashi. F-theory fluxes, chirality and Chern-Simons theories. Journal of High Energy Physics 2012 (2012).\n\n\n\nE. Gawrilow, S. Hampe and M. Joswig. The polymake XML File Format. In: Mathematical Software – ICMS 2016, edited by G.-M. Greuel, T. Koch, P. Paule and A. Sommese (Springer International Publishing, Cham, 2016); pp. 403–410.\n\n\n\nW. A. de Graaf, G. Ivanyos and L. Rónyai. Computing Cartan subalgebras of Lie algebras. Appl. Algebra Eng. Commun. Comput. 7, 339–349 (1996).\n\n\n\nE. Gawrilow and M. Joswig, polymake: a Framework for Analyzing Convex Polytopes. In: Polytopes — Combinatorics and Computation, edited by G. Kalai and G. M. Ziegler (Birkhäuser, 2000); pp. 43–74, https://polymake.org.\n\n\n\nE. Gawrilow, M. Joswig, T. Rörig and N. Witte. Drawing polytopal graphs with polymake. Comput. Vis. Sci. 13, 99–110 (2010), arXiv:0711.2397.\n\n\n\nY. Giannakopoulos and E. Koutsoupias. Duality and optimality of auctions for uniform distributions. In: Proceedings of the fifteenth ACM conference on Economics and computation (Association for Computing Machinery, New York, 2014); pp. 259–276.\n\n\n\nG.-M. Greuel, C. Lossen and E. Shustin. Introduction to Singularities and Deformations. Springer Monographs in Mathematics (Springer-Verlag, Berlin, 2007); p. xii+471.\n\n\n\nG.-M. Greuel, S. Laplagne and F. Seelisch. Normalization of rings. J. Symbolic Comput. 45, 887–901 (2010).\n\n\n\nG.-M. Greuel and G. Pfister. A Singular introduction to commutative algebra. With contributions by Olaf Bachmann, Christoph Lossen and Hans Schönemann. 2nd extended ed. (Springer, Berlin, 2008); p. xx+689. With 1 CD-ROM (Windows, Macintosh and UNIX).\n\n\n\nD. Goldfarb and W. Y. Sit. Worst case behavior of the steepest edge simplex method. Discrete Applied Mathematics 1, 277–285 (1979).\n\n\n\nD. R. Grayson, A. Seceleanu and M. E. Stillman. Computations in intersection rings of flag bundles (2022), arXiv:1205.4190 [math.AG].\n\n\n\nP. Gianni, B. Trager and G. Zacharias. Gröbner bases and primary decomposition of polynomial ideals. In: Computational aspects of commutative algebra, Vol. 6 (Elsevier Ltd, Oxford, 1988); pp. 149–167.\n\n\n\nU. Görtz and T. Wedhorn. Algebraic Geometry I: Schemes with Examples and Exercises. 2 Edition (Springer Spektrum, 2020).\n\n\n\nA. Gathmann. Class notes „Plane Algebraic Curves” (SS 2018). Published electronically (2018).\n\n\n\nK. Gatermann. Semi-invariants, equivariants and algorithms. Appl. Algebra Engrg. Comm. Comput. 7, 105–124 (1996).\n\n\n\nW. A. de Graaf. Lie algebras: theory and algorithms. Vol. 56 of North-Holland Mathematical Library (North-Holland Publishing Co., Amsterdam, 2000); p. xii+393.\n\n\n\nD. Gromada. Compact matrix quantum groups and their representation categories, doctoralthesis, Universität des Saarlandes (2020).\n\n\n\nB. Grünbaum. Convex polytopes. Second Edition, Vol. 221 of Graduate Texts in Mathematics (Springer-Verlag, New York, 2003); p. xvi+468. Prepared and with a preface by Volker Kaibel, Victor Klee and Günter M. Ziegler.\n\n\n\nD. F. Holt, B. Eick and E. A. O'Brien. Handbook of computational group theory. Discrete Mathematics and its Applications (Boca Raton) (Chapman & Hall/CRC, Boca Raton, FL, 2005); p. xvi+514.\n\n\n\nJ. Hausen, E. Herppich and H. Süss. Multigraded factorial rings and Fano varieties with torus action. Doc. Math. 16, 71–109 (2011).\n\n\n\nG. Horrocks and D. Mumford. A rank 2 vector bundle on textP^4 with 15,000 symmetries. Topology 12, 63–81 (1973).\n\n\n\nD. F. Holt and W. Plesken. Perfect groups. Oxford Mathematical Monographs (The Clarendon Press, Oxford University Press, New York, 1989); p. xii+364. With an appendix by W. Hanrath, Oxford Science Publications.\n\n\n\nA. Hulpke, C. Roney-Dougal and C. Russell. PrimGrp, GAP Primitive Permutation Groups Library, Version 3.4.4 (Feb 2023). GAP package.\n\n\n\nJ. Halverson and J. Tian. Cost of seven-brane gauge symmetry in a quadrillion F-theory compactifications. Phys. Rev. D 95, 026005 (2017), arXiv:1610.08864 [hep-th].\n\n\n\nR. Hartshorne. Algebraic Geometry. Graduate Texts in Mathematics (Springer-Verlag, New York, 1977); p. xvi+496.\n\n\n\nA. Hulpke. The perfect groups of order up to two million. Math. Comp. 91, 1007–1017 (2022).\n\n\n\nA. Hulpke. TransGrp, Transitive Groups Library, Version 3.6.5 (Dec 2023). GAP package.\n\n\n\nJ. E. Humphreys. Introduction to Lie Algebras and Representation Theory. Vol. 9 of Graduate Texts in Mathematics (Springer-Verlag, New York, 1972); p. xii+169.\n\n\n\nB. Huppert. Endliche Gruppen. I. Vol. 134 of Die Grundlehren der mathematischen Wissenschaften (Springer-Verlag, Berlin-New York, 1967); p. xii+793.\n\n\n\nD. Huybrechts. Lectures on K3 surfaces. Vol. 158 of Cambridge Studies in Advanced Mathematics (Cambridge University Press, Cambridge, 2016); p. xi+485.\n\n\n\nY. Ito and M. Reid. The McKay correspondence for finite subgroups of mathrmSL(3mathbb C). In: Higher-dimensional complex varieties (Trento, 1994) (de Gruyter, 1996); pp. 221–240.\n\n\n\nM. Joswig, M. Klimm and S. Spitz. Generalized permutahedra and optimal auctions. SIAM Journal on Applied Algebra and Geometry 6, 711–739 (2022).\n\n\n\nM. Joswig, D. Lofano, F. H. Lutz and M. Tsuruga. Frontiers of sphere recognition in practice. J. Appl. Comput. Topol. 6, 503–527 (2022).\n\n\n\nC. Jansen, K. Lux, R. Parker and R. Wilson. An atlas of Brauer characters. Vol. 11 of London Mathematical Society Monographs. New Series (The Clarendon Press Oxford University Press, New York, 1995); p. xviii+327. Appendix 2 by T. Breuer and S. Norton, Oxford Science Publications.\n\n\n\nT. de Jong and G. Pfister. Local Analytic Geometry. Advanced Lectures in Mathematics (Vieweg+Teubner Verlag, 2000); p. xi+384.\n\n\n\nM. Joswig and T. Theobald. Polyhedral and algebraic methods in computational geometry. Universitext (Springer, London, 2013); p. x+250. Revised and updated translation of the 2008 German original.\n\n\n\nM. Joswig and G. M. Ziegler. Neighborly Cubical Polytopes. Discrete & Computational Geometry  24, 325–344 (2000).\n\n\n\nF. Johansson. Efficient implementation of the Hardy-Ramanujan-Rademacher formula. LMS J. Comput. Math. 15, 341–359 (2012).\n\n\n\nM. Joswig. Beneath-and-Beyond Revisited. In: Algebra, Geometry and Software Systems, edited by M. Joswig and N. Takayama (Springer Berlin Heidelberg, Berlin, Heidelberg, 2003); pp. 1–21.\n\n\n\nM. Joswig. Polytope propagation on graphs. In: Algebraic statistics for computational biology. (Cambridge: Cambridge University Press, 2005); pp. 181–192.\n\n\n\nM. Joswig. Essentials of tropical combinatorics. Vol. 219 of Graduate Studies in Mathematics (American Mathematical Society, Providence, RI, 2021).\n\n\n\nS.-Y. Jow. Cohomology of toric line bundles via simplicial Alexander duality. Journal of Mathematical Physics 52, 033506 (2011).\n\n\n\nT. Krick and A. 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), Vol. 539 of Lecture Notes in Comput. Sci. (Springer, Berlin, 1991); pp. 195–205.\n\n\n\nM. Kaluba, B. Lorenz and S. Timme. Polymake.jl: A New Interface to polymake. In: Mathematical Software – ICMS 2020, edited by A. M. Bigatti, J. Carette, J. H. Davenport, M. Joswig and T. de Wolff (Springer International Publishing, Cham, 2020); pp. 377–385.\n\n\n\nD. Klevers, D. K. Mayorga Pena, P.-K. Oehlmann, H. Piragua and J. Reuter. F-Theory on all Toric Hypersurface Fibrations and its Higgs Branches. JHEP 01, 142 (2015), arXiv:1408.4808 [hep-th].\n\n\n\nS. Katz, D. R. Morrison, S. Schafer-Nameki and J. Sully. Tate's algorithm and F-theory. JHEP 08, 094 (2011), arXiv:1106.3854 [hep-th].\n\n\n\nJ. Kelleher and B. O'Sullivan. Generating All Partitions: A Comparison Of Two Encodings (2014), arXiv:0909.2331 [cs.DS].\n\n\n\nM. Kreuzer and L. Robbiano. Computational commutative algebra. II (Berlin: Springer, 2005); p. x + 586.\n\n\n\nG. Kemper and A. Steel. Some algorithms in invariant theory of finite groups. In: Computational methods for representations of groups and algebras (Essen, 1997), Vol. 173 of Progr. Math. (Birkhäuser, Basel, 1999); pp. 267–285.\n\n\n\nT. Kahle. Decompositions of binomial ideals. Ann. Inst. Statist. Math. 62, 727–745 (2010).\n\n\n\nG. Kemper. The calculation of radical ideals in positive characteristic. J. Symbolic Comput. 34, 229–238 (2002).\n\n\n\nG. Kemper. An algorithm to calculate optimal homogeneous systems of parameters. J. Symbolic Comput. 27, 171–184 (1999).\n\n\n\nS. King. Fast computation of secondary invariants (2007), arXiv:math/0701270 [math.AC].\n\n\n\nS. King. Minimal generating sets of non-modular invariant rings of finite groups. J. Symb. Comput. 48, 101–109 (2013).\n\n\n\nD. E. Knuth. The art of computer programming. Vol. 4A. Combinatorial algorithms. Part 1 (Addison-Wesley, Upper Saddle River, NJ, 2011); p. xv+883.\n\n\n\nJ. Kollár. Singularities of the minimal model program. Vol. 200 of Cambridge Tracts in Mathematics (Cambridge University Press, 2013). With a collaboration of Sándor Kovács.\n\n\n\nD. Kozlov. Combinatorial algebraic topology. Vol. 21 of Algorithms and Computation in Mathematics (Springer, Berlin, 2008).\n\n\n\nR. Lidl and H. Niederreiter. Finite fields. Second Edition, Vol. 20 of Encyclopedia of Mathematics and its Applications (Cambridge University Press, Cambridge, 1997); p. xiv+755. With a foreword by P. M. Cohn.\n\n\n\nV. Levandovskyy and H. 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. (New York, NY: ACM Press, 2003); pp. 176–183.\n\n\n\nC. Lawrie and S. Schäfer-Nameki. The Tate Form on Steroids: Resolution and Higher Codimension Fibers. JHEP 04, 061 (2013), arXiv:1212.2949 [hep-th].\n\n\n\nV. Levandovskyy. Non-commutative Computer Algebra for polynomial algebras: Gröbner bases, applications and implementation, doctoralthesis, Technische Universität Kaiserslautern (2005).\n\n\n\nQ. Liu. Algebraic geometry and arithmetic curves. Transl. by Reinie Erné. Vol. 6 of Oxf. Grad. Texts Math. (Oxford: Oxford University Press, 2006).\n\n\n\nE. Looijenga. Isolated Singular Points on Complete Intersections. Vol. 77 of LMS Lecture Note Series (Cambridge University Press, Cambridge, 1984); p. xi+200.\n\n\n\nT. Merkwitz, L. Naughton and G. Pfeiffer. TomLib, The GAP Library of Tables of Marks, Version 1.2.11 (Jan 2024). GAP package.\n\n\n\nR. V. Moody and J. Patera. Fast recursion formula for weight multiplicities. Bull. Amer. Math. Soc. (N.S.) 7, 237–242 (1982).\n\n\n\nT. Markwig and Y. Ren. Computing tropical varieties over fields with valuation. Found. Comput. Math. 20, 783–800 (2020).\n\n\n\nE. Miller and B. Sturmfels. Combinatorial commutative algebra. Vol. 227 (New York, NY: Springer, 2005); p. xiv + 417.\n\n\n\nD. Maclagan and B. Sturmfels. Introduction to tropical geometry. Vol. 161 (Providence, RI: American Mathematical Society (AMS), 2015); p. xii + 363.\n\n\n\nM. Michałek and B. Sturmfels. Invitation to nonlinear algebra. Vol. 211 (Providence, RI: American Mathematical Society (AMS), 2021); p. xiii + 226.\n\n\n\nD. A. Marcus. Number fields. Universitext (Springer, Cham, 2018); p. xviii+203. Second edition of [MR0457396], With a foreword by Barry Mazur.\n\n\n\nV. V. Nikulin. Integer symmetric bilinear forms and some of their geometric applications. Izv. Akad. Nauk SSSR Ser. Mat. 43, 111–177, 238 (1979).\n\n\n\nOEIS Foundation Inc. The On-Line Encyclopedia of Integer Sequences. Published electronically at https://oeis.org (2024).\n\n\n\nT. Oda and K. Miyake. Lectures on Torus Embeddings and Applications. Lectures on mathematics and physics (Tata Institute of Fundamental Research, 1978).\n\n\n\nI. Ojeda Martínez de Castilla and R. P. Sánchez. Cellular binomial ideals. Primary decomposition of binomial ideals. J. Symbolic Comput. 30, 383–400 (2000).\n\n\n\nJ. Oxley. Matroid theory. Second Edition, Vol. 21 of Oxford Graduate Texts in Mathematics (Oxford University Press, Oxford, 2011); p. xiv+684.\n\n\n\nA. Postnikov and R. P. Stanley. Chains in the Bruhat order. J. Algebraic Combin. 29, 133–174 (2009).\n\n\n\nS. Pokutta and A. S. Schulz. Integer-empty polytopes in the 0/1-cube with maximal Gomory–Chvátal rank. Operations research letters 39, 457–460 (2011).\n\n\n\nG. Pfister, A. Sadiq and S. Steidel. An algorithm for primary decomposition in polynomial rings over the integers. Cent. Eur. J. Math. 9, 897–904 (2011).\n\n\n\nM. Pohst and H. Zassenhaus. Algorithmic algebraic number theory. Vol. 30 of Encyclopedia of Mathematics and its Applications (Cambridge University Press, Cambridge, 1997); p. xiv+499. Revised reprint of the 1989 original.\n\n\n\nE. Pan. SOTGrps, Constructing and identifying groups of small order type, Version 1.2 (Jun 2023). GAP package.\n\n\n\nC. Pegel. Chow Rings of Toric Varieties. Master's thesis, University of Bremen (Faculty of Mathematics, Sep 2014). Refereed by Prof. Dr. Eva Maria Feichtner and Dr. Emanuele Delucchi.\n\n\n\nG. Pólya. On picture-writing. Amer. Math. Monthly 63, 689–697 (1956).\n\n\n\nS. Popescu. On smooth surfaces of degree geq 11 in the projective fourspace, doctoralthesis, Universität des Saarlandes, Saarbrücken (1993).\n\n\n\nA. Postnikov. Permutohedra, associahedra, and beyond. International Mathematics Research Notices 2009, 1026–1106 (2009).\n\n\n\nS. Posur. Linear systems over localizations of rings. Archiv der Mathematik 111, 23–32 (2018).\n\n\n\nW. Riha and K. R. James. Algorithm 29 efficient algorithms for doubly and multiply restricted partitions. Computing 16, 163–168 (1976).\n\n\n\nH. Roschy and T. Rahn. Cohomology of line bundles: Proof of the algorithm. Journal of Mathematical Physics 51, 103520 (2010).\n\n\n\nG. Rote, F. Santos and I. Streinu. Expansive motions and the polytope of pointed pseudo-triangulations. Discrete and Computational Geometry: The Goodman-Pollack Festschrift, 699–736 (2003).\n\n\n\nF. Rincón. Computing tropical linear spaces. J. Symb. Comput. 51, 86–98 (2013).\n\n\n\nC. Semple and M. Steel. Phylogenetics. Vol. 24 of Oxf. Lect. Ser. Math. Appl. (Oxford University Press, 2003).\n\n\n\nC. D. Savage and M. J. Schuster. Ehrhart series of lecture hall polytopes and Eulerian polynomials for inversion sequences. Journal of Combinatorial Theory, Series A 119, 850–870 (2012).\n\n\n\nA. J. Sommese and A. Van de Ven. On the adjunction mapping. Math. Ann. 278, 593–603 (1987).\n\n\n\nT. Shimoyama and K. Yokoyama. Localization and primary decomposition of polynomial ideals. J. Symbolic Comput. 22, 247–277 (1996).\n\n\n\nJ. Schmitt. On mathbb Q-factorial terminalizations of symplectic linear quotient singularities. Ph.D. Thesis, RPTU Kaiserslautern-Landau (2023).\n\n\n\nP. Schuchert. Matroid-Polytope und Einbettungen kombinatorischer Mannigfaltigkeiten. Ph.D. Thesis, TU Darmstadt (1995).\n\n\n\nÁ. Seress. Permutation group algorithms. Vol. 152 of Cambridge Tracts in Mathematics (Cambridge University Press, Cambridge, 2003); p. x+264.\n\n\n\nM. Sezer. Sharpening the generalized Noether bound in the invariant theory of finite groups. J. Algebra 254, 252–263 (2002).\n\n\n\nI. Shimada. An algorithm to compute automorphism groups of K3 surfaces and an application to singular K3 surfaces. Int. Math. Res. Not. IMRN, 11961–12014 (2015).\n\n\n\nI. Shimada. Connected Components of the Moduli of Elliptic K3 Surfaces. Michigan Mathematical Journal 67, 511–559 (2018).\n\n\n\nR. P. Stanley. Invariants of finite groups and their applications to combinatorics. Bull. Amer. Math. Soc. (N.S.) 1, 475–511 (1979).\n\n\n\nThe Stacks Project Authors. Stacks Project. Published electronically.\n\n\n\nJ. R. Stembridge. Computational aspects of root systems, Coxeter groups, and Weyl characters. In: Interaction of combinatorics and representation theory, Vol. 11 of MSJ Memoirs (The Mathematical Society of Japan, 2001); pp. 1–38.\n\n\n\nJ. Stevens. On the versal deformation of cyclic quotient singularities. In: Singularity theory and its applications, Part I (Coventry, 1988/1989), Vol. 1462 of Lecture Notes in Math. (Springer, Berlin, 1991); pp. 302–319.\n\n\n\nB. Sturmfels. Algorithms in invariant theory. Texts and Monographs in Symbolic Computation (Springer-Verlag, Vienna, 1993); p. vi+197.\n\n\n\nS. Sullivant. Algebraic statistics. Vol. 194 of Grad. Stud. Math. (Providence, RI: American Mathematical Society (AMS), 2018).\n\n\n\nP. Symonds. On the Castelnuovo-Mumford regularity of rings of polynomial invariants. Ann. of Math. (2) 174, 499–517 (2011).\n\n\n\nP. Tarrago and M. Weber. The classification of tensor categories of two-colored noncrossing partitions. Journal of Combinatorial Theory, Series A 154, 464–506 (2018).\n\n\n\nD. E. Taylor. Pairs of Generators for Matrix Groups. I. The Cayley Bulletin 3, 76–85 (1987), arXiv:2201.09155 [math.GR].\n\n\n\nQ.-N. Tran. A Fast Algorithm for Gröbner Basis Conversion and its Applications. Journal of Symbolic Computation 30, 451–467 (2000).\n\n\n\nQ.-N. Tran. Efficient Groebner walk conversion for implicitization of geometric objects. Computer Aided Geometric Design 21, 837–857 (2004).\n\n\n\nI. Turkalj. Reflective Lorentzian lattices of signature (5, 1). Journal of Algebra 513, 516–544 (2018).\n\n\n\nM. Vaughan-Lee and B. Eick. SglPPow, Database of groups of prime-power order for some prime-powers, Version 2.3 (Nov 2022). GAP package.\n\n\n\nE. B. Vinberg. Some arithmetical discrete groups in Lobacevsky spaces. In: Discrete subgroups of Lie groups and applications to moduli (Internat. Colloq., Bombay, 1973), No. 7 of Tata Inst. Fundam. Res. Stud. Math. (Published for the Tata Institute of Fundamental Research, Bombay by Oxford University Press, Bombay, 1975); pp. 323–348.\n\n\n\nS. Volz. Design and implementation of efficient algorithms for operations on partitions of sets. Bachelor's Thesis, Universität des Saarlandes (2023).\n\n\n\nL. C. Washington. Elliptic curves. Second Edition, Discrete Mathematics and its Applications (Boca Raton) (Chapman & Hall/CRC, Boca Raton, FL, 2008); p. xviii+513. Number theory and cryptography.\n\n\n\nT. Weigand. Lectures on F-theory compactifications and model building. Class. Quant. Grav. 27, 214004 (2010), arXiv:1009.3497 [hep-th].\n\n\n\nT. Weigand. TASI Lectures on F-theory. PoS TASI2017, 016 (2018), arXiv:1806.01854 [hep-th].\n\n\n\nJ. B. Wilson. Optimal algorithms of Gram-Schmidt type. Linear Algebra Appl. 438, 4573–4583 (2013).\n\n\n\nE. Witten. Topological Sigma Models. Commun. Math. Phys. 118, 411 (1988).\n\n\n\nE. Witten. On flux quantization in M theory and the effective action. J. Geom. Phys. 22, 1–13 (1997), arXiv:hep-th/9609122.\n\n\n\nR. Yamagishi. On smoothness of minimal models of quotient singularities by finite subgroups of mathrmSL_n(mathbb C). Glasg. Math. J. 60, 603–634 (2018).\n\n\n\nA. Zoghbi and I. Stojmenovic. Fast algorithms for generating integer partitions. Int. J. Comput. Math. 70, 319–332 (1998).\n\n\n\nG. M. Ziegler. Lectures on polytopes. Vol. 152 of Graduate Texts in Mathematics (Springer-Verlag, New York, 1995); p. x+370.\n\n\n\n","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 [Pos18].","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 [Pos18], 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, [Pos18] 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":"General/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"CurrentModule = Oscar\nDocTestSetup = Oscar.doctestsetup()","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 toric variety\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 mathbb Znmathbb Z, 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 mathbb Znmathbb Z, 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 access or install custom GAP packages (e.g. unpublished ones)?","category":"page"},{"location":"General/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"An already locally installed GAP package can be loaded into the OSCAR session via GAP.Packages.load, where the first argument is the local path to the package directory (the one that contains the PackageInfo.g file). This works only if no other version of this package has been loaded already.","category":"page"},{"location":"General/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"If Oscar loads the package in question already on startup but you want a different version of this package to be loaded, you can force this by storing the desired version in the pkg subdirectory of the user's root directory (GAPInfo.UserGapRoot in GAP).","category":"page"},{"location":"General/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Installing a new GAP package for which you know the URL of a package archive can be done via GAP.Packages.install, where the first argument is this URL.","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/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Q: How do I cite OSCAR?","category":"page"},{"location":"General/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Please see here.","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 [CLS11]). 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::NormalToricVarietyType, defining_polynomials::Vector{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}})\nclosed_subvariety_of_toric_variety(toric_variety::NormalToricVarietyType, defining_ideal::MPolyIdeal)","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/Subvarieties/#closed_subvariety_of_toric_variety-Tuple{Union{AffineNormalToricVariety, CyclicQuotientSingularity, NormalToricVariety}, Vector{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}}","page":"Subvarieties","title":"closed_subvariety_of_toric_variety","text":"closed_subvariety_of_toric_variety(toric_variety::NormalToricVarietyType, 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 [CLS11] 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{Union{AffineNormalToricVariety, CyclicQuotientSingularity, NormalToricVariety}, MPolyIdeal}","page":"Subvarieties","title":"closed_subvariety_of_toric_variety","text":"closed_subvariety_of_toric_variety(toric_variety::NormalToricVarietyType, 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 [CLS11] 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 [CLS11].\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::T) -> Map{T, 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)[1] mod(Integers, n)\nfinite_field(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.Note also that R and S may differ w.r.t. some structural properties because GAP does not support all kinds of constructions that are possible in Oscar. For example, if R is a non-simple number field then S will be a simple extension because GAP knows only simple field extensions. Thus using Oscar.iso_oscar_gap(R) for objects R whose recursive structure is not fully supported in GAP will likely cause overhead at runtime.\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{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)[1]\nGF(p, d) finite_field(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/manual/number_fields/conventions/#Conventions","page":"Conventions","title":"Conventions","text":"","category":"section"},{"location":"Hecke/manual/number_fields/conventions/","page":"Conventions","title":"Conventions","text":"By an absolute number field we mean finite extensions of mathbf Q, which is of type AbsSimpleNumField and whose elements are of type AbsSimpleNumFieldElem. 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/manual/number_fields/conventions/","page":"Conventions","title":"Conventions","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/manual/number_fields/conventions/","page":"Conventions","title":"Conventions","text":"beta cdot (1alphadotscalpha^d-1) = M_alpha (1 alpha dotsc alpha^d-1)","category":"page"},{"location":"Hecke/manual/number_fields/conventions/","page":"Conventions","title":"Conventions","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/manual/number_fields/conventions/","page":"Conventions","title":"Conventions","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/manual/number_fields/conventions/","page":"Conventions","title":"Conventions","text":"is called the Minkowski map (or Minkowski embedding).","category":"page"},{"location":"Hecke/manual/number_fields/conventions/","page":"Conventions","title":"Conventions","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/manual/number_fields/conventions/","page":"Conventions","title":"Conventions","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/manual/number_fields/conventions/","page":"Conventions","title":"Conventions","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/manual/number_fields/conventions/","page":"Conventions","title":"Conventions","text":"is called the Minkowski matrix of mathcal O.","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::AbsAffineScheme{<: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 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 ideal (x^3 + y + 1)\n\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/AlgebraicVarieties/AffineVariety/#variety-Tuple{AbsAffineScheme{<:Field}}","page":"Affine Varieties","title":"variety","text":"variety(X::AbsAffineScheme; 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, Oscar.MPolyLocRing, Oscar.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 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 spaces with isometry","title":"Quadratic spaces with isometry","text":"CurrentModule = Oscar","category":"page"},{"location":"Experimental/QuadFormAndIsom/spacewithisom/#Quadratic-spaces-with-isometry","page":"Quadratic spaces with isometry","title":"Quadratic spaces with isometry","text":"","category":"section"},{"location":"Experimental/QuadFormAndIsom/spacewithisom/","page":"Quadratic spaces with isometry","title":"Quadratic spaces 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 Spaces of the documentation for new users.","category":"page"},{"location":"Experimental/QuadFormAndIsom/spacewithisom/","page":"Quadratic spaces with isometry","title":"Quadratic spaces with isometry","text":"Note that currently, we support only rational quadratic forms, i.e. quadratic spaces defined over mathbbQ.","category":"page"},{"location":"Experimental/QuadFormAndIsom/spacewithisom/","page":"Quadratic spaces with isometry","title":"Quadratic spaces with isometry","text":"In Oscar, such a pair is encoded by the type called QuadSpaceWithIsom:","category":"page"},{"location":"Experimental/QuadFormAndIsom/spacewithisom/","page":"Quadratic spaces with isometry","title":"Quadratic spaces with isometry","text":"QuadSpaceWithIsom","category":"page"},{"location":"Experimental/QuadFormAndIsom/spacewithisom/#QuadSpaceWithIsom","page":"Quadratic spaces with isometry","title":"QuadSpaceWithIsom","text":"QuadSpaceWithIsom\n\nA container type for pairs (V f) consisting of a 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 infinite.\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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"type"},{"location":"Experimental/QuadFormAndIsom/spacewithisom/","page":"Quadratic spaces with isometry","title":"Quadratic spaces with isometry","text":"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 spaces with isometry","title":"Quadratic spaces 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 spaces with isometry","title":"Quadratic spaces with isometry","text":"isometry(::QuadSpaceWithIsom)\norder_of_isometry(::QuadSpaceWithIsom)\nspace(::QuadSpaceWithIsom)","category":"page"},{"location":"Experimental/QuadFormAndIsom/spacewithisom/#isometry-Tuple{QuadSpaceWithIsom}","page":"Quadratic spaces 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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/spacewithisom/#order_of_isometry-Tuple{QuadSpaceWithIsom}","page":"Quadratic spaces 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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/spacewithisom/#space-Tuple{QuadSpaceWithIsom}","page":"Quadratic spaces 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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/spacewithisom/","page":"Quadratic spaces with isometry","title":"Quadratic spaces 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 spaces with isometry","title":"Constructors","text":"","category":"section"},{"location":"Experimental/QuadFormAndIsom/spacewithisom/","page":"Quadratic spaces with isometry","title":"Quadratic spaces 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 spaces with isometry","title":"Quadratic spaces 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 spaces 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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/spacewithisom/#quadratic_space_with_isometry-Tuple{Hecke.QuadSpace}","page":"Quadratic spaces 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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/spacewithisom/","page":"Quadratic spaces with isometry","title":"Quadratic spaces 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 spaces with isometry","title":"Attributes and first operations","text":"","category":"section"},{"location":"Experimental/QuadFormAndIsom/spacewithisom/","page":"Quadratic spaces with isometry","title":"Quadratic spaces 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 spaces with isometry","title":"Quadratic spaces 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 spaces 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 spaces 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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/spacewithisom/#diagonal-Tuple{QuadSpaceWithIsom}","page":"Quadratic spaces 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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/spacewithisom/#dim-Tuple{QuadSpaceWithIsom}","page":"Quadratic spaces 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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/spacewithisom/#discriminant-Tuple{QuadSpaceWithIsom}","page":"Quadratic spaces 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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/spacewithisom/#gram_matrix-Tuple{QuadSpaceWithIsom}","page":"Quadratic spaces 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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/spacewithisom/#is_definite-Tuple{QuadSpaceWithIsom}","page":"Quadratic spaces 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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/spacewithisom/#is_positive_definite-Tuple{QuadSpaceWithIsom}","page":"Quadratic spaces 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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/spacewithisom/#is_negative_definite-Tuple{QuadSpaceWithIsom}","page":"Quadratic spaces 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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/spacewithisom/#minimal_polynomial-Tuple{QuadSpaceWithIsom}","page":"Quadratic spaces 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 spaces 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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/spacewithisom/#signature_tuple-Tuple{QuadSpaceWithIsom}","page":"Quadratic spaces 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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/spacewithisom/","page":"Quadratic spaces with isometry","title":"Quadratic spaces with isometry","text":"Similarly, some basic operations on quadratic spaces and matrices are available for quadratic spaces with isometry.","category":"page"},{"location":"Experimental/QuadFormAndIsom/spacewithisom/","page":"Quadratic spaces with isometry","title":"Quadratic spaces 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 spaces 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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/spacewithisom/#biproduct-Tuple{Vector{QuadSpaceWithIsom}}","page":"Quadratic spaces 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: quadratic space -> quadratic space, Map: quadratic space -> quadratic space], AbstractSpaceMor[Map: quadratic space -> quadratic space, Map: quadratic space -> quadratic space])\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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/spacewithisom/#direct_product-Tuple{Vector{QuadSpaceWithIsom}}","page":"Quadratic spaces with isometry","title":"direct_product","text":"direct_product(algebras::StructureConstantAlgebra...; task::Symbol = :sum)\n -> StructureConstantAlgebra, Vector{AbsAlgAssMor}, Vector{AbsAlgAssMor}\ndirect_product(algebras::Vector{StructureConstantAlgebra}; task::Symbol = :sum)\n -> StructureConstantAlgebra, 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(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: quadratic space -> quadratic space, Map: quadratic space -> quadratic space])\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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/spacewithisom/#direct_sum-Tuple{Vector{QuadSpaceWithIsom}}","page":"Quadratic spaces with isometry","title":"direct_sum","text":"direct_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(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: quadratic space -> quadratic space, Map: quadratic space -> quadratic space])\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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/spacewithisom/#rescale-Tuple{QuadSpaceWithIsom, Union{Integer, QQFieldElem, ZZRingElem, Rational}}","page":"Quadratic spaces 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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/spacewithisom/#Spinor-norm","page":"Quadratic spaces with isometry","title":"Spinor norm","text":"","category":"section"},{"location":"Experimental/QuadFormAndIsom/spacewithisom/","page":"Quadratic spaces with isometry","title":"Quadratic spaces with isometry","text":"Given a rational quadratic space (V Phi), and given an integer binmathbbQ, we define the rational spinor norm sigma on (V bPhi) to be the group homomorphism","category":"page"},{"location":"Experimental/QuadFormAndIsom/spacewithisom/","page":"Quadratic spaces with isometry","title":"Quadratic spaces with isometry","text":"sigmacolon O(V bPhi) = O(V Phi)to mathbbQ^ast(mathbbQ^ast)^2","category":"page"},{"location":"Experimental/QuadFormAndIsom/spacewithisom/","page":"Quadratic spaces with isometry","title":"Quadratic spaces with isometry","text":"defined as follows. For fin O(V bPhi), there exist elements v_1ldots v_rin V where 1leq rleq textrank(V) such that f = tau_v_1circcdotscirc tau_v_r is equal to the product of the associated reflections. We define","category":"page"},{"location":"Experimental/QuadFormAndIsom/spacewithisom/","page":"Quadratic spaces with isometry","title":"Quadratic spaces with isometry","text":"sigma(f) = (-fracbPhi(v_1 v_1)2)cdots(-fracbPhi(v_rv_r)2) mod (mathbbQ^ast)^2","category":"page"},{"location":"Experimental/QuadFormAndIsom/spacewithisom/","page":"Quadratic spaces with isometry","title":"Quadratic spaces with isometry","text":"rational_spinor_norm(::QuadSpaceWithIsom)","category":"page"},{"location":"Experimental/QuadFormAndIsom/spacewithisom/#rational_spinor_norm-Tuple{QuadSpaceWithIsom}","page":"Quadratic spaces with isometry","title":"rational_spinor_norm","text":"rational_spinor_norm(Vf::QuadSpaceWithIsom; b::Int = -1) -> QQFieldElem\n\nGiven a rational quadratic space with isometry (V b f), return the rational spinor norm of f.\n\nIf Phi is the form on V, then the spinor norm is computed with respect to bPhi.\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/spacewithisom/#Equality","page":"Quadratic spaces with isometry","title":"Equality","text":"","category":"section"},{"location":"Experimental/QuadFormAndIsom/spacewithisom/","page":"Quadratic spaces with isometry","title":"Quadratic spaces with isometry","text":"We choose as a convention that two pairs (V f) and (V f) of quadratic spaces with isometries are equal 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":"Experimental/IntersectionTheory/AbstractVarieties/","page":"Abstract Varieties","title":"Abstract Varieties","text":"CurrentModule = Oscar\nDocTestSetup = Oscar.doctestsetup()","category":"page"},{"location":"Experimental/IntersectionTheory/AbstractVarieties/#Abstract-Varieties","page":"Abstract Varieties","title":"Abstract Varieties","text":"","category":"section"},{"location":"Experimental/IntersectionTheory/AbstractVarieties/#Types","page":"Abstract Varieties","title":"Types","text":"","category":"section"},{"location":"Experimental/IntersectionTheory/AbstractVarieties/","page":"Abstract Varieties","title":"Abstract Varieties","text":"AbsVariety <: Variety","category":"page"},{"location":"Experimental/IntersectionTheory/AbstractVarieties/#Constructors","page":"Abstract Varieties","title":"Constructors","text":"","category":"section"},{"location":"Experimental/IntersectionTheory/AbstractVarieties/","page":"Abstract Varieties","title":"Abstract Varieties","text":"abstract_variety(n::Int, A::MPolyDecRingOrQuo)","category":"page"},{"location":"Experimental/IntersectionTheory/AbstractVarieties/#abstract_variety-Tuple{Int64, MPolyDecRingOrQuo}","page":"Abstract Varieties","title":"abstract_variety","text":" abstract_variety(n::Int, A::Union{MPolyDecRing, MPolyQuoRing{<:MPolyDecRingElem}})\n\nReturn an abstract variety of dimension n with Chow ring A.\n\nExamples\n\njulia> R, (h,) = graded_polynomial_ring(QQ, [:h])\n(Graded multivariate polynomial ring in 1 variable over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[h])\n\njulia> A, _ = quo(R, ideal(R, [h^3]))\n(Quotient of multivariate polynomial ring by ideal (h^3), Map: R -> A)\n\njulia> P2 = abstract_variety(2, A)\nAbstractVariety of dim 2\n\nnote: Note\nThe example above shows one way of setting up a version of the abstract projective plane. A more convenient way is to use the built-in command abstract_projective_space which implements additional data such as the tangent bundle:\n\njulia> P2 = abstract_projective_space(2)\nAbstractVariety of dim 2\n\njulia> TP2 = tangent_bundle(P2)\nAbstractBundle of rank 2 on AbstractVariety of dim 2\n\njulia> chern_character(TP2)\n3//2*h^2 + 3*h + 2\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/IntersectionTheory/AbstractVarieties/","page":"Abstract Varieties","title":"Abstract Varieties","text":"abstract_point()","category":"page"},{"location":"Experimental/IntersectionTheory/AbstractVarieties/#abstract_point-Tuple{}","page":"Abstract Varieties","title":"abstract_point","text":"abstract_point()\n\nReturn an abstract variety consisting of a point.\n\nExamples\n\njulia> p = abstract_point()\nAbstractVariety of dim 0\n\njulia> chow_ring(p)\nQuotient\n of multivariate polynomial ring in 1 variable over QQ graded by\n p -> [1]\n by ideal (p)\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/IntersectionTheory/AbstractVarieties/#Specialized-Constructors","page":"Abstract Varieties","title":"Specialized Constructors","text":"","category":"section"},{"location":"Experimental/IntersectionTheory/AbstractVarieties/","page":"Abstract Varieties","title":"Abstract Varieties","text":"abstract_projective_space(n::Int; base::Ring = QQ, symbol::String = \"h\")","category":"page"},{"location":"Experimental/IntersectionTheory/AbstractVarieties/#abstract_projective_space-Tuple{Int64}","page":"Abstract Varieties","title":"abstract_projective_space","text":"abstract_projective_space(n::Int; base::Ring = QQ, symbol::String = \"h\")\n\nReturn the abstract projective space of lines in an n+1-dimensional vector space.\n\nExamples\n\njulia> P3 = abstract_projective_space(3)\nAbstractVariety of dim 3\n\njulia> chow_ring(P3)\nQuotient\n of multivariate polynomial ring in 1 variable over QQ graded by\n h -> [1]\n by ideal (h^4)\n\njulia> T, (s,t) = polynomial_ring(QQ, [:s, :t])\n(Multivariate polynomial ring in 2 variables over QQ, QQMPolyRingElem[s, t])\n\njulia> QT = fraction_field(T)\nFraction field\n of multivariate polynomial ring in 2 variables over QQ\n\njulia> P3 = abstract_projective_space(3, base = QT)\nAbstractVariety of dim 3\n\njulia> chow_ring(P3)\nQuotient\n of multivariate polynomial ring in 1 variable over QT graded by\n h -> [1]\n by ideal (h^4)\n\njulia> TB = tangent_bundle(P3)\nAbstractBundle of rank 3 on AbstractVariety of dim 3\n\njulia> CTB = cotangent_bundle(P3)\nAbstractBundle of rank 3 on AbstractVariety of dim 3\n\njulia> chern_character((s*TB)*(t*CTB))\n-4*s*t*h^2 + 9*s*t\n\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/IntersectionTheory/AbstractVarieties/","page":"Abstract Varieties","title":"Abstract Varieties","text":"abstract_grassmannian(k::Int, n::Int; bott::Bool = false, weights = :int, base::Ring = QQ, symbol::String = \"c\")","category":"page"},{"location":"Experimental/IntersectionTheory/AbstractVarieties/#abstract_grassmannian-Tuple{Int64, Int64}","page":"Abstract Varieties","title":"abstract_grassmannian","text":"abstract_grassmannian(k::Int, n::Int; base::Ring = QQ, symbol::String = \"c\")\n\nReturn the abstract Grassmannian mathrmG(k n) of k-dimensional subspaces of an n-dimensional vector space.\n\nExamples\n\njulia> G = abstract_grassmannian(2,4)\nAbstractVariety of dim 4\n\njulia> CR = chow_ring(G)\nQuotient\n of multivariate polynomial ring in 2 variables over QQ graded by\n c[1] -> [1]\n c[2] -> [2]\n by ideal (-c[1]^3 + 2*c[1]*c[2], c[1]^4 - 3*c[1]^2*c[2] + c[2]^2)\n\njulia> S = tautological_bundles(G)[1]\nAbstractBundle of rank 2 on AbstractVariety of dim 4\n\njulia> V = [chern_class(S, i) for i = 1:2]\n2-element Vector{MPolyQuoRingElem{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}}:\n c[1]\n c[2]\n\njulia> is_regular_sequence(gens(modulus(CR)))\ntrue\n\njulia> Q = tautological_bundles(G)[2]\nAbstractBundle of rank 2 on AbstractVariety of dim 4\n\njulia> tangent_bundle(G) == dual(S)*Q\ntrue\n\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/IntersectionTheory/AbstractVarieties/","page":"Abstract Varieties","title":"Abstract Varieties","text":"abstract_flag_variety(dims::Int...; base::Ring = QQ, symbol::String = \"c\")","category":"page"},{"location":"Experimental/IntersectionTheory/AbstractVarieties/#abstract_flag_variety-Tuple{Vararg{Int64}}","page":"Abstract Varieties","title":"abstract_flag_variety","text":"abstract_flag_variety(dims::Int...; base::Ring = QQ, symbol::String = \"c\")\nabstract_flag_variety(dims::Vector{Int}; base::Ring = QQ, symbol::String = \"c\")\n\nGiven integers, say, d_1 dots d_k n with 0 d_1 dots d_k n or a vector of such integers, return the abstract flag variety mathrmF(d_1 dots d_k n) of nested sequences of subspaces of dimensions d_1 dots d_k of an n-dimensional vector space.\n\nExamples\n\njulia> F = abstract_flag_variety(1,3,4)\nAbstractVariety of dim 5\n\njulia> chow_ring(F)\nQuotient\n of multivariate polynomial ring in 4 variables over QQ graded by\n c[1, 1] -> [1]\n c[2, 1] -> [1]\n c[2, 2] -> [2]\n c[3, 1] -> [1]\n by ideal with 4 generators\n\njulia> modulus(chow_ring(F))\nIdeal generated by\n -c[1, 1]*c[2, 2]*c[3, 1]\n -c[1, 1]*c[2, 1]*c[3, 1] - c[1, 1]*c[2, 2] - c[2, 2]*c[3, 1]\n -c[1, 1]*c[2, 1] - c[1, 1]*c[3, 1] - c[2, 1]*c[3, 1] - c[2, 2]\n -c[1, 1] - c[2, 1] - c[3, 1]\n\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/IntersectionTheory/AbstractVarieties/#New-Varieties-From-Given-Varieties/Bundles","page":"Abstract Varieties","title":"New Varieties From Given Varieties/Bundles","text":"","category":"section"},{"location":"Experimental/IntersectionTheory/AbstractVarieties/","page":"Abstract Varieties","title":"Abstract Varieties","text":"complete_intersection(X::AbstractVariety, degs::Int...)","category":"page"},{"location":"Experimental/IntersectionTheory/AbstractVarieties/#complete_intersection-Tuple{AbstractVariety, Vararg{Int64}}","page":"Abstract Varieties","title":"complete_intersection","text":"complete_intersection(X::AbstractVariety, degs::Int...)\ncomplete_intersection(X::AbstractVariety, degs::Vector{Int})\n\nReturn the complete intersection in X of general hypersurfaces with the given degrees.\n\nExamples\n\njulia> P3 = abstract_projective_space(3)\nAbstractVariety of dim 3\n\njulia> CI = complete_intersection(P3, 2, 2)\nAbstractVariety of dim 1\n\njulia> dim(CI)\n1\n\njulia> degree(CI)\n4\n\njulia> chow_ring(CI)\nQuotient\n of multivariate polynomial ring in 1 variable over QQ graded by\n h -> [1]\n by ideal (h^2)\n\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/IntersectionTheory/AbstractVarieties/","page":"Abstract Varieties","title":"Abstract Varieties","text":"abstract_projective_bundle(F::AbstractBundle; symbol::String = \"z\")","category":"page"},{"location":"Experimental/IntersectionTheory/AbstractVarieties/#abstract_projective_bundle-Tuple{AbstractBundle}","page":"Abstract Varieties","title":"abstract_projective_bundle","text":"abstract_projective_bundle(F::AbstractBundle; symbol::String = \"z\")\n\nReturn the projective bundle of 1-dimensional subspaces in the fibers of F.\n\nExamples\n\njulia> P2 = abstract_projective_space(2)\nAbstractVariety of dim 2\n\njulia> T = tangent_bundle(P2)\nAbstractBundle of rank 2 on AbstractVariety of dim 2\n\njulia> PT = abstract_projective_bundle(T)\nAbstractVariety of dim 3\n\njulia> chow_ring(PT)\nQuotient\n of multivariate polynomial ring in 2 variables over QQ graded by\n z -> [1]\n h -> [1]\n by ideal (h^3, z^2 + 3*z*h + 3*h^2)\n\njulia> [chern_class(T, i) for i = 1:2]\n2-element Vector{MPolyQuoRingElem{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}}:\n 3*h\n 3*h^2\n\njulia> gens(PT)[1]\nz\n\njulia> gens(PT)[1] == hyperplane_class(PT)\ntrue\n\n\njulia> G = abstract_grassmannian(3, 5)\nAbstractVariety of dim 6\n\njulia> USBd = dual(tautological_bundles(G)[1])\nAbstractBundle of rank 3 on AbstractVariety of dim 6\n\njulia> F = symmetric_power(USBd, 2)\nAbstractBundle of rank 6 on AbstractVariety of dim 6\n\njulia> PF = abstract_projective_bundle(F)\nAbstractVariety of dim 11\n\njulia> A = symmetric_power(USBd, 5) - symmetric_power(USBd, 3)*OO(PF, -1)\nAbstractBundle of rank 11 on AbstractVariety of dim 11\n\njulia> integral(top_chern_class(A))\n609250\n\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/IntersectionTheory/AbstractVarieties/","page":"Abstract Varieties","title":"Abstract Varieties","text":"abstract_hirzebruch_surface(n::Int)","category":"page"},{"location":"Experimental/IntersectionTheory/AbstractVarieties/#abstract_hirzebruch_surface-Tuple{Int64}","page":"Abstract Varieties","title":"abstract_hirzebruch_surface","text":"abstract_hirzebruch_surface(n::Int)\n\nReturn the n-th Hirzebruch surface.\n\nnote: Note\nRecall that the n-th Hirzebruch surface is the projective bundle associated to the bundle mathcal O_mathbb P_1 oplus O_mathbb P_1(-n).\n\nExamples\n\njulia> H2 = abstract_hirzebruch_surface(2)\nAbstractVariety of dim 2\n\njulia> chow_ring(H2)\nQuotient\n of multivariate polynomial ring in 2 variables over QQ graded by\n z -> [1]\n h -> [1]\n by ideal (h^2, z^2 - 2*z*h)\n\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/IntersectionTheory/AbstractVarieties/","page":"Abstract Varieties","title":"Abstract Varieties","text":"abstract_flag_bundle(F::AbstractBundle, dims::Int...; symbol::String = \"c\")","category":"page"},{"location":"Experimental/IntersectionTheory/AbstractVarieties/#abstract_flag_bundle-Tuple{AbstractBundle, Vararg{Int64}}","page":"Abstract Varieties","title":"abstract_flag_bundle","text":"abstract_flag_bundle(F::AbstractBundle, dims::Int...; symbol::String = \"c\")\nabstract_flag_bundle(F::AbstractBundle, dims::Vector{Int}; symbol::String = \"c\")\n\nGiven integers, say, d_1 dots d_k n with 0 d_1 dots d_k n or a vector of such integers, and given an abstract bundle F of rank n, return the abstract flag bundle of nested sequences of subspaces of dimensions d_1 dots d_k in the fibers of F.\n\nnote: Note\nEntering the number n can be omitted since this number can be recovered as the rank of F.\n\nExamples\n\njulia> P = abstract_projective_space(4)\nAbstractVariety of dim 4\n\njulia> F = exterior_power(cotangent_bundle(P), 3)*OO(P,3)\nAbstractBundle of rank 4 on AbstractVariety of dim 4\n\njulia> FB = abstract_flag_bundle(F, 1, 3)\nAbstractVariety of dim 9\n\njulia> CR = chow_ring(FB)\nQuotient\n of multivariate polynomial ring in 5 variables over QQ graded by\n c[1, 1] -> [1]\n c[2, 1] -> [1]\n c[2, 2] -> [2]\n c[3, 1] -> [1]\n h -> [1]\n by ideal with 5 generators\n\njulia> modulus(CR)\nIdeal generated by\n h^5\n -c[1, 1]*c[2, 2]*c[3, 1] + h^4\n -c[1, 1]*c[2, 1]*c[3, 1] - c[1, 1]*c[2, 2] - c[2, 2]*c[3, 1] - 2*h^3\n -c[1, 1]*c[2, 1] - c[1, 1]*c[3, 1] - c[2, 1]*c[3, 1] - c[2, 2] + 4*h^2\n -c[1, 1] - c[2, 1] - c[3, 1] - 3*h\n\njulia> FB.bundles\n3-element Vector{AbstractBundle}:\n AbstractBundle of rank 1 on AbstractVariety of dim 9\n AbstractBundle of rank 2 on AbstractVariety of dim 9\n AbstractBundle of rank 1 on AbstractVariety of dim 9\n\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/IntersectionTheory/AbstractVarieties/","page":"Abstract Varieties","title":"Abstract Varieties","text":"zero_locus_section(F::AbstractBundle; class::Bool = false)","category":"page"},{"location":"Experimental/IntersectionTheory/AbstractVarieties/#zero_locus_section-Tuple{AbstractBundle}","page":"Abstract Varieties","title":"zero_locus_section","text":"zero_locus_section(F::AbstractBundle; class::Bool = false)\n\nReturn the zero locus of a general section of F.\n\nUse the argument class = true to only compute the class of the zero locus (same as top_chern_class(F)).\n\nExamples\n\njulia> P2 = abstract_projective_space(2)\nAbstractVariety of dim 2\n\njulia> C = zero_locus_section(OO(P2, 3)) # a plane cubic curve\nAbstractVariety of dim 1\n\njulia> dim(C)\n1\n\njulia> degree(C)\n3\n\n\njulia> P3 = abstract_projective_space(3)\nAbstractVariety of dim 3\n\njulia> C = zero_locus_section(OO(P3, 2) + OO(P3, 2)) # a complete intersection\nAbstractVariety of dim 1\n\njulia> dim(C)\n1\n\njulia> degree(C)\n4\n\n\njulia> P4 = abstract_projective_space(4)\nAbstractVariety of dim 4\n\njulia> h = gens(P4)[1]\nh\n\njulia> F = abstract_bundle(P4, 2, 10*h^2 + 5*h + 1) # Horrocks-Mumford bundle\nAbstractBundle of rank 2 on AbstractVariety of dim 4\n\njulia> A = zero_locus_section(F) # abelian surface\nAbstractVariety of dim 2\n\njulia> dim(A)\n2\n\njulia> degree(A)\n10\n\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/IntersectionTheory/AbstractVarieties/","page":"Abstract Varieties","title":"Abstract Varieties","text":"degeneracy_locus(F::AbstractBundle, G::AbstractBundle, k::Int; class::Bool=false)","category":"page"},{"location":"Experimental/IntersectionTheory/AbstractVarieties/#degeneracy_locus-Tuple{AbstractBundle, AbstractBundle, Int64}","page":"Abstract Varieties","title":"degeneracy_locus","text":"degeneracy_locus(F::AbstractBundle, G::AbstractBundle, k::Int; class::Bool=false)\n\nReturn the k-th degeneracy locus of a general map from F to G.\n\nUse the argument class = true to only compute the class of the degeneracy locus (Porteous' formula).\n\nExamples\n\njulia> P4 = abstract_projective_space(4)\nAbstractVariety of dim 4\n\njulia> F = 3*OO(P4, -1)\nAbstractBundle of rank 3 on AbstractVariety of dim 4\n\njulia> G = cotangent_bundle(P4)*OO(P4,1)\nAbstractBundle of rank 4 on AbstractVariety of dim 4\n\njulia> CZ = degeneracy_locus(F, G, 2, class = true) # only class of degeneracy locus\n4*h^2\n\njulia> CZ == chern_class(G-F, 2) # Porteous' formula\ntrue\n\njulia> Z = degeneracy_locus(F, G, 2) # Veronese surface in P4\nAbstractVariety of dim 2\n\njulia> degree(Z)\n4\n\n\njulia> P = abstract_projective_space(4, symbol = \"H\")\nAbstractVariety of dim 4\n\njulia> F = exterior_power(cotangent_bundle(P), 3)*OO(P,3)\nAbstractBundle of rank 4 on AbstractVariety of dim 4\n\njulia> G = OO(P, 1)+4*OO(P)\nAbstractBundle of rank 5 on AbstractVariety of dim 4\n\njulia> Z = degeneracy_locus(F, G, 3) # rational surface in P4\nAbstractVariety of dim 2\n\njulia> K = canonical_class(Z)\nz - H\n\njulia> integral(K^2)\n-7\n\njulia> H = hyperplane_class(Z)\nH\n\njulia> integral(H^2) # degree of surface\n8\n\njulia> A = K+H\nz\n\njulia> integral(A^2) # degree of first adjoint surface which is a Del Pezzo surface in P5\n5\n\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/IntersectionTheory/AbstractVarieties/","page":"Abstract Varieties","title":"Abstract Varieties","text":"note: Note\nProducts and blowups are described elsewhere.","category":"page"},{"location":"Experimental/IntersectionTheory/AbstractVarieties/#Underlying-Data-of-an-Abstract-Variety","page":"Abstract Varieties","title":"Underlying Data of an Abstract Variety","text":"","category":"section"},{"location":"Experimental/IntersectionTheory/AbstractVarieties/","page":"Abstract Varieties","title":"Abstract Varieties","text":"An abstract variety is made up from (a selection of) the data discussed here:","category":"page"},{"location":"Experimental/IntersectionTheory/AbstractVarieties/","page":"Abstract Varieties","title":"Abstract Varieties","text":"dim(X::AbstractVariety)","category":"page"},{"location":"Experimental/IntersectionTheory/AbstractVarieties/#dim-Tuple{AbstractVariety}","page":"Abstract Varieties","title":"dim","text":" dim(X::AbstractVariety)\n\nReturn the dimension of X.\n\nExamples\n\njulia> P2 = abstract_projective_space(2)\nAbstractVariety of dim 2\n\njulia> P3 = abstract_projective_space(3)\nAbstractVariety of dim 3\n\njulia> dim(P2*P3)\n5\n\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/IntersectionTheory/AbstractVarieties/","page":"Abstract Varieties","title":"Abstract Varieties","text":"chow_ring(X::AbstractVariety)","category":"page"},{"location":"Experimental/IntersectionTheory/AbstractVarieties/#chow_ring-Tuple{AbstractVariety}","page":"Abstract Varieties","title":"chow_ring","text":"chow_ring(X::AbstractVariety)\n\nReturn the Chow ring of the abstract variety X.\n\nExamples\n\njulia> P2 = abstract_projective_space(2)\nAbstractVariety of dim 2\n\njulia> P3 = abstract_projective_space(3, symbol = \"H\")\nAbstractVariety of dim 3\n\njulia> chow_ring(P2*P3)\nQuotient\n of multivariate polynomial ring in 2 variables over QQ graded by\n h -> [1]\n H -> [1]\n by ideal (h^3, H^4)\n\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/IntersectionTheory/AbstractVarieties/","page":"Abstract Varieties","title":"Abstract Varieties","text":"base(X::AbstractVariety)","category":"page"},{"location":"Experimental/IntersectionTheory/AbstractVarieties/#base-Tuple{AbstractVariety}","page":"Abstract Varieties","title":"base","text":"base(X::AbstractVariety)\n\nReturn the coefficient ring of the polynomial ring underlying the Chow ring of X.\n\nExamples\n\njulia> P2 = abstract_projective_space(2)\nAbstractVariety of dim 2\n\njulia> chow_ring(P2)\nQuotient\n of multivariate polynomial ring in 1 variable over QQ graded by\n h -> [1]\n by ideal (h^3)\n\njulia> base(P2)\nRational field\n\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/IntersectionTheory/AbstractVarieties/","page":"Abstract Varieties","title":"Abstract Varieties","text":"point_class(X::AbstractVariety)","category":"page"},{"location":"Experimental/IntersectionTheory/AbstractVarieties/#point_class-Tuple{AbstractVariety}","page":"Abstract Varieties","title":"point_class","text":"point_class(X::AbstractVariety)\n\nReturn the point class of X.\n\nExamples\n\njulia> P2 = abstract_projective_space(2)\nAbstractVariety of dim 2\n\njulia> P3 = abstract_projective_space(3, symbol = \"H\")\nAbstractVariety of dim 3\n\njulia> p = point_class(P2*P3)\nh^2*H^3\n\njulia> degree(p)\n[5]\n\njulia> integral(p)\n1\n\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/IntersectionTheory/AbstractVarieties/","page":"Abstract Varieties","title":"Abstract Varieties","text":"tangent_bundle(X::AbstractVariety)","category":"page"},{"location":"Experimental/IntersectionTheory/AbstractVarieties/#tangent_bundle-Tuple{AbstractVariety}","page":"Abstract Varieties","title":"tangent_bundle","text":"tangent_bundle(X::AbstractVariety)\n\nReturn the tangent bundle of X.\n\nExamples\n\njulia> G = abstract_grassmannian(2,5)\nAbstractVariety of dim 6\n\njulia> TG = tangent_bundle(G)\nAbstractBundle of rank 6 on AbstractVariety of dim 6\n\njulia> chern_character(TG)\n-5//6*c[1]^3 + 5//24*c[1]^2*c[2] + 3//2*c[1]^2 + 5//2*c[1]*c[2] - 5*c[1] + 7//72*c[2]^3 - 25//24*c[2]^2 - c[2] + 6\n\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/IntersectionTheory/AbstractVarieties/","page":"Abstract Varieties","title":"Abstract Varieties","text":"hyperplane_class(X::AbstractVariety)","category":"page"},{"location":"Experimental/IntersectionTheory/AbstractVarieties/#hyperplane_class-Tuple{AbstractVariety}","page":"Abstract Varieties","title":"hyperplane_class","text":"hyperplane_class(X::AbstractVariety)\n\nIf defined, return the class of a hyperplane section of X.\n\nnote: Note\nSpeaking of a hyperplane class of X means that we have a specific embedding of X into projective space in mind. For Grassmanians, for example, this embedding is the Plücker embedding. For the product of two abstract varieties with given hyperplane classes, it is the Segre embedding.\n\nExamples\n\njulia> G = abstract_grassmannian(2, 5)\nAbstractVariety of dim 6\n\njulia> hyperplane_class(G)\n-c[1]\n\njulia> degree(G) == integral(hyperplane_class(G)^dim(G)) == 5\ntrue\n\n\njulia> P1s = abstract_projective_space(1, symbol = \"s\")\nAbstractVariety of dim 1\n\njulia> P1t = abstract_projective_space(1, symbol = \"t\")\nAbstractVariety of dim 1\n\njulia> P = P1s*P1t\nAbstractVariety of dim 2\n\njulia> H = hyperplane_class(P)\ns + t\n\njulia> integral(H^dim(P))\n2\n\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/IntersectionTheory/AbstractVarieties/","page":"Abstract Varieties","title":"Abstract Varieties","text":"tautological_bundles(X::AbstractVariety)","category":"page"},{"location":"Experimental/IntersectionTheory/AbstractVarieties/#tautological_bundles-Tuple{AbstractVariety}","page":"Abstract Varieties","title":"tautological_bundles","text":"tautological_bundles(X::AbstractVariety)\n\nReturn the tautological_bundles of X (if applicable).\n\nExamples\n\njulia> P2 = abstract_projective_space(2)\nAbstractVariety of dim 2\n\njulia> TB = tautological_bundles(P2)\n2-element Vector{AbstractBundle}:\n AbstractBundle of rank 1 on AbstractVariety of dim 2\n AbstractBundle of rank 2 on AbstractVariety of dim 2\n\njulia> TB[1] == OO(P2, -1)\ntrue\n\njulia> TB[2] == tangent_bundle(P2)*OO(P2, -1)\ntrue\n\n\njulia> G = abstract_grassmannian(3, 5)\nAbstractVariety of dim 6\n\njulia> tautological_bundles(G)\n2-element Vector{AbstractBundle}:\n AbstractBundle of rank 3 on AbstractVariety of dim 6\n AbstractBundle of rank 2 on AbstractVariety of dim 6\n\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/IntersectionTheory/AbstractVarieties/","page":"Abstract Varieties","title":"Abstract Varieties","text":"structure_map(X::AbstractVariety)","category":"page"},{"location":"Experimental/IntersectionTheory/AbstractVarieties/#structure_map-Tuple{AbstractVariety}","page":"Abstract Varieties","title":"structure_map","text":"structure_map(X::AbstractVariety)\n\nReturn the structure map of X.\n\nExamples\n\njulia> P2 = abstract_projective_space(2)\nAbstractVariety of dim 2\n\njulia> structure_map(P2)\nAbstractVarietyMap from AbstractVariety of dim 2 to AbstractVariety of dim 0\n\njulia> T = tangent_bundle(P2)\nAbstractBundle of rank 2 on AbstractVariety of dim 2\n\njulia> E = abstract_projective_bundle(T, symbol = \"H\")\nAbstractVariety of dim 3\n\njulia> chow_ring(E)\nQuotient\n of multivariate polynomial ring in 2 variables over QQ graded by\n H -> [1]\n h -> [1]\n by ideal (h^3, H^2 + 3*H*h + 3*h^2)\n\njulia> structure_map(E)\nAbstractVarietyMap from AbstractVariety of dim 3 to AbstractVariety of dim 2\n\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/IntersectionTheory/AbstractVarieties/#Further-Data-Associated-to-an-Abstract-Variety","page":"Abstract Varieties","title":"Further Data Associated to an Abstract Variety","text":"","category":"section"},{"location":"Experimental/IntersectionTheory/AbstractVarieties/","page":"Abstract Varieties","title":"Abstract Varieties","text":"trivial_line_bundle(X::AbstractVariety)","category":"page"},{"location":"Experimental/IntersectionTheory/AbstractVarieties/#trivial_line_bundle-Tuple{AbstractVariety}","page":"Abstract Varieties","title":"trivial_line_bundle","text":"trivial_line_bundle(X::AbstractVariety)\n\nReturn the trivial line bundle mathcal O_X on X. Alternatively, use OO instead of trivial_line_bundle.\n\nExamples\n\njulia> P2 = abstract_projective_space(2)\nAbstractVariety of dim 2\n\njulia> OX = trivial_line_bundle(P2)\nAbstractBundle of rank 1 on AbstractVariety of dim 2\n\njulia> chern_character(OX)\n1\n\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/IntersectionTheory/AbstractVarieties/","page":"Abstract Varieties","title":"Abstract Varieties","text":"line_bundle(X::AbstractVariety, n::RingElement)","category":"page"},{"location":"Experimental/IntersectionTheory/AbstractVarieties/#line_bundle-Tuple{AbstractVariety, RingElement}","page":"Abstract Varieties","title":"line_bundle","text":"line_bundle(X::AbstractVariety, n::RingElement)\nline_bundle(X::AbstractVariety, D::MPolyDecRingElem)\n\nReturn the line bundle mathcal O_X(n) on X if X has been given a hyperplane class, or a line bundle mathcal O_X(D) with first Chern class D. Alternatively, use OO instead of line_bundle.\n\nExamples\n\njulia> P2 = abstract_projective_space(2)\nAbstractVariety of dim 2\n\njulia> tautological_bundles(P2)[1] == OO(P2, -1)\ntrue\n\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/IntersectionTheory/AbstractVarieties/","page":"Abstract Varieties","title":"Abstract Varieties","text":"cotangent_bundle(X::AbstractVariety)","category":"page"},{"location":"Experimental/IntersectionTheory/AbstractVarieties/#cotangent_bundle-Tuple{AbstractVariety}","page":"Abstract Varieties","title":"cotangent_bundle","text":"cotangent_bundle(X::AbstractVariety)\n\nReturn the cotangent bundle of X.\n\nExamples\n\njulia> P2 = abstract_projective_space(2)\nAbstractVariety of dim 2\n\njulia> cotangent_bundle(P2) == dual(tangent_bundle(P2)) \ntrue\n\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/IntersectionTheory/AbstractVarieties/","page":"Abstract Varieties","title":"Abstract Varieties","text":"canonical_class(X::AbstractVariety)","category":"page"},{"location":"Experimental/IntersectionTheory/AbstractVarieties/#canonical_class-Tuple{AbstractVariety}","page":"Abstract Varieties","title":"canonical_class","text":"canonical_class(X::AbstractVariety)\n\nReturn the canonical class of X.\n\nExamples\n\njulia> P2 = abstract_projective_space(2)\nAbstractVariety of dim 2\n\njulia> canonical_class(P2) == chern_class(cotangent_bundle(P2), 1)\ntrue\n\njulia> canonical_class(P2) \n-3*h\n\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/IntersectionTheory/AbstractVarieties/","page":"Abstract Varieties","title":"Abstract Varieties","text":"canonical_bundle(X::AbstractVariety)","category":"page"},{"location":"Experimental/IntersectionTheory/AbstractVarieties/#canonical_bundle-Tuple{AbstractVariety}","page":"Abstract Varieties","title":"canonical_bundle","text":"canonical_bundle(X::AbstractVariety)\n\nReturn the canonical bundle of X.\n\njulia> P2 = abstract_projective_space(2)\nAbstractVariety of dim 2\n\njulia> canonical_bundle(P2) == det(cotangent_bundle(P2))\ntrue\n\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/IntersectionTheory/AbstractVarieties/","page":"Abstract Varieties","title":"Abstract Varieties","text":"degree(X::AbstractVariety)","category":"page"},{"location":"Experimental/IntersectionTheory/AbstractVarieties/#degree-Tuple{AbstractVariety}","page":"Abstract Varieties","title":"degree","text":"degree(X::AbstractVariety)\n\nIf X has been given a hyperplane class, return the corresponding degree of X.\n\nExamples\n\njulia> G = abstract_grassmannian(2,5)\nAbstractVariety of dim 6\n\njulia> degree(G)\n5\n\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/IntersectionTheory/AbstractVarieties/","page":"Abstract Varieties","title":"Abstract Varieties","text":"hilbert_polynomial(X::AbstractVariety)","category":"page"},{"location":"Experimental/IntersectionTheory/AbstractVarieties/#hilbert_polynomial-Tuple{AbstractVariety}","page":"Abstract Varieties","title":"hilbert_polynomial","text":"hilbert_polynomial(X::AbstractVariety)\n\nIf X has been given a hyperplane class, return the corresponding Hilbert polynomial of X.\n\nExamples\n\njulia> P2 = abstract_projective_space(2)\nAbstractVariety of dim 2\n\njulia> hilbert_polynomial(P2) == hilbert_polynomial(OO(P2))\ntrue\n\njulia> hilbert_polynomial(P2)\n1//2*t^2 + 3//2*t + 1\n\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/IntersectionTheory/AbstractVarieties/","page":"Abstract Varieties","title":"Abstract Varieties","text":"basis(X::AbstractVariety)","category":"page"},{"location":"Experimental/IntersectionTheory/AbstractVarieties/#basis-Tuple{AbstractVariety}","page":"Abstract Varieties","title":"basis","text":"basis(X::AbstractVariety)\n\nIf K = base(X), return a K-basis of the Chow ring of X.\n\nnote: Note\nThe basis elements are ordered by increasing degree (geometrically, by increasing codimension).\n\nExamples\n\njulia> G = abstract_grassmannian(2,4)\nAbstractVariety of dim 4\n\njulia> chow_ring(G)\nQuotient\n of multivariate polynomial ring in 2 variables over QQ graded by\n c[1] -> [1]\n c[2] -> [2]\n by ideal (-c[1]^3 + 2*c[1]*c[2], c[1]^4 - 3*c[1]^2*c[2] + c[2]^2)\n\njulia> basis(G)\n5-element Vector{Vector{MPolyQuoRingElem}}:\n [1]\n [c[1]]\n [c[2], c[1]^2]\n [c[1]*c[2]]\n [c[2]^2]\n\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/IntersectionTheory/AbstractVarieties/","page":"Abstract Varieties","title":"Abstract Varieties","text":"intersection_matrix(X::AbstractVariety)","category":"page"},{"location":"Experimental/IntersectionTheory/AbstractVarieties/#intersection_matrix-Tuple{AbstractVariety}","page":"Abstract Varieties","title":"intersection_matrix","text":"intersection_matrix(X::AbstractVariety)\n\nIf b = vcat(basis(X)...), return matrix([integral(bi*bj) for bi in b, bj in b]).\n\nintersection_matrix(a::Vector, b::Vector)\n\nReturn matrix([integral(ai*bj) for ai in a, bj in b]).\n\nintersection_matrix(a::Vector)\n\nAs above, with b = a.\n\nExamples\n\njulia> G = abstract_grassmannian(2,4)\nAbstractVariety of dim 4\n\njulia> basis(G)\n5-element Vector{Vector{MPolyQuoRingElem}}:\n [1]\n [c[1]]\n [c[2], c[1]^2]\n [c[1]*c[2]]\n [c[2]^2]\n\njulia> b = vcat(basis(G)...)\n6-element Vector{MPolyQuoRingElem}:\n 1\n c[1]\n c[2]\n c[1]^2\n c[1]*c[2]\n c[2]^2\n\njulia> intersection_matrix(G)\n[0 0 0 0 0 1]\n[0 0 0 0 1 0]\n[0 0 1 1 0 0]\n[0 0 1 2 0 0]\n[0 1 0 0 0 0]\n[1 0 0 0 0 0]\n\njulia> integral(b[4]*b[4])\n2\n\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/IntersectionTheory/AbstractVarieties/","page":"Abstract Varieties","title":"Abstract Varieties","text":"dual_basis(X::AbstractVariety)","category":"page"},{"location":"Experimental/IntersectionTheory/AbstractVarieties/#dual_basis-Tuple{AbstractVariety}","page":"Abstract Varieties","title":"dual_basis","text":"dual_basis(X::AbstractVariety)\n\nIf K = base(X), return a K-basis for the Chow ring of X which is dual to basis(X) with respect to the K-bilinear form defined by intersection_matrix(X).\n\nnote: Note\nThe basis elements are ordered by decreasing degree (geometrically, by decreasing codimension).\n\nExamples\n\njulia> G = abstract_grassmannian(2,4)\nAbstractVariety of dim 4\n\njulia> b = basis(G)\n5-element Vector{Vector{MPolyQuoRingElem}}:\n [1]\n [c[1]]\n [c[2], c[1]^2]\n [c[1]*c[2]]\n [c[2]^2]\n\njulia> intersection_matrix(G)\n[0 0 0 0 0 1]\n[0 0 0 0 1 0]\n[0 0 1 1 0 0]\n[0 0 1 2 0 0]\n[0 1 0 0 0 0]\n[1 0 0 0 0 0]\n\njulia> bd = dual_basis(G)\n5-element Vector{Vector{MPolyQuoRingElem{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}}}:\n [c[2]^2]\n [c[1]*c[2]]\n [-c[1]^2 + 2*c[2], c[1]^2 - c[2]]\n [c[1]]\n [1]\n\njulia> integral(b[3][2]*b[3][2])\n2\n\njulia> integral(b[3][2]*bd[3][2])\n1\n\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/IntersectionTheory/AbstractVarieties/","page":"Abstract Varieties","title":"Abstract Varieties","text":"note: Note\nIf X is of type AbstractVariety, entering total_chern_class(X) returns the total Chern class of the tangent bundle of X. Similarly for entering euler(X), chern_class(X, k), todd_class(X), total_pontryagin_class(X), pontryagin_class(X, k)","category":"page"},{"location":"Experimental/IntersectionTheory/AbstractVarieties/#Operations-on-Abstract-Varieties","page":"Abstract Varieties","title":"Operations on Abstract Varieties","text":"","category":"section"},{"location":"Experimental/IntersectionTheory/AbstractVarieties/","page":"Abstract Varieties","title":"Abstract Varieties","text":"product(X::AbstractVariety, Y::AbstractVariety)","category":"page"},{"location":"Experimental/IntersectionTheory/AbstractVarieties/#product-Tuple{AbstractVariety, AbstractVariety}","page":"Abstract Varieties","title":"product","text":"product(X::AbstractVariety, Y::AbstractVariety)\n\nReturn the product Xtimes Y. Alternatively, use *.\n\nnote: Note\nIf both X and Y have a hyperplane class, Xtimes Y will be endowed with the hyperplane class corresponding to the Segre embedding.\n\njulia> P2 = abstract_projective_space(2);\n\njulia> P3 = abstract_projective_space(3, symbol = \"H\");\n\njulia> P2xP3 = P2*P3\nAbstractVariety of dim 5\n\njulia> chow_ring(P2xP3)\nQuotient\n of multivariate polynomial ring in 2 variables over QQ graded by\n h -> [1]\n H -> [1]\n by ideal (h^3, H^4)\n\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/IntersectionTheory/AbstractVarieties/","page":"Abstract Varieties","title":"Abstract Varieties","text":"note: Note\nBlowups are described in their own section.","category":"page"},{"location":"Experimental/IntersectionTheory/AbstractVarieties/#Integrate-Chow-Ring-Elements","page":"Abstract Varieties","title":"Integrate Chow Ring Elements","text":"","category":"section"},{"location":"Experimental/IntersectionTheory/AbstractVarieties/","page":"Abstract Varieties","title":"Abstract Varieties","text":"integral(x::MPolyDecRingElem)","category":"page"},{"location":"Experimental/IntersectionTheory/AbstractVarieties/","page":"Abstract Varieties","title":"Abstract Varieties","text":"Given an element x of the Chow ring of an abstract variety X, say, return the integral of x.","category":"page"},{"location":"Experimental/IntersectionTheory/AbstractVarieties/","page":"Abstract Varieties","title":"Abstract Varieties","text":"note: Note\nIf X has a (unique) point class, the integral will be a number (that is, a QQFieldElem or a function field element). Otherwise, the highests degree part of x is returned (geometrically, this is the 0-dimensional part of x).","category":"page"},{"location":"Experimental/IntersectionTheory/AbstractVarieties/#Examples","page":"Abstract Varieties","title":"Examples","text":"","category":"section"},{"location":"Experimental/IntersectionTheory/AbstractVarieties/","page":"Abstract Varieties","title":"Abstract Varieties","text":"julia> G = abstract_grassmannian(2, 4)\nAbstractVariety of dim 4\n\njulia> Q = tautological_bundles(G)[2]\nAbstractBundle of rank 2 on AbstractVariety of dim 4\n\njulia> E = symmetric_power(Q, 3)\nAbstractBundle of rank 4 on AbstractVariety of dim 4\n\njulia> integral(top_chern_class(E))\n27\n","category":"page"},{"location":"Hecke/manual/misc/sparse/#Sparse-linear-algebra","page":"Sparse linear algebra","title":"Sparse linear algebra","text":"","category":"section"},{"location":"Hecke/manual/misc/sparse/","page":"Sparse linear algebra","title":"Sparse linear algebra","text":"CurrentModule = Hecke","category":"page"},{"location":"Hecke/manual/misc/sparse/#Introduction","page":"Sparse linear algebra","title":"Introduction","text":"","category":"section"},{"location":"Hecke/manual/misc/sparse/","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/manual/misc/sparse/","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/manual/misc/sparse/#Sparse-rows","page":"Sparse linear algebra","title":"Sparse rows","text":"","category":"section"},{"location":"Hecke/manual/misc/sparse/","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/manual/misc/sparse/","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/manual/misc/sparse/#Creation","page":"Sparse linear algebra","title":"Creation","text":"","category":"section"},{"location":"Hecke/manual/misc/sparse/","page":"Sparse linear algebra","title":"Sparse linear algebra","text":"sparse_row(::NCRing, ::Vector{Tuple{Int, T}}) where T\nsparse_row(::NCRing, ::Vector{Tuple{Int, Int}})\nsparse_row(::NCRing, ::Vector{Int}, ::Vector{T}) where T","category":"page"},{"location":"Hecke/manual/misc/sparse/#sparse_row-Union{Tuple{T}, Tuple{NCRing, Array{Tuple{Int64, T}, 1}}} where T","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/manual/misc/sparse/#sparse_row-Tuple{NCRing, Vector{Tuple{Int64, Int64}}}","page":"Sparse linear algebra","title":"sparse_row","text":"sparse_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/manual/misc/sparse/#sparse_row-Union{Tuple{T}, Tuple{NCRing, Vector{Int64}, Vector{T}}} where T","page":"Sparse linear algebra","title":"sparse_row","text":"sparse_row(R::NCRing, 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/manual/misc/sparse/#Basic-operations","page":"Sparse linear algebra","title":"Basic operations","text":"","category":"section"},{"location":"Hecke/manual/misc/sparse/","page":"Sparse linear algebra","title":"Sparse linear algebra","text":"Rows support the usual operations:","category":"page"},{"location":"Hecke/manual/misc/sparse/","page":"Sparse linear algebra","title":"Sparse linear algebra","text":"+, -, ==\nmultiplication by scalars\ndiv, divexact","category":"page"},{"location":"Hecke/manual/misc/sparse/","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/manual/misc/sparse/#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/manual/misc/sparse/#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/manual/misc/sparse/#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/manual/misc/sparse/#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/manual/misc/sparse/#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/manual/misc/sparse/#Change-of-base-ring","page":"Sparse linear algebra","title":"Change of base ring","text":"","category":"section"},{"location":"Hecke/manual/misc/sparse/","page":"Sparse linear algebra","title":"Sparse linear algebra","text":"change_base_ring(::ZZRing, ::SRow{ZZRingElem})","category":"page"},{"location":"Hecke/manual/misc/sparse/#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/manual/misc/sparse/#Maximum,-minimum-and-2-norm","page":"Sparse linear algebra","title":"Maximum, minimum and 2-norm","text":"","category":"section"},{"location":"Hecke/manual/misc/sparse/","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/manual/misc/sparse/#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/manual/misc/sparse/#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/manual/misc/sparse/#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::RelNumFieldOrderIdeal) -> AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}\n minimum(A::RelNumFieldOrderIdeal) -> RelNumFieldOrderIdeal\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/manual/misc/sparse/#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/manual/misc/sparse/#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/manual/misc/sparse/#Functionality-for-integral-sparse-rows","page":"Sparse linear algebra","title":"Functionality for integral sparse rows","text":"","category":"section"},{"location":"Hecke/manual/misc/sparse/","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/manual/misc/sparse/#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/manual/misc/sparse/#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/manual/misc/sparse/#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/manual/misc/sparse/#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/manual/misc/sparse/#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/manual/misc/sparse/#Conversion-to/from-julia-and-AbstractAlgebra-types","page":"Sparse linear algebra","title":"Conversion to/from julia and AbstractAlgebra types","text":"","category":"section"},{"location":"Hecke/manual/misc/sparse/","page":"Sparse linear algebra","title":"Sparse linear algebra","text":"Vector(r::SRow, n::Int)\nsparse_row(A::MatElem)\ndense_row(r::SRow, n::Int)","category":"page"},{"location":"Hecke/manual/misc/sparse/#Vector-Tuple{SRow, Int64}","page":"Sparse linear algebra","title":"Vector","text":"Vector(a::SMat{T}, n::Int) -> Vector{T}\n\nThe first n entries of a, as a julia vector.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/misc/sparse/#sparse_row-Tuple{MatElem}","page":"Sparse linear algebra","title":"sparse_row","text":"sparse_row(A::MatElem)\n\nConvert A to a sparse row. nrows(A) == 1 must hold.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/misc/sparse/#dense_row-Tuple{SRow, Int64}","page":"Sparse linear algebra","title":"dense_row","text":"dense_row(r::SRow, n::Int)\n\nConvert r[1:n] to a dense row, that is an AbstractAlgebra matrix.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/misc/sparse/#Sparse-matrices","page":"Sparse linear algebra","title":"Sparse matrices","text":"","category":"section"},{"location":"Hecke/manual/misc/sparse/","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/manual/misc/sparse/","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/manual/misc/sparse/#Construction","page":"Sparse linear algebra","title":"Construction","text":"","category":"section"},{"location":"Hecke/manual/misc/sparse/","page":"Sparse linear algebra","title":"Sparse linear algebra","text":"sparse_matrix(::Ring)\nsparse_matrix(::Ring, ::Int, ::Int)","category":"page"},{"location":"Hecke/manual/misc/sparse/#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/manual/misc/sparse/#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/manual/misc/sparse/","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/manual/misc/sparse/","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/manual/misc/sparse/#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/manual/misc/sparse/#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/manual/misc/sparse/#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/manual/misc/sparse/","page":"Sparse linear algebra","title":"Sparse linear algebra","text":"The normal way however, is to add rows:","category":"page"},{"location":"Hecke/manual/misc/sparse/","page":"Sparse linear algebra","title":"Sparse linear algebra","text":"push!(::SMat{T}, ::SRow{T}) where {T}","category":"page"},{"location":"Hecke/manual/misc/sparse/#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/manual/misc/sparse/","page":"Sparse linear algebra","title":"Sparse linear algebra","text":"Sparse matrices can also be concatenated to form larger ones:","category":"page"},{"location":"Hecke/manual/misc/sparse/","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/manual/misc/sparse/#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/manual/misc/sparse/#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/manual/misc/sparse/#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/manual/misc/sparse/#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/manual/misc/sparse/","page":"Sparse linear algebra","title":"Sparse linear algebra","text":"(Normal julia cat is also supported)","category":"page"},{"location":"Hecke/manual/misc/sparse/","page":"Sparse linear algebra","title":"Sparse linear algebra","text":"There are special constructors:","category":"page"},{"location":"Hecke/manual/misc/sparse/","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)\nblock_diagonal_matrix(xs::Vector{<:SMat{T}}) where {T}","category":"page"},{"location":"Hecke/manual/misc/sparse/#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/manual/misc/sparse/#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/manual/misc/sparse/#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/manual/misc/sparse/#block_diagonal_matrix-Union{Tuple{Vector{<:SMat{T}}}, Tuple{T}} where T","page":"Sparse linear algebra","title":"block_diagonal_matrix","text":"block_diagonal_matrix(xs::Vector{SMat})\n\nReturn the block diagonal matrix with the matrices in xs on the diagonal. Requires all blocks to have the same base ring.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/misc/sparse/","page":"Sparse linear algebra","title":"Sparse linear algebra","text":"Slices:","category":"page"},{"location":"Hecke/manual/misc/sparse/","page":"Sparse linear algebra","title":"Sparse linear algebra","text":"sub(::SMat{T}, ::AbstractUnitRange, ::AbstractUnitRange) where {T}","category":"page"},{"location":"Hecke/manual/misc/sparse/#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/manual/misc/sparse/","page":"Sparse linear algebra","title":"Sparse linear algebra","text":"Transpose:","category":"page"},{"location":"Hecke/manual/misc/sparse/","page":"Sparse linear algebra","title":"Sparse linear algebra","text":"transpose(A::SMat)","category":"page"},{"location":"Hecke/manual/misc/sparse/#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/manual/misc/sparse/#Elementary-Properties","page":"Sparse linear algebra","title":"Elementary Properties","text":"","category":"section"},{"location":"Hecke/manual/misc/sparse/","page":"Sparse linear algebra","title":"Sparse linear algebra","text":"sparsity(::SMat)\ndensity(::SMat)\nnnz(::SMat)\nnumber_of_rows(::SMat)\nnumber_of_columns(::SMat)\nisone(::SMat)\niszero(::SMat)\nis_upper_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/manual/misc/sparse/#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/manual/misc/sparse/#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/manual/misc/sparse/#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/manual/misc/sparse/#number_of_rows-Tuple{SMat}","page":"Sparse linear algebra","title":"number_of_rows","text":"number_of_rows(A::SMat) -> Int\n\nReturn the number of rows of A.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/misc/sparse/#number_of_columns-Tuple{SMat}","page":"Sparse linear algebra","title":"number_of_columns","text":"number_of_columns(A::SMat) -> Int\n\nReturn the number of columns of A.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/misc/sparse/#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/manual/misc/sparse/#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/manual/misc/sparse/#is_upper_triangular-Tuple{SMat}","page":"Sparse linear algebra","title":"is_upper_triangular","text":"is_upper_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/manual/misc/sparse/#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/manual/misc/sparse/#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/manual/misc/sparse/#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/manual/misc/sparse/#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/manual/misc/sparse/#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/manual/misc/sparse/#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/manual/misc/sparse/#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/manual/misc/sparse/#reduce_full-Tuple{SMat{ZZRingElem}, SRow{ZZRingElem}}","page":"Sparse linear algebra","title":"reduce_full","text":"reduce_full(A::SMat{ZZRingElem}, g::SRow{ZZRingElem},\n with_transform = 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 with_transform is set to Val(true), then additionally an array of transformations is returned.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/misc/sparse/#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/manual/misc/sparse/#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/manual/misc/sparse/#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/manual/misc/sparse/#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/manual/misc/sparse/#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/manual/misc/sparse/#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/manual/misc/sparse/#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/manual/misc/sparse/#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/manual/misc/sparse/#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 cap 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/manual/misc/sparse/#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/manual/misc/sparse/#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/manual/misc/sparse/#Manipulation/-Access","page":"Sparse linear algebra","title":"Manipulation/ Access","text":"","category":"section"},{"location":"Hecke/manual/misc/sparse/","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/manual/misc/sparse/#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/manual/misc/sparse/#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/manual/misc/sparse/#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/manual/misc/sparse/#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/manual/misc/sparse/#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/manual/misc/sparse/#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/manual/misc/sparse/#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/manual/misc/sparse/#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/manual/misc/sparse/#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/manual/misc/sparse/#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/manual/misc/sparse/#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/manual/misc/sparse/#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/manual/misc/sparse/#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/manual/misc/sparse/#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/manual/misc/sparse/#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/manual/misc/sparse/#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/manual/misc/sparse/#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/manual/misc/sparse/","page":"Sparse linear algebra","title":"Sparse linear algebra","text":"Changing of the ring:","category":"page"},{"location":"Hecke/manual/misc/sparse/","page":"Sparse linear algebra","title":"Sparse linear algebra","text":"map_entries(f, ::SMat)\nchange_base_ring(::Ring, ::SMat)","category":"page"},{"location":"Hecke/manual/misc/sparse/#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/manual/misc/sparse/#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/manual/misc/sparse/#Arithmetic","page":"Sparse linear algebra","title":"Arithmetic","text":"","category":"section"},{"location":"Hecke/manual/misc/sparse/","page":"Sparse linear algebra","title":"Sparse linear algebra","text":"Matrices support the usual operations as well","category":"page"},{"location":"Hecke/manual/misc/sparse/","page":"Sparse linear algebra","title":"Sparse linear algebra","text":"+, -, ==\ndiv, divexact by scalars\nmultiplication by scalars","category":"page"},{"location":"Hecke/manual/misc/sparse/","page":"Sparse linear algebra","title":"Sparse linear algebra","text":"Various products:","category":"page"},{"location":"Hecke/manual/misc/sparse/","page":"Sparse linear algebra","title":"Sparse linear algebra","text":"*(::SMat{T}, ::AbstractVector{T}) where {T}\n*(::SMat{T}, ::AbstractMatrix{T}) where {T}\n*(::SMat{T}, ::MatElem{T}) where {T}\n*(::SRow{T}, ::SMat{T}) where {T}","category":"page"},{"location":"Hecke/manual/misc/sparse/#*-Union{Tuple{T}, Tuple{SMat{T}, AbstractVector{T}}} where T","page":"Sparse linear algebra","title":"*","text":"*(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/manual/misc/sparse/#*-Union{Tuple{T}, Tuple{SMat{T}, AbstractMatrix{T}}} where T","page":"Sparse linear algebra","title":"*","text":"*(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/manual/misc/sparse/#*-Union{Tuple{T}, Tuple{SMat{T}, MatElem{T}}} where T","page":"Sparse linear algebra","title":"*","text":"*(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/manual/misc/sparse/#*-Union{Tuple{T}, Tuple{SRow{T}, SMat{T}}} where T","page":"Sparse linear algebra","title":"*","text":"*(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/manual/misc/sparse/","page":"Sparse linear algebra","title":"Sparse linear algebra","text":"dot(::SRow{T}, ::SMat{T}, ::SRow{T}) where T\ndot(::MatrixElem{T}, ::SMat{T}, ::MatrixElem{T}) where T\ndot(::AbstractVector{T}, ::SMat{T}, ::AbstractVector{T}) where T","category":"page"},{"location":"Hecke/manual/misc/sparse/#dot-Union{Tuple{T}, Tuple{SRow{T}, SMat{T}, SRow{T}}} where T","page":"Sparse linear algebra","title":"dot","text":"dot(x::SRow{T}, A::SMat{T}, y::SRow{T}) where T -> T\n\nReturn the generalized dot product dot(x, A*y).\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/misc/sparse/#dot-Union{Tuple{T}, Tuple{MatrixElem{T}, SMat{T}, MatrixElem{T}}} where T","page":"Sparse linear algebra","title":"dot","text":"dot(x::MatrixElem{T}, A::SMat{T}, y::MatrixElem{T}) where T -> T\n\nReturn the generalized dot product dot(x, A*y).\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/misc/sparse/#dot-Union{Tuple{T}, Tuple{AbstractVector{T}, SMat{T}, AbstractVector{T}}} where T","page":"Sparse linear algebra","title":"dot","text":"dot(x::AbstractVector{T}, A::SMat{T}, y::AbstractVector{T}) where T -> T\n\nReturn the generalized dot product dot(x, A*y).\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/misc/sparse/","page":"Sparse linear algebra","title":"Sparse linear algebra","text":"Other:","category":"page"},{"location":"Hecke/manual/misc/sparse/","page":"Sparse linear algebra","title":"Sparse linear algebra","text":"sparse(::SMat)\nZZMatrix(::SMat{ZZRingElem})\nZZMatrix(::SMat{T}) where {T <: Integer}\nMatrix(::SMat)\nArray(::SMat)","category":"page"},{"location":"Hecke/manual/misc/sparse/#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/manual/misc/sparse/#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/manual/misc/sparse/#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/manual/misc/sparse/#Matrix-Tuple{SMat}","page":"Sparse linear algebra","title":"Matrix","text":"Matrix(A::SMat{T}) -> Matrix{T}\n\nThe same matrix, but as a julia matrix.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/misc/sparse/#Array-Tuple{SMat}","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":"AlgebraicGeometry/Curves/ParametrizationPlaneCurves/","page":"Rational Parametrizations of Rational Plane Curves","title":"Rational Parametrizations of Rational Plane Curves","text":"CurrentModule = Oscar","category":"page"},{"location":"AlgebraicGeometry/Curves/ParametrizationPlaneCurves/#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/ParametrizationPlaneCurves/","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/ParametrizationPlaneCurves/","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/ParametrizationPlaneCurves/","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/ParametrizationPlaneCurves/","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/ParametrizationPlaneCurves/","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/ParametrizationPlaneCurves/","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/ParametrizationPlaneCurves/","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/ParametrizationPlaneCurves/","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/ParametrizationPlaneCurves/","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/ParametrizationPlaneCurves/","page":"Rational Parametrizations of Rational Plane Curves","title":"Rational Parametrizations of Rational Plane Curves","text":"See [Bhm99] and [BDLP17] for details and further references.","category":"page"},{"location":"AlgebraicGeometry/Curves/ParametrizationPlaneCurves/#Adjoint-Ideals-of-Plane-Curves","page":"Rational Parametrizations of Rational Plane Curves","title":"Adjoint Ideals of Plane Curves","text":"","category":"section"},{"location":"AlgebraicGeometry/Curves/ParametrizationPlaneCurves/","page":"Rational Parametrizations of Rational Plane Curves","title":"Rational Parametrizations of Rational Plane Curves","text":"adjoint_ideal(C::ProjectivePlaneCurve{QQField})","category":"page"},{"location":"AlgebraicGeometry/Curves/ParametrizationPlaneCurves/#adjoint_ideal-Tuple{ProjectivePlaneCurve{QQField}}","page":"Rational Parametrizations of Rational Plane Curves","title":"adjoint_ideal","text":"adjoint_ideal(C::ProjectivePlaneCurve{QQField})\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 = ProjectivePlaneCurve(y^4-2*x^3*z+3*x^2*z^2-2*y^2*z^2)\nProjective plane curve\n defined by 0 = 2*x^3*z - 3*x^2*z^2 - y^4 + 2*y^2*z^2\n\njulia> I = adjoint_ideal(C)\nIdeal generated by\n -x*z + y^2\n x*y - y*z\n x^2 - x*z\n\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Curves/ParametrizationPlaneCurves/#Rational-Points-on-Conics","page":"Rational Parametrizations of Rational Plane Curves","title":"Rational Points on Conics","text":"","category":"section"},{"location":"AlgebraicGeometry/Curves/ParametrizationPlaneCurves/","page":"Rational Parametrizations of Rational Plane Curves","title":"Rational Parametrizations of Rational Plane Curves","text":"rational_point_conic(D::ProjectivePlaneCurve{QQField})","category":"page"},{"location":"AlgebraicGeometry/Curves/ParametrizationPlaneCurves/#rational_point_conic-Tuple{ProjectivePlaneCurve{QQField}}","page":"Rational Parametrizations of Rational Plane Curves","title":"rational_point_conic","text":"rational_point_conic(D::ProjectivePlaneCurve{QQField})\n\nIf the plane 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> C = ProjectivePlaneCurve(y^4-2*x^3*z+3*x^2*z^2-2*y^2*z^2)\nProjective plane curve\n defined by 0 = 2*x^3*z - 3*x^2*z^2 - y^4 + 2*y^2*z^2\n\njulia> I = adjoint_ideal(C)\nIdeal generated by\n -x*z + y^2\n x*y - y*z\n x^2 - x*z\n\njulia> R, (x,y,z) = graded_polynomial_ring(QQ, [:x, :y, :z]);\n\njulia> D = ProjectivePlaneCurve(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{AbsSimpleNumFieldElem}}:\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\n","category":"method"},{"location":"AlgebraicGeometry/Curves/ParametrizationPlaneCurves/#Parametrizing-Rational-Plane-Curves","page":"Rational Parametrizations of Rational Plane Curves","title":"Parametrizing Rational Plane Curves","text":"","category":"section"},{"location":"AlgebraicGeometry/Curves/ParametrizationPlaneCurves/","page":"Rational Parametrizations of Rational Plane Curves","title":"Rational Parametrizations of Rational Plane Curves","text":"parametrization(C::ProjectivePlaneCurve{QQField})","category":"page"},{"location":"AlgebraicGeometry/Curves/ParametrizationPlaneCurves/#parametrization-Tuple{ProjectivePlaneCurve{QQField}}","page":"Rational Parametrizations of Rational Plane Curves","title":"parametrization","text":"parametrization(C::ProjectivePlaneCurve{QQField})\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 = ProjectivePlaneCurve(y^4-2*x^3*z+3*x^2*z^2-2*y^2*z^2)\nProjective plane curve\n defined by 0 = 2*x^3*z - 3*x^2*z^2 - y^4 + 2*y^2*z^2\n\njulia> parametrization(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\n","category":"method"},{"location":"AlgebraicGeometry/Curves/ParametrizationPlaneCurves/#Contact","page":"Rational Parametrizations of Rational Plane Curves","title":"Contact","text":"","category":"section"},{"location":"AlgebraicGeometry/Curves/ParametrizationPlaneCurves/","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/ParametrizationPlaneCurves/","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/ParametrizationPlaneCurves/","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/ParametrizationPlaneCurves/","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/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.FracFieldElem{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.FactoredFracFieldElem{T} with parent objects of such fractions having type Generic.FactoredFracField{T}. As opposed to the fractions of type Generic.FracFieldElem{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.FactoredFracFieldElem{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":"Hecke/manual/quad_forms/lattices/#Lattices","page":"Lattices","title":"Lattices","text":"","category":"section"},{"location":"Hecke/manual/quad_forms/lattices/","page":"Lattices","title":"Lattices","text":"CurrentModule = Hecke\nDocTestSetup = quote\n using Hecke\n end","category":"page"},{"location":"Hecke/manual/quad_forms/lattices/#Creation-of-lattices","page":"Lattices","title":"Creation of lattices","text":"","category":"section"},{"location":"Hecke/manual/quad_forms/lattices/#Inside-a-given-ambient-space","page":"Lattices","title":"Inside a given ambient space","text":"","category":"section"},{"location":"Hecke/manual/quad_forms/lattices/","page":"Lattices","title":"Lattices","text":"lattice(::AbstractSpace)\nlattice(::AbstractSpace, ::PMat)\nlattice(::AbstractSpace, ::MatElem)\nlattice(::AbstractSpace, ::Vector)","category":"page"},{"location":"Hecke/manual/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/manual/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/manual/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/manual/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/manual/quad_forms/lattices/#Quadratic-lattice-over-a-number-field","page":"Lattices","title":"Quadratic lattice over a number field","text":"","category":"section"},{"location":"Hecke/manual/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/manual/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/manual/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/manual/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/manual/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/manual/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/manual/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/manual/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/manual/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/manual/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/manual/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/manual/quad_forms/lattices/#Examples","page":"Lattices","title":"Examples","text":"","category":"section"},{"location":"Hecke/manual/quad_forms/lattices/","page":"Lattices","title":"Lattices","text":"The two following examples will be used all along this section:","category":"page"},{"location":"Hecke/manual/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{AbsSimpleNumFieldElem}[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.RelSimpleNumFieldElem{AbsSimpleNumFieldElem}}[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/manual/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/manual/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.RelSimpleNumFieldElem{AbsSimpleNumFieldElem}}[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/manual/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/manual/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/manual/quad_forms/lattices/","page":"Lattices","title":"Lattices","text":"","category":"page"},{"location":"Hecke/manual/quad_forms/lattices/#Ambient-space-and-rational-span","page":"Lattices","title":"Ambient space and rational span","text":"","category":"section"},{"location":"Hecke/manual/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/manual/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/manual/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/manual/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/manual/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/manual/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/manual/quad_forms/lattices/#Examples-2","page":"Lattices","title":"Examples","text":"","category":"section"},{"location":"Hecke/manual/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{AbsSimpleNumFieldElem}[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.RelSimpleNumFieldElem{AbsSimpleNumFieldElem}}[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/manual/quad_forms/lattices/","page":"Lattices","title":"Lattices","text":"","category":"page"},{"location":"Hecke/manual/quad_forms/lattices/#Rational-equivalence","page":"Lattices","title":"Rational equivalence","text":"","category":"section"},{"location":"Hecke/manual/quad_forms/lattices/","page":"Lattices","title":"Lattices","text":"hasse_invariant(L::QuadLat, p)\nwitt_invariant(L::QuadLat, p)\nis_rationally_isometric(::AbstractLat, ::AbstractLat, ::AbsNumFieldOrderIdeal)\nis_rationally_isometric(L::AbstractLat, M::AbstractLat)","category":"page"},{"location":"Hecke/manual/quad_forms/lattices/#hasse_invariant-Tuple{QuadLat, Any}","page":"Lattices","title":"hasse_invariant","text":"hasse_invariant(L::AbstractLat, p::Union{InfPlc, AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}}) -> 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/manual/quad_forms/lattices/#witt_invariant-Tuple{QuadLat, Any}","page":"Lattices","title":"witt_invariant","text":"witt_invariant(L::AbstractLat, p::Union{InfPlc, AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}}) -> 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/manual/quad_forms/lattices/#is_rationally_isometric-Tuple{AbstractLat, AbstractLat, AbsNumFieldOrderIdeal}","page":"Lattices","title":"is_rationally_isometric","text":"is_rationally_isometric(L::AbstractLat, M::AbstractLat, p::Union{InfPlc, AbsNumFieldOrderIdeal})\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/manual/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/manual/quad_forms/lattices/#Examples-3","page":"Lattices","title":"Examples","text":"","category":"section"},{"location":"Hecke/manual/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/manual/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{AbsSimpleNumFieldElem}[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{AbsSimpleNumFieldElem}[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/manual/quad_forms/lattices/","page":"Lattices","title":"Lattices","text":"","category":"page"},{"location":"Hecke/manual/quad_forms/lattices/#Attributes","page":"Lattices","title":"Attributes","text":"","category":"section"},{"location":"Hecke/manual/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/manual/quad_forms/lattices/","page":"Lattices","title":"Lattices","text":" L = bigoplus_i = 1^n mathfrak A_ix_i","category":"page"},{"location":"Hecke/manual/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/manual/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/manual/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/manual/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/manual/quad_forms/lattices/#discriminant-Tuple{AbstractLat}","page":"Lattices","title":"discriminant","text":"discriminant(L::AbstractLat) -> AbsSimpleNumFieldOrderFractionalIdeal\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/manual/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/manual/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/manual/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/manual/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/manual/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/manual/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/manual/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/manual/quad_forms/lattices/#coefficient_ideals-Tuple{AbstractLat}","page":"Lattices","title":"coefficient_ideals","text":"coefficient_ideals(L::AbstractLat) -> Vector{AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}}\n\nReturn the coefficient ideals of a pseudo-basis of the lattice L.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/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/manual/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/manual/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/manual/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/manual/quad_forms/lattices/#Examples-4","page":"Lattices","title":"Examples","text":"","category":"section"},{"location":"Hecke/manual/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.RelSimpleNumFieldElem{AbsSimpleNumFieldElem}}[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/manual/quad_forms/lattices/","page":"Lattices","title":"Lattices","text":"","category":"page"},{"location":"Hecke/manual/quad_forms/lattices/#Module-operations","page":"Lattices","title":"Module operations","text":"","category":"section"},{"location":"Hecke/manual/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/manual/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/manual/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/manual/quad_forms/lattices/","page":"Lattices","title":"Lattices","text":"Base.:(+)(::AbstractLat, ::AbstractLat)\nBase.:(*)(::NumFieldElem, ::AbstractLat)\nBase.:(*)(::NumFieldOrderIdeal, ::AbstractLat)\nBase.:(*)(::NumFieldOrderFractionalIdeal, ::AbstractLat)\nrescale(::AbstractLat, ::NumFieldElem)\ndual(::AbstractLat)\nintersect(::AbstractLat, ::AbstractLat)\nprimitive_closure(::AbstractLat, ::AbstractLat)\northogonal_submodule(::AbstractLat, ::AbstractLat)","category":"page"},{"location":"Hecke/manual/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/manual/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/manual/quad_forms/lattices/#*-Tuple{NumFieldOrderIdeal, AbstractLat}","page":"Lattices","title":"*","text":"*(a::NumFieldOrderIdeal, 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/manual/quad_forms/lattices/#*-Tuple{NumFieldOrderFractionalIdeal, AbstractLat}","page":"Lattices","title":"*","text":"*(a::NumFieldOrderFractionalIdeal, 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/manual/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/manual/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/manual/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/manual/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/manual/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/manual/quad_forms/lattices/#Examples-5","page":"Lattices","title":"Examples","text":"","category":"section"},{"location":"Hecke/manual/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{AbsSimpleNumFieldElem}[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{AbsSimpleNumFieldElem}[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/manual/quad_forms/lattices/#Categorical-constructions","page":"Lattices","title":"Categorical constructions","text":"","category":"section"},{"location":"Hecke/manual/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/manual/quad_forms/lattices/","page":"Lattices","title":"Lattices","text":"direct_sum(::Vector{AbstractLat})\ndirect_product(::Vector{AbstractLat})\nbiproduct(::Vector{AbstractLat})","category":"page"},{"location":"Hecke/manual/quad_forms/lattices/#direct_sum-Tuple{Vector{AbstractLat}}","page":"Lattices","title":"direct_sum","text":"direct_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\ndirect_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":"Hecke/manual/quad_forms/lattices/#direct_product-Tuple{Vector{AbstractLat}}","page":"Lattices","title":"direct_product","text":"direct_product(algebras::StructureConstantAlgebra...; task::Symbol = :sum)\n -> StructureConstantAlgebra, Vector{AbsAlgAssMor}, Vector{AbsAlgAssMor}\ndirect_product(algebras::Vector{StructureConstantAlgebra}; task::Symbol = :sum)\n -> StructureConstantAlgebra, 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\ndirect_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\n","category":"method"},{"location":"Hecke/manual/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/manual/quad_forms/lattices/","page":"Lattices","title":"Lattices","text":"","category":"page"},{"location":"Hecke/manual/quad_forms/lattices/#Invariants","page":"Lattices","title":"Invariants","text":"","category":"section"},{"location":"Hecke/manual/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/manual/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/manual/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/manual/quad_forms/lattices/","page":"Lattices","title":"Lattices","text":"norm(::AbstractLat)\nscale(L::AbstractLat)\nvolume(L::AbstractLat)","category":"page"},{"location":"Hecke/manual/quad_forms/lattices/#norm-Tuple{AbstractLat}","page":"Lattices","title":"norm","text":"norm(L::AbstractLat) -> AbsNumFieldOrderFractionalIdeal\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/manual/quad_forms/lattices/#scale-Tuple{AbstractLat}","page":"Lattices","title":"scale","text":"scale(L::AbstractLat) -> AbsSimpleNumFieldOrderFractionalIdeal\n\nReturn the scale of the lattice L.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/quad_forms/lattices/#volume-Tuple{AbstractLat}","page":"Lattices","title":"volume","text":"volume(L::AbstractLat) -> AbsSimpleNumFieldOrderFractionalIdeal\n\nReturn the volume of the lattice L.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/quad_forms/lattices/#Examples-6","page":"Lattices","title":"Examples","text":"","category":"section"},{"location":"Hecke/manual/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.RelSimpleNumFieldElem{AbsSimpleNumFieldElem}}[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/manual/quad_forms/lattices/","page":"Lattices","title":"Lattices","text":"","category":"page"},{"location":"Hecke/manual/quad_forms/lattices/#Predicates","page":"Lattices","title":"Predicates","text":"","category":"section"},{"location":"Hecke/manual/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/manual/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/manual/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/manual/quad_forms/lattices/#is_modular-Tuple{AbstractLat}","page":"Lattices","title":"is_modular","text":"is_modular(L::AbstractLat) -> Bool, AbsSimpleNumFieldOrderFractionalIdeal\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/manual/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/manual/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/manual/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/manual/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/manual/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/manual/quad_forms/lattices/#Examples-7","page":"Lattices","title":"Examples","text":"","category":"section"},{"location":"Hecke/manual/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.RelSimpleNumFieldElem{AbsSimpleNumFieldElem}}[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/manual/quad_forms/lattices/","page":"Lattices","title":"Lattices","text":"","category":"page"},{"location":"Hecke/manual/quad_forms/lattices/#Local-properties","page":"Lattices","title":"Local properties","text":"","category":"section"},{"location":"Hecke/manual/quad_forms/lattices/","page":"Lattices","title":"Lattices","text":"local_basis_matrix(L::AbstractLat, p; type::Symbol = :any)\njordan_decomposition(L::AbstractLat, p::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem})\nis_isotropic(::AbstractLat, p)","category":"page"},{"location":"Hecke/manual/quad_forms/lattices/#local_basis_matrix-Tuple{AbstractLat, Any}","page":"Lattices","title":"local_basis_matrix","text":"local_basis_matrix(L::AbstractLat, p::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}; 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/manual/quad_forms/lattices/#jordan_decomposition-Tuple{AbstractLat, AbsSimpleNumFieldOrderIdeal}","page":"Lattices","title":"jordan_decomposition","text":"jordan_decomposition(L::AbstractLat, p::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem})\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/manual/quad_forms/lattices/#is_isotropic-Tuple{AbstractLat, Any}","page":"Lattices","title":"is_isotropic","text":"is_isotropic(L::AbstractLat, p::Union{AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}, 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/manual/quad_forms/lattices/#Examples-8","page":"Lattices","title":"Examples","text":"","category":"section"},{"location":"Hecke/manual/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{AbsSimpleNumFieldElem}[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/manual/quad_forms/lattices/","page":"Lattices","title":"Lattices","text":"","category":"page"},{"location":"Hecke/manual/quad_forms/lattices/#Automorphisms-for-definite-lattices","page":"Lattices","title":"Automorphisms for definite lattices","text":"","category":"section"},{"location":"Hecke/manual/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/manual/quad_forms/lattices/","page":"Lattices","title":"Lattices","text":" Phi(f(x) f(y)) = Phi(xy)","category":"page"},{"location":"Hecke/manual/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/manual/quad_forms/lattices/","page":"Lattices","title":"Lattices","text":"automorphism_group_order(::AbstractLat)\nautomorphism_group_generators(::AbstractLat)","category":"page"},{"location":"Hecke/manual/quad_forms/lattices/#automorphism_group_order-Tuple{AbstractLat}","page":"Lattices","title":"automorphism_group_order","text":"automorphism_group_order(L::AbstractLat; depth::Int = -1, bacher_depth::Int = 0) -> Int\n\nGiven a definite lattice L, return the order of the automorphism group of L.\n\nSetting the parameters depth and bacher_depth to a positive value may improve performance. If set to -1 (default), the used value of depth is chosen heuristically depending on the rank of L. By default, bacher_depth is set to 0.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/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 depth::Int = -1, bacher_depth::Int = 0)\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\nSetting the parameters depth and bacher_depth to a positive value may improve performance. If set to -1 (default), the used value of depth is chosen heuristically depending on the rank of L. By default, bacher_depth is set to 0.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/quad_forms/lattices/#Examples-9","page":"Lattices","title":"Examples","text":"","category":"section"},{"location":"Hecke/manual/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{AbsSimpleNumFieldElem}[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/manual/quad_forms/lattices/","page":"Lattices","title":"Lattices","text":"","category":"page"},{"location":"Hecke/manual/quad_forms/lattices/#Isometry","page":"Lattices","title":"Isometry","text":"","category":"section"},{"location":"Hecke/manual/quad_forms/lattices/","page":"Lattices","title":"Lattices","text":"is_isometric(::AbstractLat, ::AbstractLat)\nis_isometric_with_isometry(::AbstractLat, ::AbstractLat)\nis_locally_isometric(::AbstractLat, ::AbstractLat, p::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem})","category":"page"},{"location":"Hecke/manual/quad_forms/lattices/#is_isometric-Tuple{AbstractLat, AbstractLat}","page":"Lattices","title":"is_isometric","text":"is_isometric(L::AbstractLat, M::AbstractLat; depth::Int = -1, bacher_depth::Int = 0) -> Bool\n\nReturn whether the lattices L and M are isometric.\n\nSetting the parameters depth and bacher_depth to a positive value may improve performance. If set to -1 (default), the used value of depth is chosen heuristically depending on the rank of L. By default, bacher_depth is set to 0.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/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 depth::Int = -1, bacher_depth::Int = 0)\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\nSetting the parameters depth and bacher_depth to a positive value may improve performance. If set to -1 (default), the used value of depth is chosen heuristically depending on the rank of L. By default, bacher_depth is set to 0.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/quad_forms/lattices/#is_locally_isometric-Tuple{AbstractLat, AbstractLat, AbsSimpleNumFieldOrderIdeal}","page":"Lattices","title":"is_locally_isometric","text":"is_locally_isometric(L::AbstractLat, M::AbstractLat, p::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}) -> 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/manual/quad_forms/lattices/#Examples-10","page":"Lattices","title":"Examples","text":"","category":"section"},{"location":"Hecke/manual/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{AbsSimpleNumFieldElem}[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{AbsSimpleNumFieldElem}[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/manual/quad_forms/lattices/","page":"Lattices","title":"Lattices","text":"","category":"page"},{"location":"Hecke/manual/quad_forms/lattices/#Maximal-integral-lattices","page":"Lattices","title":"Maximal integral lattices","text":"","category":"section"},{"location":"Hecke/manual/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/manual/quad_forms/lattices/#is_maximal_integral-Tuple{AbstractLat, Any}","page":"Lattices","title":"is_maximal_integral","text":"is_maximal_integral(L::AbstractLat, p::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}) -> 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 has integral norm and that L has no proper overlattice satisfying this property.\n\nIf the norm of L is not integral at p, the second output is L by default. Otherwise, either L is maximal at p and the second output is L, or the second output is a lattice M in the ambient space of L whose completion at p is a minimal overlattice of L_p with integral norm.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/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 has integral norm and has no proper overlattice satisfying this property.\n\nIf the norm of L is not integral, the second output is L by default. Otherwise, either L is maximal and the second output is L, or the second output is a minimal overlattice M of L with integral norm.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/quad_forms/lattices/#is_maximal-Tuple{AbstractLat, Any}","page":"Lattices","title":"is_maximal","text":"is_maximal(L::AbstractLat, p::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}) -> Bool, AbstractLat\n\nGiven a lattice L and a prime ideal p in the fixed ring mathcal O_K of L such that the norm of L_p is integral, return whether L is maximal integral at p.\n\nIf L is locally maximal at p, the second output is L, otherwise it is a lattice M 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/manual/quad_forms/lattices/#maximal_integral_lattice-Tuple{AbstractLat, Any}","page":"Lattices","title":"maximal_integral_lattice","text":"maximal_integral_lattice(L::AbstractLat, p::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}) -> AbstractLat\n\nGiven a lattice L and a prime ideal p of the fixed ring mathcal O_K of L such that the norm of L_p is integral, 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/manual/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 with integral norm, return a maximal integral overlattice M of L.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/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/manual/quad_forms/lattices/#Examples-11","page":"Lattices","title":"Examples","text":"","category":"section"},{"location":"Hecke/manual/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.RelSimpleNumFieldElem{AbsSimpleNumFieldElem}}[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":"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 = Oscar.doctestsetup()","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 [AL94] 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 generated by\n 3*x^2*y + 7*y\n 4*x*y^2 - 5*x\n\njulia> G = groebner_basis(I, ordering = lex(R))\nGröbner basis with elements\n 1 -> 28*y^3 - 35*y\n 2 -> 4*x*y^2 - 5*x\n 3 -> 15*x^2 + 28*y^2\n 4 -> 3*x^2*y + 7*y\n 5 -> x^2*y^2 - 5*x^2 - 7*y^2\nwith respect to the ordering\n lex([x, y])","category":"page"},{"location":"AlgebraicGeometry/Surfaces/AdjunctionProcess/","page":"Adjunction Process for Surfaces","title":"Adjunction Process for Surfaces","text":"CurrentModule = Oscar","category":"page"},{"location":"AlgebraicGeometry/Surfaces/AdjunctionProcess/#Adjunction-Process-for-Surfaces","page":"Adjunction Process for Surfaces","title":"Adjunction Process for Surfaces","text":"","category":"section"},{"location":"AlgebraicGeometry/Surfaces/AdjunctionProcess/","page":"Adjunction Process for Surfaces","title":"Adjunction Process for Surfaces","text":"A surface in this section is a smooth projective surface over mathbb C.","category":"page"},{"location":"AlgebraicGeometry/Surfaces/AdjunctionProcess/","page":"Adjunction Process for Surfaces","title":"Adjunction Process for Surfaces","text":"Blowing up a surface in a point means to replace the point by an exceptional curve. Each such curve E is a smooth, rational curve with self-intersection number E^2=-1. We speak of a (-1)-curve. A surface is minimal if it contains no (-1)-curves. That is, the surface cannot be obtained by blowing up a point on another surface. A surface X_textmin is called a minimal model of a surface X if X_textmin is minimal and X can be obtained from X_textmin by repeatedly blowing up a point. Each surface X has a minimal model which is unique if X has non-negative Kodaira dimension. The Enriques-Kodaira classification classifies surfaces according to their minimal models. See [BHPV-D-V04] for more on this.","category":"page"},{"location":"AlgebraicGeometry/Surfaces/AdjunctionProcess/","page":"Adjunction Process for Surfaces","title":"Adjunction Process for Surfaces","text":"Given a surface, we may apply the adjunction process of Van de Ven and Sommese [SV-D-V87] to discover a minimal model. To describe this process, consider a surface X subset mathbb P^n of codimension c. Let S and S_X denote the homogeneous coordinate rings of mathbb P^n and X, respectively. Consider omega_X=textExt^c_S(S_XS(-n-1)) the graded dualizing module of S_X. A basis of the graded piece (omega_X)_1 corresponds to the linear system K_X +H, where K_X is a canonical divisor on X and H is the hyperplane class. Except for some exceptional cases, this linear system defines a birational morphism varphi_K_X+Hcolon X to X onto another smooth projective surface X such that varphi_K_X+H blows down precisely all (-1)-lines on X. As shown by Van de Ven and Sommese, in the exceptional cases,","category":"page"},{"location":"AlgebraicGeometry/Surfaces/AdjunctionProcess/","page":"Adjunction Process for Surfaces","title":"Adjunction Process for Surfaces","text":"X is a linearly or quadratically embedded $ \\mathbb P^{2}$ or X is ruled by lines, in which case K_X+H = emptyset,\nX is an anti-canonically embedded del Pezzo surface, in which case varphi_K_X+H maps X to a point,\nX is a conic bundle, in which case varphi_K_X+Hcolon X to B maps X to a curve B such that the fibers of varphi_K_X+H are the conics, or\nX is a surface in one of four explicit families identified by Sommese and Van de Ven, and varphi_K_X+Hcolon X to X is not birational, but finite to one.","category":"page"},{"location":"AlgebraicGeometry/Surfaces/AdjunctionProcess/","page":"Adjunction Process for Surfaces","title":"Adjunction Process for Surfaces","text":"If we are not in one of these cases, a (-1)-conic C in X is mapped to a (-1)-line in X since (K_X+H) C=-1+2=1. Thus, the adjunction process, which consists of applying the adjunction maps varphi_K_X+H, varphi_K_X+H and so on, yields finitely many surfaces X rightarrow X^prime rightarrow X^primeprime rightarrow dots which are called the adjoint surfaces of X. The last adjoint surface is either minimal or belongs to one of the exceptional cases. In particular, if X has non-negative Kodaira dimension, the adjunction process yields the uniquely determined minimal model of X.","category":"page"},{"location":"AlgebraicGeometry/Surfaces/AdjunctionProcess/","page":"Adjunction Process for Surfaces","title":"Adjunction Process for Surfaces","text":"note: Note\nIf X is rational, the last adjoint surface is either mathbb P^2, the Veronese surface, a Hirzebruch surface, a Del Pezzo surface, a conic bundle, or one of the four explicit families identified by Sommese and Van de Ven.","category":"page"},{"location":"AlgebraicGeometry/Surfaces/AdjunctionProcess/","page":"Adjunction Process for Surfaces","title":"Adjunction Process for Surfaces","text":"note: Note\nIn explicit computations, we consider surfaces which are defined by polynomial equations with coefficients in a subfield of mathbb C which can be handled by OSCAR.","category":"page"},{"location":"AlgebraicGeometry/Surfaces/AdjunctionProcess/","page":"Adjunction Process for Surfaces","title":"Adjunction Process for Surfaces","text":"note: Note\nThe surfaces in the examples below are taken from the OSCAR data base of nongeneral type surfaces in mathbb P^4. To ease subsequent computations, the surfaces in the data base where constructed over finite fields. Note, however, that the recipes used in the constructions also work in characteristic zero. So all computations can be confirmed in characteristic zero, although this may be time consuming.","category":"page"},{"location":"AlgebraicGeometry/Surfaces/AdjunctionProcess/#Adjunction-Process","page":"Adjunction Process for Surfaces","title":"Adjunction Process","text":"","category":"section"},{"location":"AlgebraicGeometry/Surfaces/AdjunctionProcess/","page":"Adjunction Process for Surfaces","title":"Adjunction Process for Surfaces","text":"What we describe here goes back to joint work of Wolfram Decker and Frank-Olaf Schreyer. See [DES93], [DS00].","category":"page"},{"location":"AlgebraicGeometry/Surfaces/AdjunctionProcess/","page":"Adjunction Process for Surfaces","title":"Adjunction Process for Surfaces","text":"adjunction_process(X::AbsProjectiveVariety, steps::Int=0)","category":"page"},{"location":"AlgebraicGeometry/Surfaces/AdjunctionProcess/#adjunction_process","page":"Adjunction Process for Surfaces","title":"adjunction_process","text":"adjunction_process(X::AbsProjectiveVariety, steps::Int=0)\n\nGiven a smooth surface X and a non-negative integer steps, return data which describes the adjunction process for X: If steps == 0, carry out the complete process. Otherwise, carry out the indicated number of steps only.\n\nMore precisely, if X^(0) = X rightarrow X^(1)rightarrow dots rightarrow X^(r) is the sequence of successive adjunction maps and adjoint surfaces in the completed adjunction process, return a quadruple L, say, where: \n\nL[1] is a vector of tuples of numerical data: For each step X^(i)rightarrow X^(i+1), return the tuple (n^(i) d^(i) pi^(i) s^(i)) where n^(i) is the dimension of the ambient projective space of X^(i), d^(i) is the degree of X^(i), pi^(i) is the sectional genus of X^(i), and s^(i) is the number of exceptional (-1)-lines on X^(i) which are blown down to points in $ X^{(i+1)}$.\n\nL[2] is a vector of adjoint matrices: For each step X^(i)rightarrow X^(i+1), return a presentation matrix of S_X^(i)(1) considered as a module over S_X^(i+1), where the S_X^(i) are the homogeneous coordinate rings of the X^(i). If X is rational, these matrices can be used to compute a rational parametrization of X.\n\nL[3] is a vector of zero-dimensional projective algebraic sets: For each step X^(i)rightarrow X^(i+1), return the union of points in $ X^{(i+1)}$ which are obtained by blowing down the exceptional (-1)-lines on X^(i).\n\nL[4] is a projective variety: Return the last adjoint surface X^(r). \n\nnote: Note\nThe function does not check whether X is smooth. If you are uncertain, enter is_smooth(X) first.\n\nwarning: Warning\nAt current state, the adjunction process is only implemented for rational and Enriques surfaces which are linearly normal in the given embedding. The function does not check whether X is rational or an Enriques surface. In fact, at current state, OSCAR does not offer direct checks for this. Note, however, that the adjunction process will give an answer to this question a posteriori in cases where it terminates with a surface which is known to be rational or an Enriques surface.\n\nExamples\n\njulia> X = bordiga()\nProjective variety\n in projective 4-space over GF(31991) with coordinates [x, y, z, u, v]\ndefined by ideal with 4 generators\n\n\njulia> dim(X)\n2\n\njulia> codim(X)\n2\n\njulia> L = adjunction_process(X);\n\njulia> L[1]\n2-element Vector{NTuple{4, ZZRingElem}}:\n (4, 6, 3, 0)\n (2, 1, 0, 10)\n\njulia> L[4]\nProjective variety\n in projective 2-space over GF(31991) with coordinates [z[1], z[2], z[3]]\ndefined by ideal (0)\n\njulia> L[3][1]\nProjective algebraic set\n in projective 2-space over GF(31991) with coordinates [z[1], z[2], z[3]]\ndefined by ideal with 5 generators\n\njulia> dim(L[3][1])\n0\n\njulia> degree(L[3][1])\n10\n\njulia> X = rational_d9_pi7();\n\njulia> L = adjunction_process(X);\n\njulia> L[1]\n3-element Vector{NTuple{4, ZZRingElem}}:\n (4, 9, 7, 0)\n (6, 9, 4, 6)\n (3, 3, 1, 3)\n\nnote: Note\nInspecting the returned numerical data in the first example above, we see that the Bordiga surface is the blow-up of the projective plane in 10 points, embedded into projective 4-space by the linear system H = 4L -sum_i=1^10 E_i. Here, L is the preimage of a line and the E_i are the exceptional divisors. In the second example, we see from the output that the terminal object of the adjunction process is a Del Pezzo surface in projective 3-space, that is, the blow-up of the projective plane in 6 points. In sum, we see that X is the blow-up of the projective plane in 15 points, embedded into projective 4-space by the linear system H = 9L - sum_i=1^6 3E_i - sum_i=7^9 2E_i - sum_i=10^15 E_i. \n\n\n\n\n\n","category":"function"},{"location":"AlgebraicGeometry/Surfaces/AdjunctionProcess/#Contact","page":"Adjunction Process for Surfaces","title":"Contact","text":"","category":"section"},{"location":"AlgebraicGeometry/Surfaces/AdjunctionProcess/","page":"Adjunction Process for Surfaces","title":"Adjunction Process for Surfaces","text":"Please direct questions about this part of OSCAR to the following people:","category":"page"},{"location":"AlgebraicGeometry/Surfaces/AdjunctionProcess/","page":"Adjunction Process for Surfaces","title":"Adjunction Process for Surfaces","text":"Wolfram Decker.","category":"page"},{"location":"AlgebraicGeometry/Surfaces/AdjunctionProcess/","page":"Adjunction Process for Surfaces","title":"Adjunction Process for Surfaces","text":"You can ask questions in the OSCAR Slack.","category":"page"},{"location":"AlgebraicGeometry/Surfaces/AdjunctionProcess/","page":"Adjunction Process for Surfaces","title":"Adjunction Process for Surfaces","text":"Alternatively, you can raise an issue on github.","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{<:MPolyDecRingElem}; check::Bool=true, is_radical::Bool=false) -> 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^3 + s1^3 + s2^3 + s3^3, s0)\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":"In addition to what is inherited from Projective Algebraic Sets and Projective schemes, we currently have:","category":"page"},{"location":"AlgebraicGeometry/AlgebraicVarieties/ProjectiveVariety/","page":"Projective Varieties","title":"Projective Varieties","text":"sectional_genus(X::AbsProjectiveVariety)","category":"page"},{"location":"AlgebraicGeometry/AlgebraicVarieties/ProjectiveVariety/#sectional_genus-Tuple{AbsProjectiveVariety}","page":"Projective Varieties","title":"sectional_genus","text":"sectional_genus(X::AbsProjectiveVariety)\n\nGiven a subvariety X of some mathbb P^n, return the arithmetic genus of the intersection of X with a general linear subspace of mathbb P^n of dimension c+1.\n\nExamples\n\njulia> X = bordiga()\nProjective variety\n in projective 4-space over GF(31991) with coordinates [x, y, z, u, v]\ndefined by ideal with 4 generators\n\njulia> dim(X)\n2\n\njulia> codim(X)\n2\n\njulia> degree(X)\n6\n\njulia> sectional_genus(X)\n3\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/AlgebraicVarieties/ProjectiveVariety/#Properties","page":"Projective Varieties","title":"Properties","text":"","category":"section"},{"location":"AlgebraicGeometry/AlgebraicVarieties/ProjectiveVariety/","page":"Projective Varieties","title":"Projective Varieties","text":"In addition to what is inherited from Projective Algebraic Sets and Projective schemes, we currently have:","category":"page"},{"location":"AlgebraicGeometry/AlgebraicVarieties/ProjectiveVariety/","page":"Projective Varieties","title":"Projective Varieties","text":"is_linearly_normal(X::AbsProjectiveVariety)","category":"page"},{"location":"AlgebraicGeometry/AlgebraicVarieties/ProjectiveVariety/#is_linearly_normal-Tuple{AbsProjectiveVariety}","page":"Projective Varieties","title":"is_linearly_normal","text":"is_linearly_normal(X::AbsProjectiveVariety)\n\nReturn true if X is linearly normal, and false otherwise.\n\nExamples\n\njulia> X = bordiga()\nProjective variety\n in projective 4-space over GF(31991) with coordinates [x, y, z, u, v]\ndefined by ideal with 4 generators\n\njulia> dim(X)\n2\n\njulia> codim(X)\n2\n\njulia> is_linearly_normal(X)\ntrue\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/AlgebraicVarieties/ProjectiveVariety/#Methods","page":"Projective Varieties","title":"Methods","text":"","category":"section"},{"location":"AlgebraicGeometry/AlgebraicVarieties/ProjectiveVariety/","page":"Projective Varieties","title":"Projective Varieties","text":"In addition to what is inherited from Projective Algebraic Sets and Projective schemes, we currently have:","category":"page"},{"location":"AlgebraicGeometry/AlgebraicVarieties/ProjectiveVariety/","page":"Projective Varieties","title":"Projective Varieties","text":"canonical_bundle(X::AbsProjectiveVariety)","category":"page"},{"location":"AlgebraicGeometry/AlgebraicVarieties/ProjectiveVariety/#canonical_bundle-Tuple{AbsProjectiveVariety}","page":"Projective Varieties","title":"canonical_bundle","text":"canonical_bundle(X::AbsProjectiveVariety)\n\nGiven a smooth projective variety X, return a module whose sheafification is the canonical bundle of X.\n\nnote: Note\nThe function does not check smoothness. If you are uncertain, enter is_smooth(X) first.\n\nExamples\n\njulia> R, x = graded_polynomial_ring(QQ, :x => (1:6));\n\njulia> I = ideal(R, [x[1]*x[6] - x[2]*x[5] + x[3]*x[4]]);\n\njulia> GRASSMANNIAN = variety(I); \n\njulia> Omega = canonical_bundle(GRASSMANNIAN)\nGraded subquotient of submodule of R^1 generated by\n1 -> e[1]\nby submodule of R^1 generated by\n1 -> (x[1]*x[6] - x[2]*x[5] + x[3]*x[4])*e[1]\n\njulia> degrees_of_generators(Omega)\n1-element Vector{FinGenAbGroupElem}:\n [4]\n\njulia> R, (x, y, z) = graded_polynomial_ring(QQ,[:x, :y, :z]);\n\njulia> I = ideal(R, [y^2*z + x*y*z - x^3 - x*z^2 - z^3]);\n\njulia> ELLCurve = variety(I);\n\njulia> Omega = canonical_bundle(ELLCurve)\nGraded subquotient of submodule of R^1 generated by\n1 -> e[1]\nby submodule of R^1 generated by\n1 -> (x^3 - x*y*z + x*z^2 - y^2*z + z^3)*e[1]\n\njulia> degrees_of_generators(Omega)\n1-element Vector{FinGenAbGroupElem}:\n [0]\n\njulia> X = bordiga()\nProjective variety\n in projective 4-space over GF(31991) with coordinates [x, y, z, u, v]\ndefined by ideal with 4 generators\n\njulia> dim(X)\n2\n\njulia> codim(X)\n2\n\njulia> Omega = canonical_bundle(X);\n\njulia> typeof(Omega)\nSubquoModule{MPolyDecRingElem{fpFieldElem, fpMPolyRingElem}}\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/number_fields/elements/","page":"Element operations","title":"Element operations","text":"CurrentModule = Hecke\nDocTestSetup = quote\n using Hecke\n end","category":"page"},{"location":"Hecke/manual/number_fields/elements/#Element-operations","page":"Element operations","title":"Element operations","text":"","category":"section"},{"location":"Hecke/manual/number_fields/elements/#Creation","page":"Element operations","title":"Creation","text":"","category":"section"},{"location":"Hecke/manual/number_fields/elements/","page":"Element operations","title":"Element operations","text":"gen(::SimpleNumField)\ngens(::NonSimpleNumField)","category":"page"},{"location":"Hecke/manual/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\n\n","category":"method"},{"location":"Hecke/manual/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\n\n","category":"method"},{"location":"Hecke/manual/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/manual/number_fields/elements/","page":"Element operations","title":"Element operations","text":" (L::number_field)(c::Vector{NumFieldElem}) -> NumFieldElem","category":"page"},{"location":"Hecke/manual/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/manual/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/manual/number_fields/elements/","page":"Element operations","title":"Element operations","text":"quadratic_defect(a::NumFieldElem, p)\nhilbert_symbol(a::AbsSimpleNumFieldElem, b::AbsSimpleNumFieldElem, p::Union{AbsNumFieldOrderIdeal, RelNumFieldOrderIdeal})\nrepresentation_matrix(::NumFieldElem)\nbasis_matrix(::Vector{AbsSimpleNumFieldElem})\ncoefficients(::SimpleNumFieldElem)\ncoordinates(::NumFieldElem)\nabsolute_coordinates(::NumFieldElem)\ncoeff(::SimpleNumFieldElem, ::Int)\nvaluation(::NumFieldElem, ::Any)\ntorsion_unit_order(::AbsSimpleNumFieldElem, ::Int)\ntr(::NumFieldElem)\nabsolute_tr(::NumFieldElem)\nalgebraic_split(::AbsSimpleNumFieldElem)","category":"page"},{"location":"Hecke/manual/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\n\n","category":"method"},{"location":"Hecke/manual/number_fields/elements/#hilbert_symbol-Tuple{AbsSimpleNumFieldElem, AbsSimpleNumFieldElem, Union{AbsNumFieldOrderIdeal, Hecke.RelNumFieldOrderIdeal}}","page":"Element operations","title":"hilbert_symbol","text":"hilbert_symbol(a::NumFieldElem, b::NumFieldElem, p::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}) -> Int\n\nReturns the local Hilbert symbol (ab)_p.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/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\n\n","category":"method"},{"location":"Hecke/manual/number_fields/elements/#basis_matrix-Tuple{Vector{AbsSimpleNumFieldElem}}","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\n\n","category":"method"},{"location":"Hecke/manual/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\n\n","category":"method"},{"location":"Hecke/manual/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\n\n","category":"method"},{"location":"Hecke/manual/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\n\n","category":"method"},{"location":"Hecke/manual/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\n\n","category":"method"},{"location":"Hecke/manual/number_fields/elements/#valuation-Tuple{NumFieldElem, Any}","page":"Element operations","title":"valuation","text":"valuation(a::NumFieldElem, p::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}) -> 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/manual/number_fields/elements/#torsion_unit_order-Tuple{AbsSimpleNumFieldElem, Int64}","page":"Element operations","title":"torsion_unit_order","text":"torsion_unit_order(x::AbsSimpleNumFieldElem, 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/manual/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\n\n","category":"method"},{"location":"Hecke/manual/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\n\n","category":"method"},{"location":"Hecke/manual/number_fields/elements/#algebraic_split-Tuple{AbsSimpleNumFieldElem}","page":"Element operations","title":"algebraic_split","text":"algebraic_split(a::AbsSimpleNumFieldElem) -> AbsSimpleNumFieldElem, AbsSimpleNumFieldElem\n\nWrites the input as a quotient of two \"small\" algebraic integers.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/number_fields/elements/#Conjugates","page":"Element operations","title":"Conjugates","text":"","category":"section"},{"location":"Hecke/manual/number_fields/elements/","page":"Element operations","title":"Element operations","text":"conjugates(::NumFieldElem, ::AcbField)\nconjugates(::NumFieldElem)\nconjugates_log(::AbsSimpleNumFieldElem, ::Int)\nconjugates_real(::AbsSimpleNumFieldElem)\nconjugates_complex(::AbsSimpleNumFieldElem)\nconjugates_arb_log_normalise(::AbsSimpleNumFieldElem)\nminkowski_map(::AbsSimpleNumFieldElem)","category":"page"},{"location":"Hecke/manual/number_fields/elements/#conjugates-Tuple{NumFieldElem, AcbField}","page":"Element operations","title":"conjugates","text":"conjugates(x::AbsSimpleNumFieldElem, C::AcbField) -> Vector{AcbFieldElem}\n\nCompute the conjugates of x as elements of type AcbFieldElem. 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/manual/number_fields/elements/#conjugates-Tuple{NumFieldElem}","page":"Element operations","title":"conjugates","text":"conjugates(x::AbsSimpleNumFieldElem, abs_tol::Int) -> Vector{AcbFieldElem}\n\nCompute the conjugates of x as elements of type AcbFieldElem. 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/manual/number_fields/elements/#conjugates_log-Tuple{AbsSimpleNumFieldElem, Int64}","page":"Element operations","title":"conjugates_log","text":"conjugates_arb_log(x::AbsSimpleNumFieldElem, abs_tol::Int) -> Vector{ArbFieldElem}\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 ArbFieldElem with radius less then 2^-abs_tol.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/number_fields/elements/#conjugates_real-Tuple{AbsSimpleNumFieldElem}","page":"Element operations","title":"conjugates_real","text":"conjugates_arb_real(x::AbsSimpleNumFieldElem, abs_tol::Int) -> Vector{ArbFieldElem}\n\nCompute the real conjugates of x as elements of type ArbFieldElem.\n\nEvery entry y of the array returned satisfies radius(y) < 2^-abs_tol.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/number_fields/elements/#conjugates_complex-Tuple{AbsSimpleNumFieldElem}","page":"Element operations","title":"conjugates_complex","text":"conjugates_complex(x::AbsSimpleNumFieldElem, abs_tol::Int) -> Vector{AcbFieldElem}\n\nCompute the complex conjugates of x as elements of type AcbFieldElem. 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/manual/number_fields/elements/#conjugates_arb_log_normalise-Tuple{AbsSimpleNumFieldElem}","page":"Element operations","title":"conjugates_arb_log_normalise","text":"conjugates_arb_log_normalise(x::AbsSimpleNumFieldElem, p::Int = 10)\nconjugates_arb_log_normalise(x::FacElem{AbsSimpleNumFieldElem, AbsSimpleNumField}, 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/manual/number_fields/elements/#minkowski_map-Tuple{AbsSimpleNumFieldElem}","page":"Element operations","title":"minkowski_map","text":"minkowski_map(a::AbsSimpleNumFieldElem, abs_tol::Int) -> Vector{ArbFieldElem}\n\nReturns the image of a under the Minkowski embedding. Every entry of the array returned is of type ArbFieldElem with radius less then 2^(-abs_tol).\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/number_fields/elements/#Predicates","page":"Element operations","title":"Predicates","text":"","category":"section"},{"location":"Hecke/manual/number_fields/elements/","page":"Element operations","title":"Element operations","text":"is_integral(::NumFieldElem)\nis_torsion_unit(::AbsSimpleNumFieldElem)\nis_local_norm(::NumField, ::NumFieldElem, ::Any)\nis_norm_divisible(::AbsSimpleNumFieldElem, ::ZZRingElem)\nis_norm(::AbsSimpleNumField, ::ZZRingElem)","category":"page"},{"location":"Hecke/manual/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\n\n","category":"method"},{"location":"Hecke/manual/number_fields/elements/#is_torsion_unit-Tuple{AbsSimpleNumFieldElem}","page":"Element operations","title":"is_torsion_unit","text":"is_torsion_unit(x::AbsSimpleNumFieldElem, 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/manual/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/manual/number_fields/elements/#is_norm_divisible-Tuple{AbsSimpleNumFieldElem, ZZRingElem}","page":"Element operations","title":"is_norm_divisible","text":"is_norm_divisible(a::AbsSimpleNumFieldElem, 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/manual/number_fields/elements/#is_norm-Tuple{AbsSimpleNumField, ZZRingElem}","page":"Element operations","title":"is_norm","text":"is_norm(K::AbsSimpleNumField, a::ZZRingElem; extra::Vector{ZZRingElem}) -> Bool, AbsSimpleNumFieldElem\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/manual/number_fields/elements/#Invariants","page":"Element operations","title":"Invariants","text":"","category":"section"},{"location":"Hecke/manual/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/manual/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\n\n","category":"method"},{"location":"Hecke/manual/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\n\n","category":"method"},{"location":"Hecke/manual/number_fields/elements/#minpoly-Tuple{NumFieldElem}","page":"Element operations","title":"minpoly","text":"minpoly(a::NumFieldElem) -> PolyRingElem\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\n\n","category":"method"},{"location":"Hecke/manual/number_fields/elements/#absolute_minpoly-Tuple{NumFieldElem}","page":"Element operations","title":"absolute_minpoly","text":"absolute_minpoly(a::NumFieldElem) -> PolyRingElem\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\n\n","category":"method"},{"location":"Hecke/manual/number_fields/elements/#charpoly-Tuple{NumFieldElem}","page":"Element operations","title":"charpoly","text":"charpoly(a::NumFieldElem) -> PolyRingElem\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\n\n","category":"method"},{"location":"Hecke/manual/number_fields/elements/#absolute_charpoly-Tuple{NumFieldElem}","page":"Element operations","title":"absolute_charpoly","text":"absolute_charpoly(a::NumFieldElem) -> PolyRingElem\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\n\n","category":"method"},{"location":"Hecke/manual/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\n\n","category":"method"},{"location":"Experimental/FTheoryTools/g4/","page":"G4-Fluxes","title":"G4-Fluxes","text":"CurrentModule = Oscar","category":"page"},{"location":"Experimental/FTheoryTools/g4/#G4-Fluxes","page":"G4-Fluxes","title":"G4-Fluxes","text":"","category":"section"},{"location":"Experimental/FTheoryTools/g4/","page":"G4-Fluxes","title":"G4-Fluxes","text":"G_4","category":"page"},{"location":"Experimental/FTheoryTools/g4/","page":"G4-Fluxes","title":"G4-Fluxes","text":"-fluxes are at the heart of F-theory model building.","category":"page"},{"location":"Experimental/FTheoryTools/g4/#Constructors","page":"G4-Fluxes","title":"Constructors","text":"","category":"section"},{"location":"Experimental/FTheoryTools/g4/","page":"G4-Fluxes","title":"G4-Fluxes","text":"We currently support the following constructor:","category":"page"},{"location":"Experimental/FTheoryTools/g4/","page":"G4-Fluxes","title":"G4-Fluxes","text":"g4_flux(model::AbstractFTheoryModel, class::CohomologyClass)","category":"page"},{"location":"Experimental/FTheoryTools/g4/#g4_flux-Tuple{AbstractFTheoryModel, CohomologyClass}","page":"G4-Fluxes","title":"g4_flux","text":"g4_flux(model::AbstractFTheoryModel, class::CohomologyClass)\n\nConstruct a G4-flux candidate on an F-theory model. This functionality is currently limited to\n\nWeierstrass models,\nglobal Tate models,\nhypersurface models.\n\nFurthermore, our functionality requires a concrete geometry. That is, the base space as well as the ambient space must be toric varieties. In the toric ambient space X_Sigma, the elliptically fibered space Y that defines the F-theory model, is given by a hypersurface (cut out by the Weierstrass, Tate or hypersurface polynomial, respectively).\n\nIn this setting, we assume that a G_4-flux candidate is represented by a cohomology class h in H^(22) (X_Sigma). The actual G_4-flux candidate is then obtained by restricting h to Y.\n\nIt is worth recalling that the G_4-flux candidate is subject to the quantization condition G_4 + frac12 c_2(Y) in H^22)( Y_ mathbbZ) (see [Wit97]). This condition is very hard to verify. However, it is relatively easy to gather evidence for this condition to be satisfied/show that it is violated. To this end, let D_1, D_2 be two toric divisors in X_Sigma, then the topological intersection number left h_Y right cdot left P right cdot left D_1 right cdot left D_2 right must be an integer. Even this rather elementary check can be computationally expensive. Users can therefore decide to skip this check upon construction by setting the parameter check to the value false.\n\nAnother bottleneck can be the computation of the cohomology ring, which is necessary to work with cohomology classes on the toric ambient space, which in turn define the G4-flux, as explained above. The reason for this is, that by employing the theory explained in [CLS11], we can only work out the cohomology ring of simpicial and complete (i.e. compact) toric varieties. However, checking if a toric variety is complete (i.e. compact) can take a long time. If the geometry in question is involved and you already know that the variety is simplicial and complete, then we recommend to trigger the computation of the cohomology ring with check = false. This will avoid this time consuming test.\n\nAn example is in order.\n\nExamples\n\njulia> qsm_model = literature_model(arxiv_id = \"1903.00009\", model_parameters = Dict(\"k\" => 4))\nHypersurface model over a concrete base\n\njulia> cohomology_ring(ambient_space(qsm_model), check = false);\n\njulia> g4_class = cohomology_class(anticanonical_divisor_class(ambient_space(qsm_model)))^2;\n\njulia> g4f = g4_flux(qsm_model, g4_class)\nG4-flux candidate\n\njulia> g4f2 = g4_flux(qsm_model, g4_class, check = false)\nG4-flux candidate lacking elementary quantization checks\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/g4/#Attributes","page":"G4-Fluxes","title":"Attributes","text":"","category":"section"},{"location":"Experimental/FTheoryTools/g4/","page":"G4-Fluxes","title":"G4-Fluxes","text":"We currently support the following attributes:","category":"page"},{"location":"Experimental/FTheoryTools/g4/","page":"G4-Fluxes","title":"G4-Fluxes","text":"model(gf::G4Flux)\ncohomology_class(gf::G4Flux)","category":"page"},{"location":"Experimental/FTheoryTools/g4/#model-Tuple{Oscar.G4Flux}","page":"G4-Fluxes","title":"model","text":"model(gf::G4Flux)\n\nReturn the F-theory model for which this G_4-flux candidate is defined.\n\njulia> qsm_model = literature_model(arxiv_id = \"1903.00009\", model_parameters = Dict(\"k\" => 4))\nHypersurface model over a concrete base\n\njulia> cohomology_ring(ambient_space(qsm_model), check = false);\n\njulia> g4_class = cohomology_class(anticanonical_divisor_class(ambient_space(qsm_model)))^2;\n\njulia> g4f = g4_flux(qsm_model, g4_class, check = false)\nG4-flux candidate lacking elementary quantization checks\n\njulia> model(g4f)\nHypersurface model over a concrete base\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/g4/#cohomology_class-Tuple{Oscar.G4Flux}","page":"G4-Fluxes","title":"cohomology_class","text":"cohomology_class(gf::G4Flux)\n\nReturn the cohomology class which defines the G_4-flux candidate.\n\njulia> qsm_model = literature_model(arxiv_id = \"1903.00009\", model_parameters = Dict(\"k\" => 4))\nHypersurface model over a concrete base\n\njulia> cohomology_ring(ambient_space(qsm_model), check = false);\n\njulia> g4_class = cohomology_class(anticanonical_divisor_class(ambient_space(qsm_model)))^2;\n\njulia> g4f = g4_flux(qsm_model, g4_class, check = false)\nG4-flux candidate lacking elementary quantization checks\n\njulia> cohomology_class(g4f) == g4_class\ntrue\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/g4/#Properties","page":"G4-Fluxes","title":"Properties","text":"","category":"section"},{"location":"Experimental/FTheoryTools/g4/","page":"G4-Fluxes","title":"G4-Fluxes","text":"We currently support the following properties:","category":"page"},{"location":"Experimental/FTheoryTools/g4/","page":"G4-Fluxes","title":"G4-Fluxes","text":"passes_elementary_quantization_checks(gf::G4Flux)","category":"page"},{"location":"Experimental/FTheoryTools/g4/#passes_elementary_quantization_checks-Tuple{Oscar.G4Flux}","page":"G4-Fluxes","title":"passes_elementary_quantization_checks","text":"passes_elementary_quantization_checks(gf::G4Flux)\n\nG4-fluxes are subject to the quantization condition [Wit97] G_4 + frac12 c_2(Y) in H^(22)(Y mathbbZ). It is hard to verify that this condition is met. However, we can execute a number of simple consistency checks, by verifying that int_YG_4 wedge D_1 wedge D_2 in mathbbZ for any two toric divisors D_1, D_2. If all of these simple consistency checks are met, this method will return true and otherwise false.\n\nIt is worth mentioning that currently (August 2024), we only support this check for G_4-fluxes defined on Weierstrass, global Tate and hypersurface models. If this condition is not met, this method will return an error.\n\njulia> qsm_model = literature_model(arxiv_id = \"1903.00009\", model_parameters = Dict(\"k\" => 4))\nHypersurface model over a concrete base\n\njulia> cohomology_ring(ambient_space(qsm_model), check = false);\n\njulia> g4_class = cohomology_class(anticanonical_divisor_class(ambient_space(qsm_model)))^2;\n\njulia> g4 = g4_flux(qsm_model, g4_class, check = false)\nG4-flux candidate lacking elementary quantization checks\n\njulia> passes_elementary_quantization_checks(g4)\ntrue\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/g4/#Methods","page":"G4-Fluxes","title":"Methods","text":"","category":"section"},{"location":"Groups/action/","page":"Group actions","title":"Group actions","text":"CurrentModule = Oscar\nDocTestSetup = Oscar.doctestsetup()","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 Omega (from the right) is defined by a map muOmegatimes Gto Omega that satisfies the compatibility conditions mu(mu(xg)h) = mu(x gh) and mu(x 1_G) = x for all xinOmega.","category":"page"},{"location":"Groups/action/","page":"Group actions","title":"Group actions","text":"The maps mu are implemented as functions that take two arguments, an element x of Omega 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 Omega 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::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 = 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::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 = 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::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 = 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::GapObj, p::PermGroupElem)\non_indeterminates(f::MPolyRingElem, p::PermGroupElem)\non_indeterminates(f::FreeAssociativeAlgebraElem, p::PermGroupElem)\non_indeterminates(f::MPolyIdeal, p::PermGroupElem)\n\nReturn the image of f under p where p acts via permuting the indeterminates.\n\nFor MPolyRingElem, FreeAssociativeAlgebraElem, 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\n\n\n\n\non_indeterminates(f::GapObj, p::MatrixGroupElem)\non_indeterminates(f::MPolyRingElem{T}, p::MatrixGroupElem{T}) where T\non_indeterminates(f::MPolyIdeal, p::MatrixGroupElem)\n\nReturn the image of f under p where p acts via evaluating f at the vector obtained by multiplying p with the (column) vector of indeterminates. This corresponds to considering the variables of the polynomial ring containing f as the basis of a vector space on which p acts by multiplication from the right.\n\nFor MPolyRingElem and MPolyIdeal objects, one can also call ^ instead of on_indeterminates.\n\nExamples\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. Note that the explicit elements of a G-set Omega can be obtained using collect(Omega).","category":"page"},{"location":"Groups/action/","page":"Group actions","title":"Group actions","text":"gset(G::Union{GAPGroup, FinGenAbGroup}, fun::Function, Omega)\npermutation\nacting_group(Omega::GSetByElements)\naction_function(Omega::GSetByElements)\naction_homomorphism(Omega::GSetByElements{T}) where T<:GAPGroup\nis_conjugate(Omega::GSet, omega1, omega2)\nis_conjugate_with_data(Omega::GSet, omega1, omega2)\norbit(Omega::GSetByElements{<:GAPGroup, S}, omega::S) where S\norbit(G::PermGroup, omega)\norbits(Omega::T) where T <: GSetByElements{TG} where TG <: GAPGroup","category":"page"},{"location":"Groups/action/#gset-Tuple{Union{FinGenAbGroup, Oscar.GAPGroup}, Function, Any}","page":"Group actions","title":"gset","text":"gset(G::Union{GAPGroup, FinGenAbGroup}[, 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","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","category":"function"},{"location":"Groups/action/#acting_group-Tuple{Oscar.GSetByElements}","page":"Group actions","title":"acting_group","text":"acting_group(Omega::GSetByElements)\n\nReturn the group G acting on Omega.\n\nExamples\n\njulia> G = symmetric_group(4);\n\njulia> acting_group(gset(G, [1])) == G\ntrue\n\n\n\n\n\n","category":"method"},{"location":"Groups/action/#action_function-Tuple{Oscar.GSetByElements}","page":"Group actions","title":"action_function","text":"action_function(Omega::GSetByElements)\n\nReturn the function f Omega times G to Omega that defines the G-set.\n\nExamples\n\njulia> G = symmetric_group(4);\n\njulia> action_function(gset(G, [1])) == ^\ntrue\n\njulia> action_function(gset(G, [[1, 2]])) == on_tuples\ntrue\n\njulia> action_function(gset(G, on_sets, [[1, 2]])) == on_sets\ntrue\n\n\n\n\n\n","category":"method"},{"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\n from Sym(6)\n to Sym(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","category":"method"},{"location":"Groups/action/#is_conjugate-Tuple{GSet, Any, Any}","page":"Group actions","title":"is_conjugate","text":"is_conjugate(Omega::GSet, omega1, omega2)\n\nReturn true if omega1, omega2 are in the same orbit of Omega, and false otherwise. To also obtain a conjugating element use is_conjugate_with_data.\n\nExamples\n\njulia> G = sylow_subgroup(symmetric_group(6), 2)[1]\nPermutation group of degree 6 and order 16\n\njulia> Omega = gset(G);\n\njulia> is_conjugate(Omega, 1, 2)\ntrue\n\njulia> is_conjugate(Omega, 1, 5)\nfalse\n\n\n\n\n\n","category":"method"},{"location":"Groups/action/#is_conjugate_with_data-Tuple{GSet, Any, Any}","page":"Group actions","title":"is_conjugate_with_data","text":"is_conjugate_with_data(Omega::GSet, omega1, omega2)\n\nDetermine whether omega1, omega2 are in the same orbit of Omega. If yes, return (true, g) where g is an element in the group G of Omega that maps omega1 to omega2. If not, return (false, nothing). If the conjugating element g is not needed, use is_conjugate.\n\nExamples\n\njulia> G = sylow_subgroup(symmetric_group(6), 2)[1]\nPermutation group of degree 6 and order 16\n\njulia> Omega = gset(G);\n\njulia> is_conjugate_with_data(Omega, 1, 2)\n(true, (1,2))\n\njulia> is_conjugate_with_data(Omega, 1, 5)\n(false, ())\n\n\n\n\n\n","category":"method"},{"location":"Groups/action/#orbit-Union{Tuple{S}, Tuple{Oscar.GSetByElements{<:Oscar.GAPGroup, S}, S}} where S","page":"Group actions","title":"orbit","text":"orbit(Omega::GSet, omega)\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]\nPermutation group of degree 6 and order 16\n\njulia> Omega = gset(G, [1, 5]);\n\njulia> length(orbit(Omega, 1))\n4\n\n\n\n\n\n","category":"method"},{"location":"Groups/action/#orbit-Tuple{PermGroup, Any}","page":"Group actions","title":"orbit","text":"orbit(G::Union{GAPGroup, FinGenAbGroup}[, 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","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]\nPermutation group of degree 6 and order 16\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","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::GAPGroup, pnt::Any, actfun::Function)\nstabilizer(Omega::GSet)","category":"page"},{"location":"Groups/action/#stabilizer-Tuple{Oscar.GAPGroup, Any, Function}","page":"Group actions","title":"stabilizer","text":"stabilizer(G::GAPGroup, pnt::Any[, actfun::Function])\n\nReturn S, emb where S is 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, and emb is the embedding of S into G.\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":"Groups/action/#stabilizer-Tuple{GSet}","page":"Group actions","title":"stabilizer","text":"stabilizer(Omega::GSet{T,S})\nstabilizer(Omega::GSet{T,S}, omega::S = representative(Omega); check::Bool = true) where {T,S}\n\nReturn the subgroup of G = acting_group(Omega) that fixes omega, together with the embedding of this subgroup into G. If check is false then it is not checked whether omega is in Omega.\n\nExamples\n\njulia> Omega = gset(symmetric_group(3));\n\njulia> stabilizer(Omega)\n(Permutation group of degree 3 and order 2, Hom: permutation group -> Sym(3))\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/free_modules/","page":"Free Modules","title":"Free Modules","text":"CurrentModule = Oscar\nDocTestSetup = Oscar.doctestsetup()","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 modeled 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 R\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 R at complement of prime ideal (x, y, z)\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 RQ 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{FinGenAbGroupElem})","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/free_modules/#grade-Tuple{FreeMod, Vector{FinGenAbGroupElem}}","page":"Free Modules","title":"grade","text":"grade(F::FreeMod, W::Vector{FinGenAbGroupElem})\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])\nZ^2\n\njulia> g = gens(G)\n2-element Vector{FinGenAbGroupElem}:\n [1, 0]\n [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 (x*y), Map: R -> S)\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{FinGenAbGroupElem}=[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::AdmissibleModuleFPRing, p::Int, W::Vector{FinGenAbGroupElem}=[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::AdmissibleModuleFPRing, W::Vector{FinGenAbGroupElem}, 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)\nZ\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::AdmissibleModuleFPRing, 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::AdmissibleModuleFPRing, W::Union{ZZMatrix, Matrix{<:IntegerUnion}}, name::String=\"e\")\n\nAs above, converting the columns of W.\n\ngraded_free_module(R::AdmissibleModuleFPRing, 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), number_of_generators(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)\nZ\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{FinGenAbGroupElem}:\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 modeled 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 R\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{T}) where {T<:Union{<:MPolyDecRingElem, <:MPolyQuoRingElem{<:MPolyDecRingElem}}}","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/free_modules/#degree-Union{Tuple{FreeModElem{T}}, Tuple{T}} where T<:(Union{var\"#s23\", var\"#s22\"} where {var\"#s23\"<:MPolyDecRingElem, var\"#s22\"<:(MPolyQuoRingElem{<:MPolyDecRingElem})})","page":"Free Modules","title":"degree","text":"degree(f::FreeModElem{T}; check::Bool=true) where {T<:AnyGradedRingElem}\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\nIf check is set to false, then there is no check for homegeneity. This should be called internally on provably sane input, as it speeds up computation significantly. \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))\nFinGenAbGroupElem\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> Rg, (x, y, z) = graded_polynomial_ring(QQ, [:x, :y, :z]);\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 R\n\njulia> G = free_module(R, 2)\nFree module of rank 2 over R\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 R\nCodomain:\n=========\nFree module of rank 2 over R\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 R\nCodomain:\n=========\nFree module of rank 2 over R\n\njulia> a == b\ntrue\n\njulia> Rg, (x, y, z) = graded_polynomial_ring(QQ, [:x, :y, :z]);\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 R\n\njulia> G = free_module(R, 2)\nFree module of rank 2 over R\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::ModuleFPHom)\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; check::Bool=true)\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)\nZ\n\n\n\n\n\n","category":"method"},{"location":"NumberTheory/intro/","page":"Introduction","title":"Introduction","text":"CurrentModule = Oscar","category":"page"},{"location":"NumberTheory/intro/#number_theory","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":"[Coh93]\n[Coh00]\n[Mar18]\n[PZ97]","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 src/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_type(::Type{MyParent})","category":"page"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"Return the type of the of base rings for parent objects with the given parent type. For example, base_ring_type(Generic.PolyRing{T}) will return parent_type(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 require 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/#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-unsafe-operators","page":"Ring Interface","title":"Optional unsafe operators","text":"","category":"section"},{"location":"AbstractAlgebra/ring_interface/","page":"Ring Interface","title":"Ring Interface","text":"The various operators described in Unsafe ring operators such as add! and mul! have default implementations which are not faster than their regular safe counterparts. Implementors may wish to implement some or all of them for their rings. Note that in general only the variants with the most arguments needs to be implemented. E.g. for add! only add(z,a,b) has to be implemented for any new ring type, as add!(a,b) delegates to add!(a,a,b).","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-2","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, base_ring_type, parent, is_domain_type,\n is_exact_type, canonical_unit, isequal, divexact, zero!, mul!, add!,\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_type(::Type{ConstPolyRing{T}}) where T <: RingElement = parent_type(T)\n\nbase_ring(R::ConstPolyRing) = R.base_ring::base_ring_type(R)\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 check_parent(f, g)\n R = parent(f)\n return R(f.c + g.c)\nend\n\nfunction -(f::ConstPoly{T}, g::ConstPoly{T}) where T <: RingElement\n check_parent(f, g)\n R = parent(f)\n return R(f.c - g.c)\nend\n\nfunction *(f::ConstPoly{T}, g::ConstPoly{T}) where T <: RingElement\n check_parent(f, g)\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 check_parent(f, g)\n return f.c == g.c\nend\n\nfunction isequal(f::ConstPoly{T}, g::ConstPoly{T}) where T <: RingElement\n check_parent(f, g)\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 check_parent(f, g)\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\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::AbstractUnitRange{Int}) = R(rand(rng, n))\n\nrand(R::ConstPolyRing, n::AbstractUnitRange{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 constant_polynomial_ring(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 constant_polynomial_ring 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(constant_polynomial_ring(S))","category":"page"},{"location":"Experimental/AlgebraicStatistics/ci/","page":"Conditional independence statements","title":"Conditional independence statements","text":"CurrentModule = Oscar\nDocTestSetup = Oscar.doctestsetup()","category":"page"},{"location":"Experimental/AlgebraicStatistics/ci/#Conditional-independence-statements","page":"Conditional independence statements","title":"Conditional independence statements","text":"","category":"section"},{"location":"Experimental/AlgebraicStatistics/ci/","page":"Conditional independence statements","title":"Conditional independence statements","text":"Conditional independence (CI) statements over a ground set N are triples of pairwise disjoint subsets I J K subseteq N denoted as I mathrel J mid K. The ground set indexes objects under consideration and the CI statement asserts that once the objects in K are \"controlled\" (conditioned on, in statistical language), the objects in I reveal no information about (are independent of) the objects in J.","category":"page"},{"location":"Experimental/AlgebraicStatistics/ci/","page":"Conditional independence statements","title":"Conditional independence statements","text":"The functionality documented here deals with CI statements are combinatorial objects. Collections of CI statements are often used to state Markov properties of graphical models in statistics and are ultimately used to define ideals. Their interpretations as polynomial equations depend on the ambient ring (markov_ring or gaussian_ring).","category":"page"},{"location":"Experimental/AlgebraicStatistics/ci/","page":"Conditional independence statements","title":"Conditional independence statements","text":"ci_stmt(I::Vector{<:VarName}, J::Vector{<:VarName}, K::Vector{<:VarName})\n@CI_str(str)\nBase.:(==)(lhs::CIStmt, rhs::CIStmt)\nBase.hash(stmt::CIStmt, h::UInt)\nci_statements(random_variables::Vector{<:VarName})\nmake_elementary(stmt::CIStmt; semigaussoid=false)","category":"page"},{"location":"Experimental/AlgebraicStatistics/ci/#ci_stmt-Tuple{Vector{<:Union{Char, AbstractString, Symbol}}, Vector{<:Union{Char, AbstractString, Symbol}}, Vector{<:Union{Char, AbstractString, Symbol}}}","page":"Conditional independence statements","title":"ci_stmt","text":"ci_stmt(I::Vector{<:VarName}, J::Vector{<:VarName}, K::Vector{<:VarName}; symmetric=true, semigraphoid=true)\n\nA conditional independence statement asserting that I is independent of J given K. These parameters are lists of names of random variables. The sets I and J must be disjoint as this package cannot yet deal with functional dependencies.\n\nIf symmetric is true, CI statements are assumed to be symmetric in their I and J components. The constructor then reorders the arguments to make the I field lexicographically smaller than the J to ensure that comparisons and hashing respect the symmetry.\n\nIf semigraphoid is set to true, the constructor also removes elements in the intersection of I and K from I (and symetrically removes the intersection of J and K from J).\n\nAs all three fields are sets, each of them may be deduplicated and sorted to ensure consistent comparison and hashing.\n\nExamples\n\njulia> ci_stmt([\"A\"], [\"B\"], [\"X\"])\n[A _||_ B | X]\n\njulia> ci_stmt([\"1\"], [\"2\", \"3\"], [\"4\", \"5\"])\n[1 _||_ {2, 3} | {4, 5}]\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/AlgebraicStatistics/ci/#@CI_str-Tuple{Any}","page":"Conditional independence statements","title":"@CI_str","text":"CI\"I...,J...|K...\"\n\nA literal syntax for denoting CI statements is provided for cases in which all variable names consist of a single character. If I and J only consist of a single element, then even the comma may be omitted. Once the three sets are extracted, ci_stmt is called.\n\nExamples\n\njulia> CI\"AB|X\"\n[A _||_ B | X]\n\njulia> CI\"1,23|5424\"\n[1 _||_ 3 | {2, 4, 5}]\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"macro"},{"location":"Experimental/AlgebraicStatistics/ci/#==-Tuple{CIStmt, CIStmt}","page":"Conditional independence statements","title":"==","text":"Base.:(==)(lhs::CIStmt, rhs::CIStmt)\n\nCompares CIStmts for identity in all their three fields.\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/AlgebraicStatistics/ci/#hash-Tuple{CIStmt, UInt64}","page":"Conditional independence statements","title":"hash","text":"Base.hash(stmt:;CIStmt, h::UInt)\n\nComputes the hash of a CIStmt.\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/AlgebraicStatistics/ci/#ci_statements-Tuple{Vector{<:Union{Char, AbstractString, Symbol}}}","page":"Conditional independence statements","title":"ci_statements","text":"ci_statements(random_variables::Vector{<:VarName})\n\nReturn a list of all elementary CI statements over a given set of variable names. A CIStmt(I, J, K) is elementary if both I and J have only one element.\n\nAs a consequence of the semigraphoid properties, these statements are enough to describe the entire CI structure of a probability distribution.\n\nExamples\n\njulia> ci_statements([\"A\", \"B\", \"X\", \"Y\"])\n24-element Vector{CIStmt}:\n [A _||_ Y | {}]\n [A _||_ Y | B]\n [A _||_ Y | X]\n [A _||_ Y | {B, X}]\n [B _||_ Y | {}]\n [B _||_ Y | A]\n [B _||_ Y | X]\n [B _||_ Y | {A, X}]\n [X _||_ Y | {}]\n [X _||_ Y | A]\n ⋮\n [A _||_ X | {B, Y}]\n [B _||_ X | {}]\n [B _||_ X | A]\n [B _||_ X | Y]\n [B _||_ X | {A, Y}]\n [A _||_ B | {}]\n [A _||_ B | X]\n [A _||_ B | Y]\n [A _||_ B | {X, Y}]\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/AlgebraicStatistics/ci/#make_elementary-Tuple{CIStmt}","page":"Conditional independence statements","title":"make_elementary","text":"make_elementary(stmt::CIStmt; semigaussoid=false)\n\nConvert a CIStmt into an equivalent list of CIStmts all of which are elementary. The default operation assumes the semigraphoid axioms and converts I mathrel J mid K into the list consisting of i mathrel j mid L for all i in I, j in J and L in the interval K subseteq L subseteq (I cup J cup K) setminus ij.\n\nIf semigaussoid is true, the stronger semigaussoid axioms are assumed and L in the above procedure does not range in the interval above K but is always fixed to K. Semigaussoids are also known as compositional graphoids.\n\nExamples\n\njulia> make_elementary(CI\"12,34|56\")\n16-element Vector{CIStmt}:\n [1 _||_ 3 | {5, 6}]\n [1 _||_ 3 | {5, 6, 2}]\n [1 _||_ 3 | {5, 6, 4}]\n [1 _||_ 3 | {5, 6, 2, 4}]\n [1 _||_ 4 | {5, 6}]\n [1 _||_ 4 | {5, 6, 2}]\n [1 _||_ 4 | {5, 6, 3}]\n [1 _||_ 4 | {5, 6, 2, 3}]\n [2 _||_ 3 | {5, 6}]\n [2 _||_ 3 | {5, 6, 1}]\n [2 _||_ 3 | {5, 6, 4}]\n [2 _||_ 3 | {5, 6, 1, 4}]\n [2 _||_ 4 | {5, 6}]\n [2 _||_ 4 | {5, 6, 1}]\n [2 _||_ 4 | {5, 6, 3}]\n [2 _||_ 4 | {5, 6, 1, 3}]\n\njulia> make_elementary(CI\"12,34|56\"; semigaussoid=true)\n4-element Vector{CIStmt}:\n [1 _||_ 3 | {5, 6}]\n [1 _||_ 4 | {5, 6}]\n [2 _||_ 3 | {5, 6}]\n [2 _||_ 4 | {5, 6}]\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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":"laurent_polynomial_ring(R::Ring, S::Vector{<:VarName}; cached::Bool = true)\nlaurent_polynomial_ring(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)\nnumber_of_variables(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::AbstractUnitRange{Int}, exp_range::AbstractUnitRange{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) = laurent_polynomial_ring(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":"Hecke/manual/quad_forms/integer_lattices/#Integer-Lattices","page":"Integer Lattices","title":"Integer Lattices","text":"","category":"section"},{"location":"Hecke/manual/quad_forms/integer_lattices/","page":"Integer Lattices","title":"Integer Lattices","text":"CurrentModule = Hecke\nDocTestSetup = quote\n using Hecke\n end","category":"page"},{"location":"Hecke/manual/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/manual/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/manual/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/manual/quad_forms/integer_lattices/#Creation-of-integer-lattices","page":"Integer Lattices","title":"Creation of integer lattices","text":"","category":"section"},{"location":"Hecke/manual/quad_forms/integer_lattices/#From-a-gram-matrix","page":"Integer Lattices","title":"From a gram matrix","text":"","category":"section"},{"location":"Hecke/manual/quad_forms/integer_lattices/","page":"Integer Lattices","title":"Integer Lattices","text":"integer_lattice(B::QQMatrix)","category":"page"},{"location":"Hecke/manual/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/manual/quad_forms/integer_lattices/#In-a-quadratic-space","page":"Integer Lattices","title":"In a quadratic space","text":"","category":"section"},{"location":"Hecke/manual/quad_forms/integer_lattices/","page":"Integer Lattices","title":"Integer Lattices","text":"lattice(V::QuadSpace{QQField, QQMatrix}, B::MatElem;)","category":"page"},{"location":"Hecke/manual/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/manual/quad_forms/integer_lattices/#Special-lattices","page":"Integer Lattices","title":"Special lattices","text":"","category":"section"},{"location":"Hecke/manual/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\nk3_lattice\nmukai_lattice(::Symbol)\nhyperkaehler_lattice(::Symbol)","category":"page"},{"location":"Hecke/manual/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\nThe type :I with parameter n = 1 is also allowed and denotes the odd unimodular lattice of rank 1.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/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/manual/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/manual/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 [CS99].\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(Hecke.kernel(vG; side = :right)))*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/manual/quad_forms/integer_lattices/#k3_lattice","page":"Integer Lattices","title":"k3_lattice","text":"k3_lattice()\n\nReturn the integer lattice corresponding to the Beauville-Bogomolov-Fujiki form associated to a K3 surface.\n\nExamples\n\njulia> L = k3_lattice();\n\njulia> is_unimodular(L)\ntrue\n\njulia> signature_tuple(L)\n(3, 0, 19)\n\n\n\n\n\n","category":"function"},{"location":"Hecke/manual/quad_forms/integer_lattices/#mukai_lattice-Tuple{Symbol}","page":"Integer Lattices","title":"mukai_lattice","text":"mukai_lattice(S::Symbol = :K3; extended::Bool = false)\n\nReturn the (extended) Mukai lattice.\n\nIf S == :K3, it returns the (extended) Mukai lattice associated to hyperkaehler manifolds which are deformation equivalent to a moduli space of stable sheaves on a K3 surface.\n\nIf S == :Ab, it returns the (extended) Mukai lattice associated to hyperkaehler manifolds which are deformation equivalent to a moduli space of stable sheaves on an abelian surface.\n\nExamples\n\njulia> L = mukai_lattice();\n\njulia> genus(L)\nGenus symbol for integer lattices\nSignatures: (4, 0, 20)\nLocal symbol:\n Local genus symbol at 2: 1^24\n\njulia> L = mukai_lattice(; extended = true);\n\njulia> genus(L)\nGenus symbol for integer lattices\nSignatures: (5, 0, 21)\nLocal symbol:\n Local genus symbol at 2: 1^26\n\njulia> L = mukai_lattice(:Ab);\n\njulia> genus(L)\nGenus symbol for integer lattices\nSignatures: (4, 0, 4)\nLocal symbol:\n Local genus symbol at 2: 1^8\n\njulia> L = mukai_lattice(:Ab; extended = true);\n\njulia> genus(L)\nGenus symbol for integer lattices\nSignatures: (5, 0, 5)\nLocal symbol:\n Local genus symbol at 2: 1^10\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/quad_forms/integer_lattices/#hyperkaehler_lattice-Tuple{Symbol}","page":"Integer Lattices","title":"hyperkaehler_lattice","text":"hyperkaehler_lattice(S::Symbol; n::Int = 2)\n\nReturn the integer lattice corresponding to the Beauville-Bogomolov-Fujiki form on a hyperkaehler manifold whose deformation type is determined by S and n.\n\nIf S == :K3 or S == :Kum, then n must be an integer bigger than 2;\nIf S == :OG6 or S == :OG10, the value of n has no effect.\n\nExamples\n\njulia> L = hyperkaehler_lattice(:Kum; n = 3)\nInteger lattice of rank 7 and degree 7\nwith gram matrix\n[0 1 0 0 0 0 0]\n[1 0 0 0 0 0 0]\n[0 0 0 1 0 0 0]\n[0 0 1 0 0 0 0]\n[0 0 0 0 0 1 0]\n[0 0 0 0 1 0 0]\n[0 0 0 0 0 0 -8]\n\njulia> L = hyperkaehler_lattice(:OG6)\nInteger lattice of rank 8 and degree 8\nwith gram matrix\n[0 1 0 0 0 0 0 0]\n[1 0 0 0 0 0 0 0]\n[0 0 0 1 0 0 0 0]\n[0 0 1 0 0 0 0 0]\n[0 0 0 0 0 1 0 0]\n[0 0 0 0 1 0 0 0]\n[0 0 0 0 0 0 -2 0]\n[0 0 0 0 0 0 0 -2]\n\njulia> L = hyperkaehler_lattice(:OG10);\n\njulia> genus(L)\nGenus symbol for integer lattices\nSignatures: (3, 0, 21)\nLocal symbols:\n Local genus symbol at 2: 1^-24\n Local genus symbol at 3: 1^-23 3^1\n\njulia> L = hyperkaehler_lattice(:K3; n = 3);\n\njulia> genus(L)\nGenus symbol for integer lattices\nSignatures: (3, 0, 20)\nLocal symbol:\n Local genus symbol at 2: 1^22 4^1_7\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/quad_forms/integer_lattices/#From-a-genus","page":"Integer Lattices","title":"From a genus","text":"","category":"section"},{"location":"Hecke/manual/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/manual/quad_forms/integer_lattices/#Rescaling-the-Quadratic-Form","page":"Integer Lattices","title":"Rescaling the Quadratic Form","text":"","category":"section"},{"location":"Hecke/manual/quad_forms/integer_lattices/","page":"Integer Lattices","title":"Integer Lattices","text":"rescale(::ZZLat, ::RationalUnion)","category":"page"},{"location":"Hecke/manual/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/manual/quad_forms/integer_lattices/#Attributes","page":"Integer Lattices","title":"Attributes","text":"","category":"section"},{"location":"Hecke/manual/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/manual/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/manual/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/manual/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/manual/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/manual/quad_forms/integer_lattices/#Invariants","page":"Integer Lattices","title":"Invariants","text":"","category":"section"},{"location":"Hecke/manual/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/manual/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/manual/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/manual/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/manual/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/manual/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/manual/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/manual/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/manual/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/manual/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/manual/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/manual/quad_forms/integer_lattices/#The-Genus","page":"Integer Lattices","title":"The Genus","text":"","category":"section"},{"location":"Hecke/manual/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/manual/quad_forms/integer_lattices/","page":"Integer Lattices","title":"Integer Lattices","text":"mass(L::ZZLat)\ngenus_representatives(L::ZZLat)","category":"page"},{"location":"Hecke/manual/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/manual/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/manual/quad_forms/integer_lattices/#Real-invariants","page":"Integer Lattices","title":"Real invariants","text":"","category":"section"},{"location":"Hecke/manual/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/manual/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/manual/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/manual/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/manual/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/manual/quad_forms/integer_lattices/#Isometries","page":"Integer Lattices","title":"Isometries","text":"","category":"section"},{"location":"Hecke/manual/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/manual/quad_forms/integer_lattices/#automorphism_group_generators-Tuple{ZZLat}","page":"Integer Lattices","title":"automorphism_group_generators","text":"automorphism_group_generators(E::EllipticCurve) -> 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 depth::Int = -1, bacher_depth::Int = 0)\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\nSetting the parameters depth and bacher_depth to a positive value may improve performance. If set to -1 (default), the used value of depth is chosen heuristically depending on the rank of L. By default, bacher_depth is set to 0.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/quad_forms/integer_lattices/#automorphism_group_order-Tuple{ZZLat}","page":"Integer Lattices","title":"automorphism_group_order","text":"automorphism_group_order(L::AbstractLat; depth::Int = -1, bacher_depth::Int = 0) -> Int\n\nGiven a definite lattice L, return the order of the automorphism group of L.\n\nSetting the parameters depth and bacher_depth to a positive value may improve performance. If set to -1 (default), the used value of depth is chosen heuristically depending on the rank of L. By default, bacher_depth is set to 0.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/quad_forms/integer_lattices/#is_isometric-Tuple{ZZLat, ZZLat}","page":"Integer Lattices","title":"is_isometric","text":"is_isometric(L::AbstractLat, M::AbstractLat; depth::Int = -1, bacher_depth::Int = 0) -> Bool\n\nReturn whether the lattices L and M are isometric.\n\nSetting the parameters depth and bacher_depth to a positive value may improve performance. If set to -1 (default), the used value of depth is chosen heuristically depending on the rank of L. By default, bacher_depth is set to 0.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/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/manual/quad_forms/integer_lattices/#Root-lattices","page":"Integer Lattices","title":"Root lattices","text":"","category":"section"},{"location":"Hecke/manual/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/manual/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\nThe root sublattice is the lattice spanned by the vectors of squared length 1 and 2. The odd lattice of rank 1 and determinant 1 is denoted by (:I, 1).\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\njulia> L = integer_lattice(; gram = QQ[1 0 0 0;\n 0 9 3 3;\n 0 3 2 1;\n 0 3 1 11])\nInteger lattice of rank 4 and degree 4\nwith gram matrix\n[1 0 0 0]\n[0 9 3 3]\n[0 3 2 1]\n[0 3 1 11]\n\njulia> root_lattice_recognition(L)\n([(:A, 1), (:I, 1)], ZZLat[Integer lattice of rank 1 and degree 4, Integer lattice of rank 1 and degree 4])\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/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\nThe type (:I, 1) corresponds to the odd unimodular root lattice of rank 1.\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/manual/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/manual/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/manual/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/manual/quad_forms/integer_lattices/#Module-operations","page":"Integer Lattices","title":"Module operations","text":"","category":"section"},{"location":"Hecke/manual/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/manual/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/manual/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/manual/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/manual/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/manual/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/manual/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/manual/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/manual/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/manual/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/manual/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: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/manual/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:1,:], bU[2: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/manual/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/manual/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/manual/quad_forms/integer_lattices/#Embeddings","page":"Integer Lattices","title":"Embeddings","text":"","category":"section"},{"location":"Hecke/manual/quad_forms/integer_lattices/#Categorical-constructions","page":"Integer Lattices","title":"Categorical constructions","text":"","category":"section"},{"location":"Hecke/manual/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/manual/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/manual/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/manual/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/manual/quad_forms/integer_lattices/#Orthogonal-sublattices","page":"Integer Lattices","title":"Orthogonal sublattices","text":"","category":"section"},{"location":"Hecke/manual/quad_forms/integer_lattices/","page":"Integer Lattices","title":"Integer Lattices","text":"orthogonal_submodule(::ZZLat, ::ZZLat)\nirreducible_components(::ZZLat)","category":"page"},{"location":"Hecke/manual/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/manual/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/manual/quad_forms/integer_lattices/#Dual-lattice","page":"Integer Lattices","title":"Dual lattice","text":"","category":"section"},{"location":"Hecke/manual/quad_forms/integer_lattices/","page":"Integer Lattices","title":"Integer Lattices","text":"dual(L::ZZLat)","category":"page"},{"location":"Hecke/manual/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/manual/quad_forms/integer_lattices/#Discriminant-group","page":"Integer Lattices","title":"Discriminant group","text":"","category":"section"},{"location":"Hecke/manual/quad_forms/integer_lattices/","page":"Integer Lattices","title":"Integer Lattices","text":"See discriminant_group(L::ZZLat).","category":"page"},{"location":"Hecke/manual/quad_forms/integer_lattices/#Overlattices","page":"Integer Lattices","title":"Overlattices","text":"","category":"section"},{"location":"Hecke/manual/quad_forms/integer_lattices/","page":"Integer Lattices","title":"Integer Lattices","text":"glue_map(L::ZZLat, S::ZZLat, R::ZZLat; check=true)\noverlattice(glue_map::TorQuadModuleMap)\nlocal_modification(M::ZZLat, L::ZZLat, p)\nmaximal_integral_lattice(L::ZZLat)","category":"page"},{"location":"Hecke/manual/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{TorQuadModuleMap, TorQuadModuleMap, TorQuadModuleMap}\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: finite quadratic module -> finite quadratic module, Map: finite quadratic module -> finite quadratic module, Map: finite quadratic module -> finite quadratic module)\n\njulia> is_bijective(glue)\ntrue\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/quad_forms/integer_lattices/#overlattice-Tuple{TorQuadModuleMap}","page":"Integer Lattices","title":"overlattice","text":"overlattice(glue_map::TorQuadModuleMap) -> 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/manual/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/manual/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 with integral norm, return a maximal integral overlattice M of L.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/quad_forms/integer_lattices/#Sublattices-defined-by-endomorphisms","page":"Integer Lattices","title":"Sublattices defined by endomorphisms","text":"","category":"section"},{"location":"Hecke/manual/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/manual/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/manual/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/manual/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/manual/quad_forms/integer_lattices/#Computing-embeddings","page":"Integer Lattices","title":"Computing embeddings","text":"","category":"section"},{"location":"Hecke/manual/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/manual/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/manual/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/manual/quad_forms/integer_lattices/#LLL,-Short-and-Close-Vectors","page":"Integer Lattices","title":"LLL, Short and Close Vectors","text":"","category":"section"},{"location":"Hecke/manual/quad_forms/integer_lattices/#LLL-and-indefinite-LLL","page":"Integer Lattices","title":"LLL and indefinite LLL","text":"","category":"section"},{"location":"Hecke/manual/quad_forms/integer_lattices/","page":"Integer Lattices","title":"Integer Lattices","text":"lll(L::ZZLat; same_ambient::Bool = true)","category":"page"},{"location":"Hecke/manual/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/manual/quad_forms/integer_lattices/#Short-Vectors","page":"Integer Lattices","title":"Short Vectors","text":"","category":"section"},{"location":"Hecke/manual/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/manual/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\nReturn 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 definite.\n\nSee also short_vectors_iterator for an iterator version.\n\n\n\n\n\n","category":"function"},{"location":"Hecke/manual/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\nReturn the list of shortest non-zero vectors in absolute value. 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 definite.\n\nSee also minimum.\n\n\n\n\n\n","category":"function"},{"location":"Hecke/manual/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\nReturn 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 definite.\n\nSee also short_vectors.\n\n\n\n\n\n","category":"function"},{"location":"Hecke/manual/quad_forms/integer_lattices/#minimum-Tuple{ZZLat}","page":"Integer Lattices","title":"minimum","text":"minimum(L::ZZLat) -> QQFieldElem\n\nReturn the minimum absolute squared length among the non-zero vectors in L.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/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/manual/quad_forms/integer_lattices/#Close-Vectors","page":"Integer Lattices","title":"Close Vectors","text":"","category":"section"},{"location":"Hecke/manual/quad_forms/integer_lattices/","page":"Integer Lattices","title":"Integer Lattices","text":"close_vectors(L::ZZLat, v::Vector, arg...; kw...)","category":"page"},{"location":"Hecke/manual/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/manual/quad_forms/integer_lattices/","page":"Integer Lattices","title":"Integer Lattices","text":"","category":"page"},{"location":"Fields/intro/","page":"Introduction","title":"Introduction","text":"CurrentModule = Oscar\nDocTestSetup = Oscar.doctestsetup()","category":"page"},{"location":"Fields/intro/#fields","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\nAlgebraic numbers\nAlgebraic closure of finite prime 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":"[Coh93]\n[Coh00]\n[LN97]\n[Mar18]\n[PZ97]","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":"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]; internal_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":"intersect(::Generic.Ideal{T}, ::Generic.Ideal{T}) where T <: RingElement","category":"page"},{"location":"AbstractAlgebra/ideal/#intersect-Union{Tuple{T}, Tuple{AbstractAlgebra.Generic.Ideal{T}, AbstractAlgebra.Generic.Ideal{T}}} where T<:RingElement","page":"Ideal functionality","title":"intersect","text":"intersect(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> intersect(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]; internal_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":"Hecke/manual/developer/test/#Testing","page":"Testing","title":"Testing","text":"","category":"section"},{"location":"Hecke/manual/developer/test/#Structure","page":"Testing","title":"Structure","text":"","category":"section"},{"location":"Hecke/manual/developer/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/manual/developer/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/manual/developer/test/#Adding-tests","page":"Testing","title":"Adding tests","text":"","category":"section"},{"location":"Hecke/manual/developer/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/manual/developer/test/#Adding-long-tests","page":"Testing","title":"Adding long tests","text":"","category":"section"},{"location":"Hecke/manual/developer/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/manual/developer/test/#Running-the-tests","page":"Testing","title":"Running the tests","text":"","category":"section"},{"location":"Hecke/manual/developer/test/#Running-all-tests","page":"Testing","title":"Running all tests","text":"","category":"section"},{"location":"Hecke/manual/developer/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/manual/developer/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/manual/developer/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/manual/developer/test/#Running-a-subset-of-tests","page":"Testing","title":"Running a subset of tests","text":"","category":"section"},{"location":"Hecke/manual/developer/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/manual/developer/test/","page":"Testing","title":"Testing","text":"julia> Hecke.test_module(\"QuadForm/Quad/Genus\")","category":"page"},{"location":"Hecke/manual/developer/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/manual/developer/test/","page":"Testing","title":"Testing","text":"julia> Hecke.test_module(\"QuadForm\")","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 organized 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":"[GLS07] \n[JP00]\n[C-MLS20]\n[C-MLS21]","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":"julia> R = GF(7)\nPrime field of characteristic 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":"julia> a = R(3)\n3","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)\nPrime field of characteristic 3\n\njulia> a = characteristic(F)\n3\n\njulia> b = order(F)\n3","category":"page"},{"location":"Experimental/IntersectionTheory/BottFormulas/","page":"Bott Formulas","title":"Bott Formulas","text":"CurrentModule = Oscar","category":"page"},{"location":"Experimental/IntersectionTheory/BottFormulas/#Bott-Formulas","page":"Bott Formulas","title":"Bott Formulas","text":"","category":"section"},{"location":"Hecke/manual/quad_forms/Zgenera/#Genera-of-Integer-Lattices","page":"Genera of Integer Lattices","title":"Genera of Integer Lattices","text":"","category":"section"},{"location":"Hecke/manual/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/manual/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/manual/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 [CS99] Chapter 15 for the definitions. Note that genera for non-integral lattices are supported.","category":"page"},{"location":"Hecke/manual/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/manual/quad_forms/Zgenera/","page":"Genera of Integer Lattices","title":"Genera of Integer Lattices","text":"ZZGenus","category":"page"},{"location":"Hecke/manual/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/manual/quad_forms/Zgenera/#Creation-of-Genera","page":"Genera of Integer Lattices","title":"Creation of Genera","text":"","category":"section"},{"location":"Hecke/manual/quad_forms/Zgenera/#From-an-integral-Lattice","page":"Genera of Integer Lattices","title":"From an integral Lattice","text":"","category":"section"},{"location":"Hecke/manual/quad_forms/Zgenera/","page":"Genera of Integer Lattices","title":"Genera of Integer Lattices","text":"genus(::ZZLat)","category":"page"},{"location":"Hecke/manual/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/manual/quad_forms/Zgenera/#From-a-gram-matrix","page":"Genera of Integer Lattices","title":"From a gram matrix","text":"","category":"section"},{"location":"Hecke/manual/quad_forms/Zgenera/","page":"Genera of Integer Lattices","title":"Genera of Integer Lattices","text":"genus(A::MatElem)","category":"page"},{"location":"Hecke/manual/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/manual/quad_forms/Zgenera/#Enumeration-of-genus-symbols","page":"Genera of Integer Lattices","title":"Enumeration of genus symbols","text":"","category":"section"},{"location":"Hecke/manual/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/manual/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/manual/quad_forms/Zgenera/#From-other-genus-symbols","page":"Genera of Integer Lattices","title":"From other genus symbols","text":"","category":"section"},{"location":"Hecke/manual/quad_forms/Zgenera/","page":"Genera of Integer Lattices","title":"Genera of Integer Lattices","text":"direct_sum(G1::ZZGenus, G2::ZZGenus)","category":"page"},{"location":"Hecke/manual/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/manual/quad_forms/Zgenera/#Attributes-of-the-genus","page":"Genera of Integer Lattices","title":"Attributes of the genus","text":"","category":"section"},{"location":"Hecke/manual/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/manual/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/manual/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/manual/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/manual/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/manual/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/manual/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/manual/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/manual/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/manual/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/manual/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/manual/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/manual/quad_forms/Zgenera/#Discriminant-group","page":"Genera of Integer Lattices","title":"Discriminant group","text":"","category":"section"},{"location":"Hecke/manual/quad_forms/Zgenera/","page":"Genera of Integer Lattices","title":"Genera of Integer Lattices","text":"discriminant_group(::ZZGenus)","category":"page"},{"location":"Hecke/manual/quad_forms/Zgenera/#Primary-genera","page":"Genera of Integer Lattices","title":"Primary genera","text":"","category":"section"},{"location":"Hecke/manual/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/manual/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/manual/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/manual/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/manual/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/manual/quad_forms/Zgenera/#local-Symbol","page":"Genera of Integer Lattices","title":"local Symbol","text":"","category":"section"},{"location":"Hecke/manual/quad_forms/Zgenera/","page":"Genera of Integer Lattices","title":"Genera of Integer Lattices","text":"local_symbol(G::ZZGenus, p)","category":"page"},{"location":"Hecke/manual/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/manual/quad_forms/Zgenera/#Representative(s)","page":"Genera of Integer Lattices","title":"Representative(s)","text":"","category":"section"},{"location":"Hecke/manual/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/manual/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/manual/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/manual/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/manual/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/manual/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/manual/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/manual/quad_forms/Zgenera/#Embeddings-and-Representations","page":"Genera of Integer Lattices","title":"Embeddings and Representations","text":"","category":"section"},{"location":"Hecke/manual/quad_forms/Zgenera/","page":"Genera of Integer Lattices","title":"Genera of Integer Lattices","text":"represents(G1::ZZGenus, G2::ZZGenus)","category":"page"},{"location":"Hecke/manual/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/manual/quad_forms/Zgenera/#Local-genus-Symbols","page":"Genera of Integer Lattices","title":"Local genus Symbols","text":"","category":"section"},{"location":"Hecke/manual/quad_forms/Zgenera/","page":"Genera of Integer Lattices","title":"Genera of Integer Lattices","text":"ZZLocalGenus","category":"page"},{"location":"Hecke/manual/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: [CS99] 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/manual/quad_forms/Zgenera/#Creation","page":"Genera of Integer Lattices","title":"Creation","text":"","category":"section"},{"location":"Hecke/manual/quad_forms/Zgenera/","page":"Genera of Integer Lattices","title":"Genera of Integer Lattices","text":"genus(::ZZLat, ::IntegerUnion)\ngenus(::QQMatrix, ::IntegerUnion)","category":"page"},{"location":"Hecke/manual/quad_forms/Zgenera/#genus-Tuple{ZZLat, Union{Integer, ZZRingElem}}","page":"Genera of Integer Lattices","title":"genus","text":"genus(L::ZZLat, p::IntegerUnion) -> ZZLocalGenus\n\nReturn the local genus symbol of L at the prime p.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/quad_forms/Zgenera/#genus-Tuple{QQMatrix, Union{Integer, ZZRingElem}}","page":"Genera of Integer Lattices","title":"genus","text":"genus(A::QQMatrix, p::IntegerUnion) -> 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/manual/quad_forms/Zgenera/#Attributes","page":"Genera of Integer Lattices","title":"Attributes","text":"","category":"section"},{"location":"Hecke/manual/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/manual/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/manual/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/manual/quad_forms/Zgenera/#symbol-Tuple{ZZLocalGenus, Int64}","page":"Genera of Integer Lattices","title":"symbol","text":"symbol(S::ZZLocalGenus, scale::Int) -> Vector{Int}\n\nReturn the underlying lists of integers for the Jordan block of the given scale\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/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/manual/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/manual/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/manual/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/manual/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\n[CS99] pp 370-371.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/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/manual/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/manual/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/manual/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/manual/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/manual/quad_forms/Zgenera/#Representative","page":"Genera of Integer Lattices","title":"Representative","text":"","category":"section"},{"location":"Hecke/manual/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/manual/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/manual/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/manual/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/manual/quad_forms/Zgenera/#Direct-sums","page":"Genera of Integer Lattices","title":"Direct sums","text":"","category":"section"},{"location":"Hecke/manual/quad_forms/Zgenera/","page":"Genera of Integer Lattices","title":"Genera of Integer Lattices","text":"direct_sum(S1::ZZLocalGenus, S2::ZZLocalGenus)","category":"page"},{"location":"Hecke/manual/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/manual/quad_forms/Zgenera/#Embeddings/Representations","page":"Genera of Integer Lattices","title":"Embeddings/Representations","text":"","category":"section"},{"location":"Hecke/manual/quad_forms/Zgenera/","page":"Genera of Integer Lattices","title":"Genera of Integer Lattices","text":"represents(G1::ZZLocalGenus, G2::ZZLocalGenus)","category":"page"},{"location":"Hecke/manual/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":"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 RealPolyRingElem RealPolyRing\nmathbbC (arbitrary precision) Arb ComplexPolyRingElem ComplexPolyRing\nmathbbR (fixed precision) Arb ArbPolyRingElem ArbPolyRing\nmathbbC (fixed precision) Arb AcbPolyRingElem 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(::RealPolyRingElem, ::RealFieldElem)","category":"page"},{"location":"Nemo/polynomial/#evaluate2-Tuple{RealPolyRingElem, RealFieldElem}","page":"Univariate polynomials","title":"evaluate2","text":"evaluate2(x::RealPolyRingElem, 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(::ComplexPolyRingElem, ::ComplexFieldElem)","category":"page"},{"location":"Nemo/polynomial/#evaluate2-Tuple{ComplexPolyRingElem, ComplexFieldElem}","page":"Univariate polynomials","title":"evaluate2","text":"evaluate2(x::ComplexPolyRingElem, 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":"julia> RR = RealField()\nReal field\n\njulia> T, z = polynomial_ring(RR, \"z\")\n(Univariate polynomial ring in z over RR, z)\n\njulia> h = z^2 + 2z + 1\nz^2 + 2.0000000000000000000*z + 1\n\njulia> s, t = evaluate2(h, RR(\"2.0 +/- 0.1\"))\n([9e+0 +/- 0.611], [6e+0 +/- 0.201])","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(::ComplexPolyRingElem)","category":"page"},{"location":"Nemo/polynomial/#roots-Tuple{ComplexPolyRingElem}","page":"Univariate polynomials","title":"roots","text":"roots(x::ComplexPolyRingElem; 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":"julia> CC = ComplexField()\nComplex field\n\njulia> C, y = polynomial_ring(CC, \"y\")\n(Univariate polynomial ring in y over CC, y)\n\njulia> m = y^2 + 2y + 3\ny^2 + 2.0000000000000000000*y + 3.0000000000000000000\n\njulia> n = m + CC(\"0 +/- 0.0001\", \"0 +/- 0.0001\")\ny^2 + 2.0000000000000000000*y + [3.000 +/- 1.01e-4] + [+/- 1.01e-4]*im\n\njulia> r = roots(n);\n\njulia> sort(r; by=x->(real(x), imag(x))) # sort roots to make printing consistent\n2-element Vector{ComplexFieldElem}:\n [-1.00 +/- 1.01e-4] + [-1.414 +/- 3.14e-4]*im\n [-1.00 +/- 1.01e-4] + [1.414 +/- 3.14e-4]*im\n\njulia> p = y^7 - 1\ny^7 - 1.0000000000000000000\n\njulia> r = roots(n, isolate_real = true);\n\njulia> sort(r; by=x->(real(x), imag(x))) # sort roots to make printing consistent\n2-element Vector{ComplexFieldElem}:\n [-1.00 +/- 1.01e-4] + [-1.414 +/- 3.14e-4]*im\n [-1.00 +/- 1.01e-4] + [1.414 +/- 3.14e-4]*im","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{ArbFieldElem})\nfrom_roots(::AcbPolyRing, ::Vector{AcbFieldElem})","category":"page"},{"location":"Nemo/polynomial/#from_roots-Tuple{ArbPolyRing, Vector{ArbFieldElem}}","page":"Univariate polynomials","title":"from_roots","text":"from_roots(R::ArbPolyRing, b::Vector{ArbFieldElem})\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{AcbFieldElem}}","page":"Univariate polynomials","title":"from_roots","text":"from_roots(R::AcbPolyRing, b::Vector{AcbFieldElem})\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":"julia> RR = RealField()\nReal field\n\njulia> R, x = polynomial_ring(RR, \"x\")\n(Univariate polynomial ring in x over RR, x)\n\njulia> xs = [inv(RR(i)) for i=1:5]\n5-element Vector{RealFieldElem}:\n 1.0000000000000000000\n 0.50000000000000000000\n [0.3333333333333333333 +/- 4.24e-20]\n 0.25000000000000000000\n [0.2000000000000000000 +/- 2.44e-20]\n\njulia> f = from_roots(R, xs)\nx^5 + [-2.283333333333333333 +/- 4.54e-19]*x^4 + [1.875000000000000000 +/- 5.10e-19]*x^3 + [-0.708333333333333333 +/- 3.99e-19]*x^2 + [0.1250000000000000000 +/- 3.69e-20]*x + [-0.00833333333333333333 +/- 4.13e-21]\n\njulia> all(x -> contains_zero(evaluate(f, x)), xs)\ntrue","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(::RealPolyRingElem)\nroots_upper_bound(::ComplexPolyRingElem)","category":"page"},{"location":"Nemo/polynomial/#roots_upper_bound-Tuple{RealPolyRingElem}","page":"Univariate polynomials","title":"roots_upper_bound","text":"roots_upper_bound(x::RealPolyRingElem) -> ArbFieldElem\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{ComplexPolyRingElem}","page":"Univariate polynomials","title":"roots_upper_bound","text":"roots_upper_bound(x::ComplexPolyRingElem) -> ArbFieldElem\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 non-negative 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 non-negative 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 non-negative 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 non-negative 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":"julia> R, = residue_ring(ZZ, 123456789012345678949)\n(Integers modulo 123456789012345678949, Map: ZZ -> ZZ/(123456789012345678949))\n\njulia> S, x = polynomial_ring(R, \"x\")\n(Univariate polynomial ring in x over ZZ/(123456789012345678949), x)\n\njulia> T, y = polynomial_ring(ZZ, \"y\")\n(Univariate polynomial ring in y over ZZ, y)\n\njulia> f = x^2 + 2x + 1\nx^2 + 2*x + 1\n\njulia> a = lift(T, f)\ny^2 + 2*y + 1","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(::RealPolyRingElem, ::RealPolyRingElem)\noverlaps(::ComplexPolyRingElem, ::ComplexPolyRingElem)","category":"page"},{"location":"Nemo/polynomial/#overlaps-Tuple{RealPolyRingElem, RealPolyRingElem}","page":"Univariate polynomials","title":"overlaps","text":"overlaps(x::RealPolyRingElem, y::RealPolyRingElem)\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{ComplexPolyRingElem, ComplexPolyRingElem}","page":"Univariate polynomials","title":"overlaps","text":"overlaps(x::ComplexPolyRingElem, y::ComplexPolyRingElem)\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(::RealPolyRingElem, ::RealPolyRingElem)\ncontains(::ComplexPolyRingElem, ::ComplexPolyRingElem)","category":"page"},{"location":"Nemo/polynomial/#contains-Tuple{RealPolyRingElem, RealPolyRingElem}","page":"Univariate polynomials","title":"contains","text":"contains(x::RealPolyRingElem, y::RealPolyRingElem)\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{ComplexPolyRingElem, ComplexPolyRingElem}","page":"Univariate polynomials","title":"contains","text":"contains(x::ComplexPolyRingElem, y::ComplexPolyRingElem)\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(::RealPolyRingElem, ::ZZPolyRingElem)\ncontains(::RealPolyRingElem, ::QQPolyRingElem)\ncontains(::ComplexPolyRingElem, ::ZZPolyRingElem)\ncontains(::ComplexPolyRingElem, ::QQPolyRingElem)","category":"page"},{"location":"Nemo/polynomial/#contains-Tuple{RealPolyRingElem, ZZPolyRingElem}","page":"Univariate polynomials","title":"contains","text":"contains(x::RealPolyRingElem, 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{RealPolyRingElem, QQPolyRingElem}","page":"Univariate polynomials","title":"contains","text":"contains(x::RealPolyRingElem, 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{ComplexPolyRingElem, ZZPolyRingElem}","page":"Univariate polynomials","title":"contains","text":"contains(x::ComplexPolyRingElem, 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{ComplexPolyRingElem, QQPolyRingElem}","page":"Univariate polynomials","title":"contains","text":"contains(x::ComplexPolyRingElem, 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(::RealPolyRingElem)\nunique_integer(::ComplexPolyRingElem)","category":"page"},{"location":"Nemo/polynomial/#unique_integer-Tuple{RealPolyRingElem}","page":"Univariate polynomials","title":"unique_integer","text":"unique_integer(x::RealPolyRingElem)\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{ComplexPolyRingElem}","page":"Univariate polynomials","title":"unique_integer","text":"unique_integer(x::ComplexPolyRingElem)\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":"julia> RR = RealField()\nReal field\n\njulia> R, x = polynomial_ring(RR, \"x\")\n(Univariate polynomial ring in x over RR, x)\n\njulia> f = x^2 + 2x + 1\nx^2 + 2.0000000000000000000*x + 1\n\njulia> h = f + RR(\"0 +/- 0.0001\")\nx^2 + 2.0000000000000000000*x + [1.000 +/- 1.01e-4]\n\njulia> k = f + RR(\"0 +/- 0.0001\") * x^4\n[+/- 1.01e-4]*x^4 + x^2 + 2.0000000000000000000*x + 1\n\njulia> contains(h, f)\ntrue\n\njulia> overlaps(f, k)\ntrue\n\njulia> t, z = unique_integer(k)\n(true, x^2 + 2*x + 1)","category":"page"},{"location":"Nemo/polynomial/","page":"Univariate polynomials","title":"Univariate polynomials","text":"julia> CC = ComplexField()\nComplex field\n\njulia> C, y = polynomial_ring(CC, \"y\")\n(Univariate polynomial ring in y over CC, y)\n\njulia> m = y^2 + 2y + 1\ny^2 + 2.0000000000000000000*y + 1\n\njulia> n = m + CC(\"0 +/- 0.0001\", \"0 +/- 0.0001\")\ny^2 + 2.0000000000000000000*y + [1.000 +/- 1.01e-4] + [+/- 1.01e-4]*im\n\njulia> contains(n, m)\ntrue\n\njulia> isreal(n)\nfalse\n\njulia> isreal(m)\ntrue","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":"julia> R, = residue_ring(ZZ, 23)\n(Integers modulo 23, Map: ZZ -> ZZ/(23))\n\njulia> S, x = polynomial_ring(R, \"x\")\n(Univariate polynomial ring in x over ZZ/(23), x)\n\njulia> f = x^2 + 2x + 1\nx^2 + 2*x + 1\n\njulia> g = x^3 + 3x + 1\nx^3 + 3*x + 1\n\njulia> R = factor(f*g)\n1 * (x + 1)^2 * (x^3 + 3*x + 1)\n\njulia> S = factor_squarefree(f*g)\n1 * (x + 1)^2 * (x^3 + 3*x + 1)\n\njulia> T = factor_distinct_deg((x + 1)*g*(x^5+x^3+x+1))\nDict{Int64, zzModPolyRingElem} with 3 entries:\n 4 => x^4 + 7*x^3 + 4*x^2 + 5*x + 13\n 3 => x^3 + 3*x + 1\n 1 => x^2 + 17*x + 16","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":"julia> R, x = polynomial_ring(ZZ, \"x\")\n(Univariate polynomial ring in x over ZZ, x)\n\njulia> h = cyclotomic(120, x)\nx^32 + x^28 - x^20 - x^16 - x^12 + x^4 + 1\n\njulia> j = swinnerton_dyer(5, x)\nx^32 - 448*x^30 + 84864*x^28 - 9028096*x^26 + 602397952*x^24 - 26625650688*x^22 + 801918722048*x^20 - 16665641517056*x^18 + 239210760462336*x^16 - 2349014746136576*x^14 + 15459151516270592*x^12 - 65892492886671360*x^10 + 172580952324702208*x^8 - 255690851718529024*x^6 + 183876928237731840*x^4 - 44660812492570624*x^2 + 2000989041197056\n\njulia> k = cos_minpoly(30, x)\nx^4 + x^3 - 4*x^2 - 4*x + 1\n\njulia> l = theta_qexp(3, 30, x)\n72*x^29 + 32*x^27 + 72*x^26 + 30*x^25 + 24*x^24 + 24*x^22 + 48*x^21 + 24*x^20 + 24*x^19 + 36*x^18 + 48*x^17 + 6*x^16 + 48*x^14 + 24*x^13 + 8*x^12 + 24*x^11 + 24*x^10 + 30*x^9 + 12*x^8 + 24*x^6 + 24*x^5 + 6*x^4 + 8*x^3 + 12*x^2 + 6*x + 1\n\njulia> m = eta_qexp(24, 30, x)\n-29211840*x^29 + 128406630*x^28 + 24647168*x^27 - 73279080*x^26 + 13865712*x^25 - 25499225*x^24 + 21288960*x^23 + 18643272*x^22 - 12830688*x^21 - 4219488*x^20 - 7109760*x^19 + 10661420*x^18 + 2727432*x^17 - 6905934*x^16 + 987136*x^15 + 1217160*x^14 + 401856*x^13 - 577738*x^12 - 370944*x^11 + 534612*x^10 - 115920*x^9 - 113643*x^8 + 84480*x^7 - 16744*x^6 - 6048*x^5 + 4830*x^4 - 1472*x^3 + 252*x^2 - 24*x + 1\n\njulia> o = cyclotomic(10, 1 + x + x^2)\nx^8 + 4*x^7 + 9*x^6 + 13*x^5 + 14*x^4 + 11*x^3 + 6*x^2 + 2*x + 1","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::NormalToricVarietyType, character::Vector{T}) where {T <: IntegerUnion}\ntoric_divisor(v::NormalToricVarietyType, coeffs::Vector{T}) where {T <: IntegerUnion}","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/ToricDivisors/#divisor_of_character-Union{Tuple{T}, Tuple{Union{AffineNormalToricVariety, CyclicQuotientSingularity, NormalToricVariety}, Vector{T}}} where T<:Union{Integer, ZZRingElem}","page":"Toric Divisors","title":"divisor_of_character","text":"divisor_of_character(v::NormalToricVarietyType, 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{Union{AffineNormalToricVariety, CyclicQuotientSingularity, NormalToricVariety}, Vector{T}}} where T<:Union{Integer, ZZRingElem}","page":"Toric Divisors","title":"toric_divisor","text":"toric_divisor(v::NormalToricVarietyType, 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::NormalToricVarietyType)\nanticanonical_divisor(v::NormalToricVarietyType)\ncanonical_divisor(v::NormalToricVarietyType)","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/ToricDivisors/#trivial_divisor-Tuple{Union{AffineNormalToricVariety, CyclicQuotientSingularity, NormalToricVariety}}","page":"Toric Divisors","title":"trivial_divisor","text":"trivial_divisor(v::NormalToricVarietyType)\n\nConstruct the trivial divisor of a normal toric variety.\n\nExamples\n\njulia> v = projective_space(NormalToricVariety, 2)\nNormal toric variety\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{Union{AffineNormalToricVariety, CyclicQuotientSingularity, NormalToricVariety}}","page":"Toric Divisors","title":"anticanonical_divisor","text":"anticanonical_divisor(v::NormalToricVarietyType)\n\nConstruct the anticanonical divisor of a normal toric variety.\n\nExamples\n\njulia> v = projective_space(NormalToricVariety, 2)\nNormal toric variety\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{Union{AffineNormalToricVariety, CyclicQuotientSingularity, NormalToricVariety}}","page":"Toric Divisors","title":"canonical_divisor","text":"canonical_divisor(v::NormalToricVarietyType)\n\nConstruct the canonical divisor of a normal toric variety.\n\nExamples\n\njulia> v = projective_space(NormalToricVariety, 2)\nNormal toric variety\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 toric variety\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 toric variety\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 toric variety\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 toric variety\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 toric variety\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 toric variety\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 toric variety\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 toric variety\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 toric variety\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 toric variety\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 toric variety\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 [CLS11]. 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 toric variety\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 toric variety\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/ToricDivisors/","page":"Toric Divisors","title":"Toric Divisors","text":"The following attributes are supported by experimental code:","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/ToricDivisors/","page":"Toric Divisors","title":"Toric Divisors","text":"scheme(td::ToricDivisor)\nforget_toric_structure(td::ToricDivisor)","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/ToricDivisors/#scheme-Tuple{ToricDivisor}","page":"Toric Divisors","title":"scheme","text":"scheme(td::ToricDivisor)\n\nEvery toric divisor has an underlying scheme-theoretic Weil divisor. This method returns the scheme, on which said scheme-theoretic divisor is defined. In the case at hand, this is by design the toric variety at hand, which knows its underlying scheme. The latter can be accessed with the function underlying_toric_structure.\n\nExamples\n\njulia> P3 = projective_space(NormalToricVariety, 3)\nNormal toric variety\n\njulia> td = toric_divisor(P3, [0, 1, 0, 0])\nTorus-invariant, prime divisor on a normal toric variety\n\njulia> scheme(td)\nNormal toric variety\n\njulia> forget_toric_structure(scheme(td))\n(Scheme over QQ covered with 4 patches, Hom: scheme over QQ covered with 4 patches -> normal toric variety)\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/ToricDivisors/#forget_toric_structure-Tuple{ToricDivisor}","page":"Toric Divisors","title":"forget_toric_structure","text":"forget_toric_structure(td::ToricDivisor)\n\nEvery toric divisor has an underlying scheme-theoretic Weil divisor. This method returns said divisor.\n\nExamples\n\njulia> P3 = projective_space(NormalToricVariety, 3)\nNormal toric variety\n\njulia> td = toric_divisor(P3, [0, 1, 0, 0])\nTorus-invariant, prime divisor on a normal toric variety\n\njulia> forget_toric_structure(td)\nEffective weil divisor\n on normal, 3-dimensional toric variety\nwith coefficients in integer ring\ngiven as the formal sum of\n 1 * sheaf of ideals\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"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 [CLS11]:","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/AlgebraicCycles/","page":"The Chow ring","title":"The Chow ring","text":"By therorem 12.5.3 of [CLS11], 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 [CLS11]). 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 [CLS11], 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 [CLS11], 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::NormalToricVarietyType, p::MPolyQuoRingElem)\nrational_equivalence_class(v::NormalToricVarietyType, coefficients::Vector{T}) where {T <: IntegerUnion}","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/AlgebraicCycles/#rational_equivalence_class-Tuple{Union{AffineNormalToricVariety, CyclicQuotientSingularity, NormalToricVariety}, MPolyQuoRingElem}","page":"The Chow ring","title":"rational_equivalence_class","text":"rational_equivalence_class(v::NormalToricVarietyType, 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 toric variety\n\njulia> chow_ring(P2)\nQuotient\n of multivariate polynomial ring in 3 variables x1, x2, x3\n over rational field\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{Union{AffineNormalToricVariety, CyclicQuotientSingularity, NormalToricVariety}, Vector{T}}} where T<:Union{Integer, ZZRingElem}","page":"The Chow ring","title":"rational_equivalence_class","text":"rational_equivalence_class(v::NormalToricVarietyType, 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 toric variety\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/#toric_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 toric variety\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 toric variety\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 toric variety\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 toric variety\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. Special constructors). 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 toric variety\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, simplicial toric variety\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 toric variety\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 toric variety\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 generated by\n x1*x3\n x1*x5\n x2*x4\n x2*x5\n x3*x4\n x1 + x2 - x5\n 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 x1, x2, x3, x4, x5\n over rational field\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 toric variety\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 toric variety\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 toric variety\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 toric variety\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::NormalToricVarietyType)\ngens_of_rational_equivalence_classes(v::NormalToricVarietyType)\nmap_gens_of_chow_ring_to_cox_ring(v::NormalToricVarietyType)","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/AlgebraicCycles/#chow_ring-Tuple{Union{AffineNormalToricVariety, CyclicQuotientSingularity, NormalToricVariety}}","page":"The Chow ring","title":"chow_ring","text":"chow_ring(v::NormalToricVarietyType)\n\nReturn the Chow ring of the simplicial toric variety v.\n\nWhile [CLS11] focus on simplicial and complete varieties to define the Chow ring, it was described in [Peg14] 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 [FY04].\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(incidence_matrix([[1], [2], [3]]), [[1, 0], [0, 1], [-1, -1]])\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 x_{1}, x_{2}, x_{3}\n over rational field\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 x_{Edge(2, 1)}, x_{Edge(3, 1)}, x_{Edge(3, 2)}\n over rational field\n by ideal with 5 generators\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/AlgebraicCycles/#gens_of_rational_equivalence_classes-Tuple{Union{AffineNormalToricVariety, CyclicQuotientSingularity, NormalToricVariety}}","page":"The Chow ring","title":"gens_of_rational_equivalence_classes","text":"gens_of_rational_equivalence_classes(v::NormalToricVarietyType)\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 [CLS11]). 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{Union{AffineNormalToricVariety, CyclicQuotientSingularity, NormalToricVariety}}","page":"The Chow ring","title":"map_gens_of_chow_ring_to_cox_ring","text":"map_gens_of_chow_ring_to_cox_ring(v::NormalToricVarietyType)\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/LieAlgebras/cartan_matrix/","page":"Cartan Matrices","title":"Cartan Matrices","text":"CurrentModule = Oscar\nDocTestSetup = quote\nusing Oscar\nend","category":"page"},{"location":"Experimental/LieAlgebras/cartan_matrix/#Cartan-Matrices","page":"Cartan Matrices","title":"Cartan Matrices","text":"","category":"section"},{"location":"Experimental/LieAlgebras/cartan_matrix/","page":"Cartan Matrices","title":"Cartan Matrices","text":"cartan_matrix(::Symbol, ::Int)\ncartan_matrix(::Tuple{Symbol,Int}...)\nis_cartan_matrix(::ZZMatrix; generalized::Bool)\ncartan_symmetrizer(::ZZMatrix; check::Bool)\ncartan_bilinear_form(::ZZMatrix; check::Bool)\ncartan_type(::ZZMatrix; check::Bool)\ncartan_type_with_ordering(::ZZMatrix; check::Bool)","category":"page"},{"location":"Experimental/LieAlgebras/cartan_matrix/#cartan_matrix-Tuple{Symbol, Int64}","page":"Cartan Matrices","title":"cartan_matrix","text":"cartan_matrix(fam::Symbol, rk::Int) -> ZZMatrix\n\nReturn the Cartan matrix of finite type, where fam is the family (A, B, C, D, E, F G) and rk is the rank of the associated the root system; for B and C the rank has to be at least 2, for D at least 4. The convention is (a_ij) = (langle alpha_i^vee alpha_j rangle) for simple roots alpha_i.\n\nExample\n\njulia> cartan_matrix(:B, 2)\n[ 2 -1]\n[-2 2]\n\njulia> cartan_matrix(:C, 2)\n[ 2 -2]\n[-1 2]\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/cartan_matrix/#cartan_matrix-Tuple{Vararg{Tuple{Symbol, Int64}}}","page":"Cartan Matrices","title":"cartan_matrix","text":"cartan_matrix(type::Tuple{Symbol,Int}...) -> ZZMatrix\n\nReturn a block diagonal matrix of indecomposable Cartan matrices as defined by type. For allowed values see cartan_matrix(fam::Symbol, rk::Int).\n\nExample\n\njulia> cartan_matrix((:A, 2), (:B, 2))\n[ 2 -1 0 0]\n[-1 2 0 0]\n[ 0 0 2 -1]\n[ 0 0 -2 2]\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/cartan_matrix/#is_cartan_matrix-Tuple{ZZMatrix}","page":"Cartan Matrices","title":"is_cartan_matrix","text":"is_cartan_matrix(mat::ZZMatrix; generalized::Bool=true) -> Bool\n\nChecks if mat is a generalized Cartan matrix. The keyword argument generalized can be set to false to restrict this to Cartan matrices of finite type.\n\nExample\n\njulia> is_cartan_matrix(ZZ[2 -2; -2 2])\ntrue\n\njulia> is_cartan_matrix(ZZ[2 -2; -2 2]; generalized=false)\nfalse\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/cartan_matrix/#cartan_symmetrizer-Tuple{ZZMatrix}","page":"Cartan Matrices","title":"cartan_symmetrizer","text":"cartan_symmetrizer(gcm::ZZMatrix; check::Bool=true) -> Vector{ZZRingElem}\n\nReturn a vector d of coprime integers such that (d_i a_ij)_ij is a symmetric matrix, where a_ij are the entries of the Cartan matrix gcm. The keyword argument check can be set to false to skip verification whether gcm is indeed a generalized Cartan matrix.\n\nExample\n\njulia> cartan_symmetrizer(cartan_matrix(:B, 2))\n2-element Vector{ZZRingElem}:\n 2\n 1\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/cartan_matrix/#cartan_bilinear_form-Tuple{ZZMatrix}","page":"Cartan Matrices","title":"cartan_bilinear_form","text":"cartan_bilinear_form(gcm::ZZMatrix; check::Bool=true) -> ZZMatrix\n\nReturn the matrix of the symmetric bilinear form associated to the Cartan matrix from cartan_symmetrizer. The keyword argument check can be set to false to skip verification whether gcm is indeed a generalized Cartan matrix.\n\nExample\n\njulia> cartan_bilinear_form(cartan_matrix(:B, 2))\n[ 4 -2]\n[-2 2]\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/cartan_matrix/#cartan_type-Tuple{ZZMatrix}","page":"Cartan Matrices","title":"cartan_type","text":"cartan_type(gcm::ZZMatrix; check::Bool=true) -> Vector{Tuple{Symbol, Int}}\n\nReturn the Cartan type of a Cartan matrix gcm (currently only Cartan matrices of finite type are supported). This function is left inverse to cartan_matrix, i.e. in the case of isomorphic types (e.g. B_2 and C_2) the ordering of the roots does matter (see the example below). The keyword argument check can be set to false to skip verification whether gcm is indeed a Cartan matrix of finite type.\n\nThe order of returned components is, in general, not unique and might change between versions. If this function is called with the output of cartan_matrix(type), it will keep the order of type.\n\nExample\n\njulia> cartan_type(ZZ[2 -1; -2 2])\n1-element Vector{Tuple{Symbol, Int64}}:\n (:B, 2)\n\njulia> cartan_type(ZZ[2 -2; -1 2])\n1-element Vector{Tuple{Symbol, Int64}}:\n (:C, 2)\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/cartan_matrix/#cartan_type_with_ordering-Tuple{ZZMatrix}","page":"Cartan Matrices","title":"cartan_type_with_ordering","text":"cartan_type_with_ordering(gcm::ZZMatrix; check::Bool=true) -> Vector{Tuple{Symbol, Int}}, Vector{Int}\n\nReturn the Cartan type of a Cartan matrix gcm together with a vector indicating a canonical ordering of the roots in the Dynkin diagram (currently only Cartan matrices of finite type are supported). The keyword argument check can be set to false to skip verification whether gcm is indeed a Cartan matrix of finite type.\n\nThe order of returned components and the ordering is, in general, not unique and might change between versions. If this function is called with the output of cartan_matrix(type), it will keep the order of type and the returned ordering will be the identity.\n\nExample\n\njulia> cartan_type_with_ordering(cartan_matrix(:E, 6))\n([(:E, 6)], [1, 2, 3, 4, 5, 6])\n\njulia> cartan_type_with_ordering(ZZ[2 0 -1 0; 0 2 0 -2; -2 0 2 0; 0 -1 0 2])\n([(:B, 2), (:C, 2)], [1, 3, 2, 4])\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/number_fields/fields/#Number-field-operations","page":"Number field operations","title":"Number field operations","text":"","category":"section"},{"location":"Hecke/manual/number_fields/fields/","page":"Number field operations","title":"Number field operations","text":"CurrentModule = Hecke\nDocTestSetup = quote\n using Hecke\nend","category":"page"},{"location":"Hecke/manual/number_fields/fields/#Creation-of-number-fields","page":"Number field operations","title":"Creation of number fields","text":"","category":"section"},{"location":"Hecke/manual/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/manual/number_fields/fields/","page":"Number field operations","title":"Number field operations","text":"number_field(::DocuDummy)\nnumber_field(::DocuDummy2)","category":"page"},{"location":"Hecke/manual/number_fields/fields/#number_field-Tuple{Hecke.DocuDummy}","page":"Number field operations","title":"number_field","text":"number_field(f::Poly{NumFieldElem}, s::VarName;\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/manual/number_fields/fields/#number_field-Tuple{Hecke.DocuDummy2}","page":"Number field operations","title":"number_field","text":"number_field(f::Vector{PolyRingElem{<:NumFieldElem}}, s::VarName=\"_\\$\", 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, AbsNonSimpleNumFieldElem[a1, a2])\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/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/manual/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/manual/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/manual/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::Bool = 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/manual/number_fields/fields/#quadratic_field-Tuple{ZZRingElem}","page":"Number field operations","title":"quadratic_field","text":"quadratic_field(d::IntegerUnion) -> AbsSimpleNumField, AbsSimpleNumFieldElem\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/manual/number_fields/fields/#wildanger_field-Tuple{Int64, ZZRingElem}","page":"Number field operations","title":"wildanger_field","text":"wildanger_field(n::Int, B::ZZRingElem) -> AbsSimpleNumField, AbsSimpleNumFieldElem\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\n\n","category":"method"},{"location":"Hecke/manual/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/manual/number_fields/fields/#rationals_as_number_field-Tuple{}","page":"Number field operations","title":"rationals_as_number_field","text":"rationals_as_number_field() -> AbsSimpleNumField, AbsSimpleNumFieldElem\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\n\n","category":"method"},{"location":"Hecke/manual/number_fields/fields/#Basic-properties","page":"Number field operations","title":"Basic properties","text":"","category":"section"},{"location":"Hecke/manual/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/manual/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{AbsSimpleNumFieldElem}:\n 1\n a\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/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{AbsNonSimpleNumFieldElem}:\n 1\n a1\n a2\n a1*a2\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/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\n\n","category":"method"},{"location":"Hecke/manual/number_fields/fields/#defining_polynomial-Tuple{SimpleNumField}","page":"Number field operations","title":"defining_polynomial","text":"defining_polynomial(L::SimpleNumField) -> PolyRingElem\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/manual/number_fields/fields/#defining_polynomials-Tuple{NonSimpleNumField}","page":"Number field operations","title":"defining_polynomials","text":"defining_polynomials(L::NonSimpleNumField) -> Vector{PolyRingElem}\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/manual/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/manual/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/manual/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\n\n","category":"method"},{"location":"Hecke/manual/number_fields/fields/#Invariants","page":"Number field operations","title":"Invariants","text":"","category":"section"},{"location":"Hecke/manual/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(::AbsSimpleNumField)\nrelative_class_number(::AbsSimpleNumField)\nregulator(::AbsSimpleNumField)\ndiscriminant(::SimpleNumField)\nabsolute_discriminant(::SimpleNumField)","category":"page"},{"location":"Hecke/manual/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\n\n","category":"method"},{"location":"Hecke/manual/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\n\n","category":"method"},{"location":"Hecke/manual/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\n\n","category":"method"},{"location":"Hecke/manual/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/manual/number_fields/fields/#class_number-Tuple{AbsSimpleNumField}","page":"Number field operations","title":"class_number","text":"class_number(K::AbsSimpleNumField) -> ZZRingElem\n\nReturns the class number of K.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/number_fields/fields/#relative_class_number-Tuple{AbsSimpleNumField}","page":"Number field operations","title":"relative_class_number","text":"relative_class_number(K::AbsSimpleNumField) -> 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/manual/number_fields/fields/#regulator-Tuple{AbsSimpleNumField}","page":"Number field operations","title":"regulator","text":"regulator(K::AbsSimpleNumField)\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/manual/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/manual/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/manual/number_fields/fields/#Predicates","page":"Number field operations","title":"Predicates","text":"","category":"section"},{"location":"Hecke/manual/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(::AbsSimpleNumField, ::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem})\nis_tamely_ramified(::AbsSimpleNumField)\nis_tamely_ramified(::AbsSimpleNumField, p::Int)\nis_abelian(::NumField)","category":"page"},{"location":"Hecke/manual/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\n\n","category":"method"},{"location":"Hecke/manual/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\n\n","category":"method"},{"location":"Hecke/manual/number_fields/fields/#is_totally_real-Tuple{NumField}","page":"Number field operations","title":"is_totally_real","text":"is_totally_real(K::NumField) -> Bool\n\nReturn 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/manual/number_fields/fields/#is_totally_complex-Tuple{NumField}","page":"Number field operations","title":"is_totally_complex","text":"is_totally_complex(K::NumField) -> Bool\n\nReturn 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/manual/number_fields/fields/#is_cm_field-Tuple{NumField}","page":"Number field operations","title":"is_cm_field","text":"is_cm_field(K::AbsSimpleNumField) -> Bool, NumFieldHom{AbsSimpleNumField, AbsSimpleNumField}\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/manual/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/manual/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/manual/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/manual/number_fields/fields/#is_weakly_ramified-Tuple{AbsSimpleNumField, AbsSimpleNumFieldOrderIdeal}","page":"Number field operations","title":"is_weakly_ramified","text":"is_weakly_ramified(K::AbsSimpleNumField, P::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}) -> 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/manual/number_fields/fields/#is_tamely_ramified-Tuple{AbsSimpleNumField}","page":"Number field operations","title":"is_tamely_ramified","text":"is_tamely_ramified(K::AbsSimpleNumField) -> Bool\n\nReturns whether the number field K is tamely ramified.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/number_fields/fields/#is_tamely_ramified-Tuple{AbsSimpleNumField, Int64}","page":"Number field operations","title":"is_tamely_ramified","text":"is_tamely_ramified(O::AbsSimpleNumFieldOrder, 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/manual/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\n\n","category":"method"},{"location":"Hecke/manual/number_fields/fields/#Subfields","page":"Number field operations","title":"Subfields","text":"","category":"section"},{"location":"Hecke/manual/number_fields/fields/","page":"Number field operations","title":"Number field operations","text":"is_subfield(::SimpleNumField, ::SimpleNumField)\nsubfields(::SimpleNumField)\nprincipal_subfields(::SimpleNumField)\ncompositum(::AbsSimpleNumField, ::AbsSimpleNumField)\nembedding(::NumField, ::NumField)\nnormal_closure(::AbsSimpleNumField)\nrelative_simple_extension(::NumField, ::NumField)\nis_subfield_normal(::AbsSimpleNumField, ::AbsSimpleNumField)","category":"page"},{"location":"Hecke/manual/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/manual/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/manual/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\nExamples\n\njulia> Qx, x = QQ[\"x\"];\n\njulia> K, a = number_field(x^8 - x^4 + 1);\n\njulia> length(principal_subfields(K))\n8\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/number_fields/fields/#compositum-Tuple{AbsSimpleNumField, AbsSimpleNumField}","page":"Number field operations","title":"compositum","text":"compositum(K::AbsSimpleNumField, L::AbsSimpleNumField) -> AbsSimpleNumField, 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/manual/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/manual/number_fields/fields/#normal_closure-Tuple{AbsSimpleNumField}","page":"Number field operations","title":"normal_closure","text":"normal_closure(K::AbsSimpleNumField) -> AbsSimpleNumField, NumFieldHom{AbsSimpleNumField, AbsSimpleNumField}\n\nThe normal closure of K together with the embedding map.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/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) -> RelSimpleNumField\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/manual/number_fields/fields/#is_subfield_normal-Tuple{AbsSimpleNumField, AbsSimpleNumField}","page":"Number field operations","title":"is_subfield_normal","text":" is_subfield_normal(K::AbsSimpleNumField, L::AbsSimpleNumField) -> Bool, NumFieldHom{AbsSimpleNumField, AbsSimpleNumField}\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/manual/number_fields/fields/#Conversion","page":"Number field operations","title":"Conversion","text":"","category":"section"},{"location":"Hecke/manual/number_fields/fields/","page":"Number field operations","title":"Number field operations","text":"simplify(::AbsSimpleNumField)\nabsolute_simple_field(K::NumField)\nsimple_extension(::NonSimpleNumField)\nsimplified_simple_extension(::NonSimpleNumField)","category":"page"},{"location":"Hecke/manual/number_fields/fields/#simplify-Tuple{AbsSimpleNumField}","page":"Number field operations","title":"simplify","text":"simplify(K::AbsSimpleNumField; canonical::Bool = false) -> AbsSimpleNumField, NumFieldHom{AbsSimpleNumField, AbsSimpleNumField}\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/manual/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/manual/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/manual/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/manual/number_fields/fields/#Morphisms","page":"Number field operations","title":"Morphisms","text":"","category":"section"},{"location":"Hecke/manual/number_fields/fields/","page":"Number field operations","title":"Number field operations","text":"is_isomorphic(::SimpleNumField, ::SimpleNumField)\nis_isomorphic_with_map(::SimpleNumField, ::SimpleNumField)\nis_involution(::NumFieldHom{AbsSimpleNumField, AbsSimpleNumField})\nfixed_field(::NumFieldHom)\nautomorphism_list(::NumField)\nautomorphism_group(::AbsSimpleNumField)\ncomplex_conjugation(::AbsSimpleNumField)","category":"page"},{"location":"Hecke/manual/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/manual/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/manual/number_fields/fields/#is_involution-Tuple{NumFieldHom{AbsSimpleNumField, AbsSimpleNumField}}","page":"Number field operations","title":"is_involution","text":"is_involution(f::NumFieldHom{AbsSimpleNumField, AbsSimpleNumField}) -> 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/manual/number_fields/fields/#fixed_field-Tuple{NumFieldHom}","page":"Number field operations","title":"fixed_field","text":"fixed_field(K::SimpleNumField,\n sigma::Map;\n simplify::Bool = true) -> number_field, NumFieldHom{AbsSimpleNumField, AbsSimpleNumField}\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/manual/number_fields/fields/#automorphism_list-Tuple{NumField}","page":"Number field operations","title":"automorphism_list","text":"automorphism_list(L::NumField) -> Vector{NumFieldHom}\n\nGiven a number field LK, return a list of all K-automorphisms of L.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/number_fields/fields/#automorphism_group-Tuple{AbsSimpleNumField}","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/manual/number_fields/fields/#complex_conjugation-Tuple{AbsSimpleNumField}","page":"Number field operations","title":"complex_conjugation","text":"complex_conjugation(K::AbsSimpleNumField)\n\nGiven a 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/manual/number_fields/fields/#Galois-theory","page":"Number field operations","title":"Galois theory","text":"","category":"section"},{"location":"Hecke/manual/number_fields/fields/","page":"Number field operations","title":"Number field operations","text":"normal_basis(::NumField)\ndecomposition_group(::AbsSimpleNumField, ::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}, ::Map)\nramification_group(::AbsSimpleNumField, ::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}, ::Int, ::Map)\ninertia_subgroup(::AbsSimpleNumField, ::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}, ::Map)","category":"page"},{"location":"Hecke/manual/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\n\n","category":"method"},{"location":"Hecke/manual/number_fields/fields/#decomposition_group-Tuple{AbsSimpleNumField, AbsSimpleNumFieldOrderIdeal, Map}","page":"Number field operations","title":"decomposition_group","text":"decomposition_group(K::AbsSimpleNumField, P::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}, 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/manual/number_fields/fields/#ramification_group-Tuple{AbsSimpleNumField, AbsSimpleNumFieldOrderIdeal, Int64, Map}","page":"Number field operations","title":"ramification_group","text":"ramification_group(K::AbsSimpleNumField, P::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}, 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/manual/number_fields/fields/#inertia_subgroup-Tuple{AbsSimpleNumField, AbsSimpleNumFieldOrderIdeal, Map}","page":"Number field operations","title":"inertia_subgroup","text":"inertia_subgroup(K::AbsSimpleNumField, P::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}, 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/manual/number_fields/fields/#Infinite-places","page":"Number field operations","title":"Infinite places","text":"","category":"section"},{"location":"Hecke/manual/number_fields/fields/","page":"Number field operations","title":"Number field operations","text":"infinite_places(K::NumField)\nreal_places(K::AbsSimpleNumField)\ncomplex_places(K::AbsSimpleNumField)\nisreal(::Plc)\nis_complex(::Plc)","category":"page"},{"location":"Hecke/manual/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{AbsSimpleNumField, AbsSimpleNumFieldEmbedding}}:\n Infinite place corresponding to (Complex embedding corresponding to -2.24 of real quadratic field)\n Infinite place corresponding to (Complex embedding corresponding to 2.24 of real quadratic field)\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/number_fields/fields/#real_places-Tuple{AbsSimpleNumField}","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{AbsSimpleNumField, AbsSimpleNumFieldEmbedding}}:\n Infinite place corresponding to (Complex embedding corresponding to -2.24 of real quadratic field)\n Infinite place corresponding to (Complex embedding corresponding to 2.24 of real quadratic field)\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/number_fields/fields/#complex_places-Tuple{AbsSimpleNumField}","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{AbsSimpleNumField, AbsSimpleNumFieldEmbedding}}:\n Infinite place corresponding to (Complex embedding corresponding to 0.00 + 2.24 * i of imaginary quadratic field)\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/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\n\n","category":"method"},{"location":"Hecke/manual/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/manual/number_fields/fields/#Miscellaneous","page":"Number field operations","title":"Miscellaneous","text":"","category":"section"},{"location":"Hecke/manual/number_fields/fields/","page":"Number field operations","title":"Number field operations","text":"norm_equation(::AbsSimpleNumField, ::Any)\nlorenz_module(::AbsSimpleNumField, ::Int)\nkummer_failure(::AbsSimpleNumFieldElem, ::Int, ::Int)\nis_defining_polynomial_nice(::AbsSimpleNumField)","category":"page"},{"location":"Hecke/manual/number_fields/fields/#norm_equation-Tuple{AbsSimpleNumField, Any}","page":"Number field operations","title":"norm_equation","text":"norm_equation(K::AnticNumerField, a) -> AbsSimpleNumFieldElem\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/manual/number_fields/fields/#lorenz_module-Tuple{AbsSimpleNumField, Int64}","page":"Number field operations","title":"lorenz_module","text":"lorenz_module(k::AbsSimpleNumField, n::Int) -> AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}\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/manual/number_fields/fields/#kummer_failure-Tuple{AbsSimpleNumFieldElem, Int64, Int64}","page":"Number field operations","title":"kummer_failure","text":"kummer_failure(x::AbsSimpleNumFieldElem, 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/manual/number_fields/fields/#is_defining_polynomial_nice-Tuple{AbsSimpleNumField}","page":"Number field operations","title":"is_defining_polynomial_nice","text":"is_defining_polynomial_nice(K::AbsSimpleNumField)\n\nTests if the defining polynomial of K is integral and monic.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/RationalPointsProjective/","page":"Rational Points on Projective Schemes","title":"Rational Points on Projective Schemes","text":"CurrentModule = Oscar","category":"page"},{"location":"AlgebraicGeometry/Schemes/RationalPointsProjective/","page":"Rational Points on Projective Schemes","title":"Rational Points on Projective Schemes","text":"using Oscar","category":"page"},{"location":"AlgebraicGeometry/Schemes/RationalPointsProjective/#Rational-Points-on-Projective-Schemes","page":"Rational Points on Projective Schemes","title":"Rational Points on Projective Schemes","text":"","category":"section"},{"location":"AlgebraicGeometry/Schemes/RationalPointsProjective/","page":"Rational Points on Projective Schemes","title":"Rational Points on Projective Schemes","text":"AbsProjectiveRationalPoint\nProjectiveRationalPoint\ncoordinates(P::ProjectiveRationalPoint)\nideal(P::AbsProjectiveRationalPoint)\nscheme(P::ProjectiveRationalPoint)\nnormalize!(a::AbsProjectiveRationalPoint{<:FieldElem})\nnormalize!(a::AbsProjectiveRationalPoint{ZZRingElem})","category":"page"},{"location":"AlgebraicGeometry/Schemes/RationalPointsProjective/#AbsProjectiveRationalPoint","page":"Rational Points on Projective Schemes","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/Schemes/RationalPointsProjective/#ProjectiveRationalPoint","page":"Rational Points on Projective Schemes","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/Schemes/RationalPointsProjective/#coordinates-Tuple{Oscar.ProjectiveRationalPoint}","page":"Rational Points on Projective Schemes","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/Schemes/RationalPointsProjective/#ideal-Tuple{Oscar.AbsProjectiveRationalPoint}","page":"Rational Points on Projective Schemes","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\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/RationalPointsProjective/#scheme-Tuple{Oscar.ProjectiveRationalPoint}","page":"Rational Points on Projective Schemes","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/Schemes/RationalPointsProjective/#normalize!-Tuple{Oscar.AbsProjectiveRationalPoint{<:FieldElem}}","page":"Rational Points on Projective Schemes","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/Schemes/RationalPointsProjective/#normalize!-Tuple{Oscar.AbsProjectiveRationalPoint{ZZRingElem}}","page":"Rational Points on Projective Schemes","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":"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 [Wei10]–-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::NormalToricVariety; completeness_check::Bool = true)\nglobal_tate_model(base::NormalToricVariety, ais::Vector{T}; completeness_check::Bool = true) where {T<:MPolyRingElem}","category":"page"},{"location":"Experimental/FTheoryTools/tate/#global_tate_model-Tuple{NormalToricVariety}","page":"Global Tate models","title":"global_tate_model","text":"global_tate_model(base::NormalToricVariety; 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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/tate/#global_tate_model-Union{Tuple{T}, Tuple{NormalToricVariety, Vector{T}}} where T<:MPolyRingElem","page":"Global Tate models","title":"global_tate_model","text":"global_tate_model(base::NormalToricVariety, ais::Vector{T}; completeness_check::Bool = true) where {T<:MPolyRingElem}\n\nThis method operates analogously to global_tate_model(base::NormalToricVarietyType). 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 = generic_section(anticanonical_bundle(base));\n\njulia> a2 = generic_section(anticanonical_bundle(base)^2);\n\njulia> a3 = generic_section(anticanonical_bundle(base)^3);\n\njulia> a4 = generic_section(anticanonical_bundle(base)^4);\n\njulia> a6 = generic_section(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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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 serves as coordinate ring for the family of base spaces. 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 code 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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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)\ntate_ideal_sheaf(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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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)\nw*a21\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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)\nw^2*a32\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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)\nw^3*a43\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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\nFor convenience and uniformity with (general) hypersurface models, we also support the method hypersurface_equation to access the Tate polynomial.\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)\nw^3*a43*x*z^4 - w^2*a32*y*z^3 + w*a21*x^2*z^2 - a1*x*y*z + x^3 - y^2\n\njulia> tate_polynomial(t) == hypersurface_equation(t)\ntrue\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/tate/#tate_ideal_sheaf-Tuple{GlobalTateModel}","page":"Global Tate models","title":"tate_ideal_sheaf","text":"tate_ideal_sheaf(t::GlobalTateModel)\n\nReturn the Tate ideal sheaf of the global Tate model.\n\njulia> B3 = projective_space(NormalToricVariety, 3)\nNormal toric variety\n\njulia> w = 2 * torusinvariant_prime_divisors(B3)[1]\nTorus-invariant, non-prime divisor on a normal toric variety\n\njulia> t = literature_model(arxiv_id = \"1109.3454\", equation = \"3.1\", base_space = B3, defining_classes = Dict(\"w\" => w), completeness_check = false)\nConstruction over concrete base may lead to singularity enhancement. Consider computing singular_loci. However, this may take time!\n\nGlobal Tate model over a concrete base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)\n\njulia> tate_ideal_sheaf(t)\nSheaf of ideals\n on normal, simplicial toric variety\nwith restrictions\n 1: Ideal with 1 generator\n 2: Ideal with 1 generator\n 3: Ideal with 1 generator\n 4: Ideal with 1 generator\n 5: Ideal with 3 generators\n 6: Ideal with 3 generators\n 7: Ideal with 3 generators\n 8: Ideal with 3 generators\n 9: Ideal with 4 generators\n 10: Ideal with 4 generators\n 11: Ideal with 4 generators\n 12: Ideal with 4 generators\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/tate/","page":"Global Tate models","title":"Global Tate models","text":"The base space can be obtained with base_space, the ambient space with ambient_space and the fiber ambient space with fiber_ambient_space. Recall that is_base_space_fully_specified will tell if the model has been constructed over a concrete space (in which case the function returns true) or a family of spaces (returning false).","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 = global_tate_model(sample_toric_variety(); completeness_check = false)\nGlobal Tate model over a concrete base\n\njulia> calabi_yau_hypersurface(t)\nClosed subvariety of a normal toric variety\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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 -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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. [Wei18] 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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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 [CLS11], 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 [KMSS11]. 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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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/#Blowup","page":"Global Tate models","title":"Blowup","text":"","category":"section"},{"location":"Experimental/FTheoryTools/tate/","page":"Global Tate models","title":"Global Tate models","text":"We can blow up a global Tate model with the blow_up function. The resulting model will thereafter be partially resolved. No checks are currently implemented to test if a model is completely resolved. However, is_partially_resolved will return true if a blowup has been applied to the model in question.","category":"page"},{"location":"Experimental/FTheoryTools/tate/#Tuning","page":"Global Tate models","title":"Tuning","text":"","category":"section"},{"location":"Experimental/FTheoryTools/tate/","page":"Global Tate models","title":"Global Tate models","text":"Often, one wishes to tune an existing model, e.g. in an attempt to engineer a larger gauge group. We support the following functionality:","category":"page"},{"location":"Experimental/FTheoryTools/tate/","page":"Global Tate models","title":"Global Tate models","text":"tune(t::GlobalTateModel, special_ai_choices::Dict{String, <:Any}; completeness_check::Bool = true)","category":"page"},{"location":"Experimental/FTheoryTools/tate/#tune-Tuple{GlobalTateModel, Dict{String}}","page":"Global Tate models","title":"tune","text":"tune(t::GlobalTateModel, input_sections::Dict{String, <:Any}; completeness_check::Bool = true)\n\nTune a Tate model by fixing a special choice for the model sections. Note that it is in particular possible to set a section to zero. We anticipate that people might want to be able to come back from this by assigning a non-trivial value to a section that was previously tuned to zero. This is why we keep such trivial sections and do not delete them, say from explicit_model_sections or classes_of_model_sections.\n\nExamples\n\njulia> B3 = projective_space(NormalToricVariety, 3)\nNormal toric variety\n\njulia> w = torusinvariant_prime_divisors(B3)[1]\nTorus-invariant, prime divisor on a normal toric variety\n\njulia> t = literature_model(arxiv_id = \"1109.3454\", equation = \"3.1\", base_space = B3, defining_classes = Dict(\"w\" => w), completeness_check = false)\nConstruction over concrete base may lead to singularity enhancement. Consider computing singular_loci. However, this may take time!\n\nGlobal Tate model over a concrete base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)\n\njulia> x1, x2, x3, x4 = gens(cox_ring(base_space(t)))\n4-element Vector{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}:\n x1\n x2\n x3\n x4\n\njulia> my_choice = Dict(\"a1\" => x1^4, \"a2\" => x1^8, \"w\" => x2 - x3)\nDict{String, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}} with 3 entries:\n \"w\" => x2 - x3\n \"a2\" => x1^8\n \"a1\" => x1^4\n\njulia> tuned_t = tune(t, my_choice)\nGlobal Tate model over a concrete base\n\njulia> tate_section_a1(tuned_t) == x1^4\ntrue\n\njulia> x1, x2, x3, x4 = gens(cox_ring(base_space(tuned_t)))\n4-element Vector{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}:\n x1\n x2\n x3\n x4\n\njulia> my_choice2 = Dict(\"a1\" => x1^4, \"a2\" => zero(parent(x1)), \"w\" => x2 - x3)\nDict{String, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}} with 3 entries:\n \"w\" => x2 - x3\n \"a2\" => 0\n \"a1\" => x1^4\n\njulia> tuned_t2 = tune(tuned_t, my_choice2)\nGlobal Tate model over a concrete base\n\njulia> is_zero(explicit_model_sections(tuned_t2)[\"a2\"])\ntrue\n\njulia> x1, x2, x3, x4 = gens(cox_ring(base_space(tuned_t2)))\n4-element Vector{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}:\n x1\n x2\n x3\n x4\n\njulia> my_choice3 = Dict(\"a1\" => x1^4, \"a2\" => x1^8, \"w\" => x2 - x3)\nDict{String, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}} with 3 entries:\n \"w\" => x2 - x3\n \"a2\" => x1^8\n \"a1\" => x1^4\n\njulia> tuned_t3 = tune(tuned_t2, my_choice3)\nGlobal Tate model over a concrete base\n\njulia> is_zero(explicit_model_sections(tuned_t3)[\"a2\"])\nfalse\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/tate/","page":"Global Tate models","title":"Global Tate models","text":"See also the tune function described in Functionality for all F-theory models.","category":"page"},{"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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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 number_field function.","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) AbsSimpleNumFieldElem AbsSimpleNumField","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\nExamples\n\njulia> R, x = polynomial_ring(QQ, \"x\");\n\njulia> K, a = number_field(x^3 + 3x + 1, \"a\")\n(Number field of degree 3 over QQ, a)\n\njulia> K\nNumber field with defining polynomial x^3 + 3*x + 1\n over rational field\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::Bool = 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":"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> L, b = cyclotomic_field(5, \"b\")\n(Cyclotomic field of order 5, b)\n\njulia> M, c = cyclotomic_real_subfield(5, \"c\")\n(Maximal real subfield of cyclotomic field of order 5, c)\n\njulia> d = K(3)\n3\n\njulia> f = L(b)\nb\n\njulia> g = L(ZZ(11))\n11\n\njulia> h = L(ZZ(11)//3)\n11//3\n\njulia> k = M(x)\nc","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(::AbsSimpleNumField)","category":"page"},{"location":"Nemo/numberfield/#gen-Tuple{AbsSimpleNumField}","page":"Number field arithmetic","title":"gen","text":"gen(a::AbsSimpleNumField)\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":"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> d = gen(K)\na\n\njulia> f = a^2 + 2a - 7\na^2 + 2*a - 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!(::AbsSimpleNumFieldElem, ::AbsSimpleNumFieldElem, ::AbsSimpleNumFieldElem, ::Bool)","category":"page"},{"location":"Nemo/numberfield/#mul_red!-Tuple{AbsSimpleNumFieldElem, AbsSimpleNumFieldElem, AbsSimpleNumFieldElem, Bool}","page":"Number field arithmetic","title":"mul_red!","text":"mul_red!(z::AbsSimpleNumFieldElem, x::AbsSimpleNumFieldElem, y::AbsSimpleNumFieldElem, 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!(::AbsSimpleNumFieldElem)","category":"page"},{"location":"Nemo/numberfield/#reduce!-Tuple{AbsSimpleNumFieldElem}","page":"Number field arithmetic","title":"reduce!","text":"reduce!(x::AbsSimpleNumFieldElem)\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::AbsSimpleNumFieldElem)","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":"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> f = R(a^2 + 2a + 3)\nx^2 + 2*x + 3\n\njulia> g = K(x^2 + 2x + 1)\na^2 + 2*a + 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(::AbsSimpleNumField)","category":"page"},{"location":"Nemo/numberfield/#var-Tuple{AbsSimpleNumField}","page":"Number field arithmetic","title":"var","text":"var(a::AbsSimpleNumField)\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(::AbsSimpleNumFieldElem)","category":"page"},{"location":"Nemo/numberfield/#is_gen-Tuple{AbsSimpleNumFieldElem}","page":"Number field arithmetic","title":"is_gen","text":"is_gen(a::AbsSimpleNumFieldElem)\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(::AbsSimpleNumFieldElem, ::Int)","category":"page"},{"location":"Nemo/numberfield/#coeff-Tuple{AbsSimpleNumFieldElem, Int64}","page":"Number field arithmetic","title":"coeff","text":"coeff(x::AbsSimpleNumFieldElem, 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(::AbsSimpleNumFieldElem)","category":"page"},{"location":"Nemo/numberfield/#denominator-Tuple{AbsSimpleNumFieldElem}","page":"Number field arithmetic","title":"denominator","text":"denominator(a::AbsSimpleNumFieldElem)\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(::AbsSimpleNumField)","category":"page"},{"location":"Nemo/numberfield/#degree-Tuple{AbsSimpleNumField}","page":"Number field arithmetic","title":"degree","text":"degree(a::AbsSimpleNumField)\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":"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> d = a^2 + 2a - 7\na^2 + 2*a - 7\n\njulia> m = gen(K)\na\n\njulia> c = coeff(d, 1)\n2\n\njulia> is_gen(m)\ntrue\n\njulia> q = degree(K)\n3","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(::AbsSimpleNumFieldElem)","category":"page"},{"location":"Nemo/numberfield/#norm-Tuple{AbsSimpleNumFieldElem}","page":"Number field arithmetic","title":"norm","text":"norm(a::AbsSimpleNumFieldElem)\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(::AbsSimpleNumFieldElem)","category":"page"},{"location":"Nemo/numberfield/#tr-Tuple{AbsSimpleNumFieldElem}","page":"Number field arithmetic","title":"tr","text":"tr(a::AbsSimpleNumFieldElem)\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":"Combinatorics/phylogenetic_trees/","page":"Phylogenetic Trees","title":"Phylogenetic Trees","text":"CurrentModule = Oscar","category":"page"},{"location":"Combinatorics/phylogenetic_trees/#Phylogenetic-Trees","page":"Phylogenetic Trees","title":"Phylogenetic Trees","text":"","category":"section"},{"location":"Combinatorics/phylogenetic_trees/#Introduction","page":"Phylogenetic Trees","title":"Introduction","text":"","category":"section"},{"location":"Combinatorics/phylogenetic_trees/","page":"Phylogenetic Trees","title":"Phylogenetic Trees","text":"Phylogenetic trees represent the evolutionary history of some species of consideration. Here we consider phylogenetic trees with branch lengths as defined in [SS03].","category":"page"},{"location":"Combinatorics/phylogenetic_trees/#Construction","page":"Phylogenetic Trees","title":"Construction","text":"","category":"section"},{"location":"Combinatorics/phylogenetic_trees/","page":"Phylogenetic Trees","title":"Phylogenetic Trees","text":"phylogenetic_tree","category":"page"},{"location":"Combinatorics/phylogenetic_trees/#phylogenetic_tree","page":"Phylogenetic Trees","title":"phylogenetic_tree","text":"phylogenetic_tree(T::Type{<:Union{Float64, QQFieldElem}}, newick::String)\n\nConstructs a rooted phylogenetic tree with Newick representation newick. T indicates the numerical type of the edge lengths.\n\nExamples\n\nMake a phylogenetic tree with 4 leaves from its Newick representation and print its taxa and cophenetic matrix.\n\njulia> phylo_t = phylogenetic_tree(Float64, \"((H:3,(C:1,B:1):2):1,G:4);\");\n\njulia> taxa(phylo_t)\n4-element Vector{String}:\n \"B\"\n \"C\"\n \"G\"\n \"H\"\n\njulia> cophenetic_matrix(phylo_t)\n4×4 Matrix{Float64}:\n 0.0 2.0 8.0 6.0\n 2.0 0.0 8.0 6.0\n 8.0 8.0 0.0 8.0\n 6.0 6.0 8.0 0.0\n\n\n\n\n\nphylogenetic_tree(M::Matrix{T}, taxa::Vector{String}) where T <: Union{Float64, QQFieldElem}\n\nConstructs a phylogenetic tree with cophenetic matrix M and taxa taxa. The matrix M must be ultrametric, otherwise an error will be thrown.\n\nExamples\n\nMake a phylogenetic tree on 4 taxa with given cophenetic matrix and print one Newick representation.\n\njulia> mat = [0. 2 8 6; 2 0 8 6; 8 8 0 8; 6 6 8 0]\n4×4 Matrix{Float64}:\n 0.0 2.0 8.0 6.0\n 2.0 0.0 8.0 6.0\n 8.0 8.0 0.0 8.0\n 6.0 6.0 8.0 0.0\n\njulia> tax = [\"Bonobo\", \"Chimpanzee\", \"Gorilla\", \"Human\"]\n4-element Vector{String}:\n \"Bonobo\"\n \"Chimpanzee\"\n \"Gorilla\"\n \"Human\"\n\njulia> tree_mat = phylogenetic_tree(mat, tax);\n\njulia> newick(tree_mat)\n\"Gorilla:4,(Human:3,(Bonobo:1,Chimpanzee:1):2):1;\"\n\n\n\n\n\n","category":"function"},{"location":"Combinatorics/phylogenetic_trees/#Some-Helpful-Functions","page":"Phylogenetic Trees","title":"Some Helpful Functions","text":"","category":"section"},{"location":"Combinatorics/phylogenetic_trees/","page":"Phylogenetic Trees","title":"Phylogenetic Trees","text":"adjacency_tree\nis_equidistant\ncophenetic_matrix\ntaxa\nnewick\ntropical_median_consensus","category":"page"},{"location":"Combinatorics/phylogenetic_trees/#adjacency_tree","page":"Phylogenetic Trees","title":"adjacency_tree","text":"adjacency_tree(ptree::PhylogeneticTree)\n\nReturns the underlying graph of the phylogenetic tree ptree.\n\nExamples\n\nMake a phylogenetic tree with given Newick format and print its underlying graph.\n\njulia> ptree = phylogenetic_tree(Float64, \"((H:3,(C:1,B:1):2):1,G:4);\");\n\njulia> adjacency_tree(ptree)\nDirected graph with 7 nodes and the following edges:\n(1, 2)(1, 7)(2, 3)(2, 4)(4, 5)(4, 6)\n\n\n\n\n\n","category":"function"},{"location":"Combinatorics/phylogenetic_trees/#is_equidistant","page":"Phylogenetic Trees","title":"is_equidistant","text":"is_equidistant(ptree::PhylogeneticTree)\n\nChecks if the phylogenetic tree ptree is equidistant.\n\nExamples\n\nMake a phylogenetic tree with given Newick format and check if it is equidistant.\n\njulia> ptree = phylogenetic_tree(Float64, \"((H:3,(C:1,B:1):2):1,G:4);\");\n\njulia> is_equidistant(ptree)\ntrue\n\n\n\n\n\n","category":"function"},{"location":"Combinatorics/phylogenetic_trees/#cophenetic_matrix","page":"Phylogenetic Trees","title":"cophenetic_matrix","text":"cophenetic_matrix(ptree::PhylogeneticTree)\n\nReturns the cophenetic matrix of the phylogenetic tree ptree.\n\nExamples\n\nMake a phylogenetic tree with given Newick format and print its cophenetic matrix.\n\njulia> ptree = phylogenetic_tree(Float64, \"((H:3,(C:1,B:1):2):1,G:4);\");\n\njulia> cophenetic_matrix(ptree)\n4×4 Matrix{Float64}:\n 0.0 2.0 8.0 6.0\n 2.0 0.0 8.0 6.0\n 8.0 8.0 0.0 8.0\n 6.0 6.0 8.0 0.0\n\n\n\n\n\n","category":"function"},{"location":"Combinatorics/phylogenetic_trees/#taxa","page":"Phylogenetic Trees","title":"taxa","text":"taxa(ptree::PhylogeneticTree)\n\nReturns the taxa of the phylogenetic tree ptree.\n\nExamples\n\nMake a phylogenetic tree with given Newick format and print its taxa.\n\njulia> ptree = phylogenetic_tree(Float64, \"((H:3,(C:1,B:1):2):1,G:4);\");\n\njulia> taxa(ptree)\n4-element Vector{String}:\n \"B\"\n \"C\"\n \"G\"\n \"H\"\n\n\n\n\n\n","category":"function"},{"location":"Combinatorics/phylogenetic_trees/#newick","page":"Phylogenetic Trees","title":"newick","text":"newick(ptree::PhylogeneticTree)\n\nReturns a Newick representation of the phylogenetic tree ptree.\n\nExamples\n\nMake a phylogenetic tree from a matrix and print a Newick representation of it.\n\njulia> mat = [0. 2 8 6; 2 0 8 6; 8 8 0 8; 6 6 8 0]\n4×4 Matrix{Float64}:\n 0.0 2.0 8.0 6.0\n 2.0 0.0 8.0 6.0\n 8.0 8.0 0.0 8.0\n 6.0 6.0 8.0 0.0\n\njulia> tax = [\"Bonobo\", \"Chimpanzee\", \"Gorilla\", \"Human\"]\n4-element Vector{String}:\n \"Bonobo\"\n \"Chimpanzee\"\n \"Gorilla\"\n \"Human\"\n\njulia> tree_mat = phylogenetic_tree(mat, tax);\n\njulia> newick(tree_mat)\n\"Gorilla:4,(Human:3,(Bonobo:1,Chimpanzee:1):2):1;\"\n\n\n\n\n\n","category":"function"},{"location":"Combinatorics/phylogenetic_trees/#tropical_median_consensus","page":"Phylogenetic Trees","title":"tropical_median_consensus","text":"tropical_median_consensus(arr::Vector{PhylogeneticTree{T}})\n\nComputes the tropical median consensus tree of the phylogenetic trees from the vector arr.\n\nExamples\n\nCompute the tropical median consensus of three trees and print one of its Newick representations.\n\njulia> t1 = phylogenetic_tree(Float64, \"((H:30,(C:10,B:10):20):10,G:40);\");\n\njulia> t2 = phylogenetic_tree(Float64, \"(((H:10,C:10):20,B:30):10,G:40);\");\n\njulia> t3 = phylogenetic_tree(Float64, \"((H:25,C:25):15,(B:15,G:15):25);\");\n\njulia> arr = [t1, t2, t3];\n\njulia> tc = tropical_median_consensus(arr);\n\njulia> newick(tc)\n\"G:40,(B:35,(C:30,H:30):5):5;\"\n\n\n\n\n\ntropical_median_consensus(trees::Vararg{PhylogeneticTree, N}) where {N}\n\nComputes the tropical median consensus tree of any number of phylogenetic trees given as parameters.\n\nExamples\n\nCompute the tropical median consensus of three trees and print one of its Newick representations.\n\njulia> t1 = phylogenetic_tree(Float64, \"((H:30,(C:10,B:10):20):10,G:40);\");\n\njulia> t2 = phylogenetic_tree(Float64, \"(((H:10,C:10):20,B:30):10,G:40);\");\n\njulia> t3 = phylogenetic_tree(Float64, \"((H:25,C:25):15,(B:15,G:15):25);\");\n\njulia> tc = tropical_median_consensus(t1, t2, t3);\n\njulia> newick(tc)\n\"G:40,(B:35,(C:30,H:30):5):5;\"\n\n\n\n\n\n","category":"function"},{"location":"Experimental/StandardFiniteFields/introduction/","page":"-","title":"-","text":"CurrentModule = Oscar\nDocTestSetup = Oscar.doctestsetup()","category":"page"},{"location":"Experimental/StandardFiniteFields/introduction/","page":"-","title":"-","text":"standard_finite_field(p::IntegerUnion, n::IntegerUnion)","category":"page"},{"location":"Experimental/StandardFiniteFields/introduction/#standard_finite_field-Tuple{Union{Integer, ZZRingElem}, Union{Integer, ZZRingElem}}","page":"-","title":"standard_finite_field","text":"standard_finite_field(p::Union{ZZRingElem, Integer}, n::Union{ZZRingElem, Integer}) -> FinField\n\nReturn a finite field of order p^n.\n\nExamples\n\njulia> standard_finite_field(3, 24)\nFinite field of degree 24 over GF(3)\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"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":"universal_polynomial_ring","category":"page"},{"location":"AbstractAlgebra/univpolynomial/#universal_polynomial_ring","page":"Universal polynomial","title":"universal_polynomial_ring","text":"universal_polynomial_ring(R::Ring; cached::Bool=true, internal_ordering::Symbol=:lex)\n\nGiven a base ring R, return an object representing the universal polynomial ring S = Rldots with no variables in it initially.\n\nExamples\n\njulia> S = universal_polynomial_ring(ZZ)\nUniversal Polynomial Ring over Integers\n\njulia> x = gen(S, :x)\nx\n\njulia> y, z = gens(S, [:y, :z])\n(y, z)\n\njulia> x*y - z\nx*y - z\n\n\n\n\n\n","category":"function"},{"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 = universal_polynomial_ring(ZZ)\nUniversal Polynomial Ring over Integers\n\njulia> x = gen(S, :x)\nx\n\njulia> number_of_generators(S)\n1\n\njulia> y, z = gens(S, [:y, :z])\n(y, z)\n\njulia> number_of_generators(S)\n3","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 = Oscar.doctestsetup()","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 has_preimage_with_preimage(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(T::TorQuadModule) -> TorQuadModuleMap\n\nAlias for identity_map.\n\n\n\n\n\nid_hom(G::GAPGroup)\n\nReturn the identity homomorphism on the group G.\n\n\n\n\n\n","category":"function"},{"location":"Groups/grouphom/#trivial_morphism","page":"Group homomorphisms","title":"trivial_morphism","text":"trivial_morphism(T::TorQuadModule, U::TorQuadModule) -> TorQuadModuleMap\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) -> TorQuadModuleMap\n\nReturn the abelian group endomorphism of T sending every elements of T to the zero element of T.\n\n\n\n\n\ntrivial_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\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":"has_preimage_with_preimage(f::GAPGroupHomomorphism, x::GAPGroupElem; check::Bool = true)","category":"page"},{"location":"Groups/grouphom/#has_preimage_with_preimage-Tuple{GAPGroupHomomorphism, GAPGroupElem}","page":"Group homomorphisms","title":"has_preimage_with_preimage","text":"has_preimage_with_preimage(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> has_preimage_with_preimage(f,x)\n(true, (1,4))","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::GAPGroup)\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::GAPGroup) 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":"For all functions that return group isomorphisms, we have the following rule about the direction of the result.","category":"page"},{"location":"Groups/grouphom/","page":"Group homomorphisms","title":"Group homomorphisms","text":"If two groups are given as inputs then the domain of the returned isomorphism is the first given group and the codomain is the second.","category":"page"},{"location":"Groups/grouphom/","page":"Group homomorphisms","title":"Group homomorphisms","text":"If one group is given then the domain of the result is this group, and the codomain is some new group constructed by the function.","category":"page"},{"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, Hom: Sym(3) -> pc group)\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\n from Sym(3)\n to pc group of order 6\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{SubPcGroup, PermGroup}\nisomorphism(::Type{FinGenAbGroup}, G::GAPGroup)\nsimplified_fp_group(G::FPGroup)","category":"page"},{"location":"Groups/grouphom/#isomorphism-Union{Tuple{T}, Tuple{Type{T}, Oscar.GAPGroup}} where T<:Union{PermGroup, SubPcGroup}","page":"Group homomorphisms","title":"isomorphism","text":"isomorphism(::Type{T}, G::GAPGroup) where T <: Union{SubPcGroup, SubFPGroup, PermGroup}\nisomorphism(::Type{T}, G::GAPGroup; on_gens=false) where T <: Union{PcGroup, FPGroup}\n\nReturn an isomorphism from G to a group H of type T. An exception is thrown if no such isomorphism exists.\n\nIf on_gens is true then gens(G) is guaranteed to correspond to gens(H); an exception is thrown if this is not possible.\n\nIsomorphisms are cached in G, subsequent calls of isomorphism with the same T (and the same value of on_gens) 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)\nPc group of order 6\n\njulia> iso = isomorphism(PermGroup, G)\nGroup homomorphism\n from pc group of order 6\n to permutation group of degree 3 and order 6\n\njulia> permutation_group(G)\nPermutation group of degree 3 and order 6\n\njulia> codomain(iso) === ans\ntrue\n\n\n\n\n\n","category":"method"},{"location":"Groups/grouphom/#isomorphism-Tuple{Type{FinGenAbGroup}, Oscar.GAPGroup}","page":"Group homomorphisms","title":"isomorphism","text":"isomorphism(::Type{FinGenAbGroup}, G::GAPGroup)\n\nReturn a map from G to an isomorphic (additive) group of type FinGenAbGroup. 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)\nFree group of rank 3\n\njulia> G = quo(F, [gen(F,1)])[1]\nFinitely presented group of infinite order\n\njulia> simplified_fp_group(G)[1]\nFinitely presented group of infinite order\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\n from free group of rank 2\n to Sym(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 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 neighborhood 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":"[GLS07]\n[JP00]","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":"[Har77].","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::AbsAffineScheme, 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::AbsAffineScheme, 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":"Hecke/manual/developer/documentation/#Documentation","page":"Documentation","title":"Documentation","text":"","category":"section"},{"location":"Hecke/manual/developer/documentation/","page":"Documentation","title":"Documentation","text":"The files for the documentation are located in the docs/src/manual/ directory.","category":"page"},{"location":"Hecke/manual/developer/documentation/#Adding-files-to-the-documentation","page":"Documentation","title":"Adding files to the documentation","text":"","category":"section"},{"location":"Hecke/manual/developer/documentation/","page":"Documentation","title":"Documentation","text":"To add files to the documentation edit directly the file docs/src/.vitepress/config.mts.","category":"page"},{"location":"Hecke/manual/developer/documentation/#Building-the-documentation","page":"Documentation","title":"Building the documentation","text":"","category":"section"},{"location":"Hecke/manual/developer/documentation/","page":"Documentation","title":"Documentation","text":"Run julia and execute (with Hecke developed in your current environment)","category":"page"},{"location":"Hecke/manual/developer/documentation/","page":"Documentation","title":"Documentation","text":"julia> using Hecke\n\njulia> Hecke.build_doc() # or Hecke.build_doc(;doctest = false) to speed things up","category":"page"},{"location":"Hecke/manual/developer/documentation/","page":"Documentation","title":"Documentation","text":"In the terminal, navigate to docs/ and run","category":"page"},{"location":"Hecke/manual/developer/documentation/","page":"Documentation","title":"Documentation","text":"Hecke/docs> npm run docs:build","category":"page"},{"location":"Hecke/manual/developer/documentation/","page":"Documentation","title":"Documentation","text":"(This step takes place outside of julia.)","category":"page"},{"location":"Hecke/manual/developer/documentation/","page":"Documentation","title":"Documentation","text":"note: Note\nTo speed up the development process, step 1 can be repeated within the same julia session.","category":"page"},{"location":"NumberTheory/galois/","page":"Galois Theory","title":"Galois Theory","text":"CurrentModule = Oscar\nDocTestSetup = Oscar.doctestsetup()","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 (AbsSimpleNumField)\nK a simple extension of an AbsSimpleNumField \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 AbsSimpleNumField","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 specialized 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.NumFieldHom)\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_verbosity_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_verbosity_level(:GaloisGroup, n::Int)\nset_verbosity_level(:GaloisInvariants, n::Int)","category":"page"},{"location":"NumberTheory/galois/","page":"Galois Theory","title":"Galois Theory","text":"galois_group(K::AbsSimpleNumField, 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::AbsSimpleNumField, 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(Permutation group of degree 4 and order 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{QadicFieldElem}:\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\"Galois context\\(.*\\]\\)\"","category":"page"},{"location":"NumberTheory/galois/","page":"Galois Theory","title":"Galois Theory","text":"julia> Qt, t = rational_function_field(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 QQ 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 QQ with defining polynomial a^2 + 108*t^2 + 108*t + 27, _a^3)\n (Function Field over QQ with defining polynomial a^3 - 108*t^2 - 108*t - 27, -_a^2)\n (Function Field over QQ 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(Permutation group of degree 6 and order 6, Galois context for s^6 + 108*t^2 + 540*t + 675)\n\njulia> G, C, k = galois_group(F, overC = true)\n(Permutation group of degree 6 and order 3, 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(Permutation group of degree 4 and order 4, Galois context for x^4 - 5*x^2 + 6 and prime 11)\n\njulia> r = roots(C, 5)\n4-element Vector{QadicFieldElem}:\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 (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 (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\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 = rational_function_field(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(Permutation group of degree 6 and order 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 generated by\n x4^4 - 2\n x3^3 + x3^2*x4 + x3*x4^2 + x4^3\n x2^2 + x2*x3 + x2*x4 + x3^2 + x3*x4 + x4^2\n x1 + x2 + x3 + x4\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 generated by\n x4^4 - 2\n x3^3 + x3^2*x4 + x3*x4^2 + x4^3\n x2^2 + x2*x3 + x2*x4 + x3^2 + x3*x4 + x4^2\n x1 + x2 + x3 + x4\n x1*x3 + x2*x4\n x1^2*x3^2 + x2^2*x4^2 - 4\n x1^4 - 2\n x2^4 - 2\n x3^4 - 2\n x4^4 - 2\n\njulia> k, _ = number_field(i);\n\njulia> length(roots(k, x^4-2))\n4\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_verbosity_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.RelSimpleNumFieldElem{Hecke.RelSimpleNumFieldElem{AbsSimpleNumFieldElem}}}:\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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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(3), Galois context for x^3 - 3*x + 17 and prime 7)\n\njulia> d = derived_series(G)\n3-element Vector{PermGroup}:\n Sym(3)\n Alt(3)\n Permutation group of degree 3 and order 1\n\njulia> fixed_field(C, d)\n(Relative number field of degree 3 over number field, a2)\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"DeveloperDocumentation/release/#Release-management","page":"Release management","title":"Release management","text":"","category":"section"},{"location":"DeveloperDocumentation/release/","page":"Release management","title":"Release management","text":"We roughly follow the julia release process. The following outlines the approach taken for OSCAR 1.0.0 but is subject to change depending in how this works out.","category":"page"},{"location":"DeveloperDocumentation/release/","page":"Release management","title":"Release management","text":"Before preparing the release branch two developers are chosen to take care of managing the branches and taking final decisions on which changes can be merged during the release process.","category":"page"},{"location":"DeveloperDocumentation/release/#Branches","page":"Release management","title":"Branches","text":"","category":"section"},{"location":"DeveloperDocumentation/release/","page":"Release management","title":"Release management","text":"Assuming the current master has version number X.Y.0-DEV, in preparation for the next release a branch release-X.Y is created directly on GitHub. Once that is done the master should be set to X.Y+1.0-DEV.","category":"page"},{"location":"DeveloperDocumentation/release/","page":"Release management","title":"Release management","text":"note: Note\nPlease use the script etc/update_version.sh for version changes.","category":"page"},{"location":"DeveloperDocumentation/release/#Backports","page":"Release management","title":"Backports","text":"","category":"section"},{"location":"DeveloperDocumentation/release/","page":"Release management","title":"Release management","text":"The backports should be mostly bug-fixes and small improvements but no major new features or refactorings, to minimize the risk of regressions. Every change that is considered for backporting has to be merged to master first. Once in the stage of release candidates only small bug-fixes and documentation changes should be added.","category":"page"},{"location":"DeveloperDocumentation/release/","page":"Release management","title":"Release management","text":"Changes for the release, after the branch was created, are mostly done by cherry-picking the commits from master that correspond to the already merged PRs. Preferrably with git cherry-pick -x to keep a reference to the original commit. The cherry-picked commits are collected on a backports-release-X.Y branch and a corresponding PR, like for release 1.0.0-rc1. Please take care to set the merge target for the PR to the release-X.Y branch.","category":"page"},{"location":"DeveloperDocumentation/release/","page":"Release management","title":"Release management","text":"Once this set of changes is complete the PR is merged to the release branch, using a proper merge commit, i.e. please do not squash or rebase this. The list of backported PRs may be added to the commit message for the merge.","category":"page"},{"location":"DeveloperDocumentation/release/#Conflicts","page":"Release management","title":"Conflicts","text":"","category":"section"},{"location":"DeveloperDocumentation/release/","page":"Release management","title":"Release management","text":"If changes from another PR cannot be cleanly applied to the backports branch it may be necessary to create a separate PR targeting the backports branch to manually backport changes from that PR and resolve any conflicts. Make sure that the branch for this PR branches off from the release branch and not from master (to avoid picking up unrelated commits). Then cherry-pick the relevant commits and fix any conflicts.","category":"page"},{"location":"DeveloperDocumentation/release/#Pre-releases","page":"Release management","title":"Pre-releases","text":"","category":"section"},{"location":"DeveloperDocumentation/release/","page":"Release management","title":"Release management","text":"For the next pre-release create a new PR to the release branch adjusting the version, this may be merged with a rebase to avoid some extra commits. That commit can then be tagged on GitHub as a new pre-release.","category":"page"},{"location":"DeveloperDocumentation/release/","page":"Release management","title":"Release management","text":"note: Note\nPre-releases cannot be registered in the julia registry.","category":"page"},{"location":"DeveloperDocumentation/release/","page":"Release management","title":"Release management","text":"For OSCAR 1.0.0 we plan to have one or two release candidates but unlike julia and due to the tight schedule no -alpha or -beta versions.","category":"page"},{"location":"DeveloperDocumentation/release/#Releases","page":"Release management","title":"Releases","text":"","category":"section"},{"location":"DeveloperDocumentation/release/","page":"Release management","title":"Release management","text":"Once the version is at X.Y.0 the version can be registered in the julia registry with @JuliaRegistrator register(). In this case TagBot will create the corresponding release, but preferrably recheck and clean up the list of changes since unfortunately TagBot currently does not take the branch into account and will show all PRs that have been merged to master.","category":"page"},{"location":"DeveloperDocumentation/release/","page":"Release management","title":"Release management","text":"Consider deploying a released version at zenodo.","category":"page"},{"location":"DeveloperDocumentation/release/#Bugfix-releases","page":"Release management","title":"Bugfix releases","text":"","category":"section"},{"location":"DeveloperDocumentation/release/","page":"Release management","title":"Release management","text":"Further bugfix releases X.Y.Z can be created in a similar manner, skipping the pre-releases.","category":"page"},{"location":"Experimental/AlgebraicStatistics/gaussian_graphical_models/","page":"Gaussian Graphical Models","title":"Gaussian Graphical Models","text":"CurrentModule = Oscar\nDocTestSetup = Oscar.doctestsetup()","category":"page"},{"location":"Experimental/AlgebraicStatistics/gaussian_graphical_models/#Gaussian-Graphical-Models","page":"Gaussian Graphical Models","title":"Gaussian Graphical Models","text":"","category":"section"},{"location":"Experimental/AlgebraicStatistics/gaussian_graphical_models/","page":"Gaussian Graphical Models","title":"Gaussian Graphical Models","text":"The OSCAR type for graphical models is of parametrized form GraphicalModel{G, T} where T represents the type of ring in which the vanishing ideal of the model belongs and G represents the associated graph. Gaussian graphical models are those where the T is of type GaussianRing which is a multivariate polynomial ring equipped with some extra features.","category":"page"},{"location":"Experimental/AlgebraicStatistics/gaussian_graphical_models/#Gaussian-Rings","page":"Gaussian Graphical Models","title":"Gaussian Rings","text":"","category":"section"},{"location":"Experimental/AlgebraicStatistics/gaussian_graphical_models/","page":"Gaussian Graphical Models","title":"Gaussian Graphical Models","text":"gaussian_ring(n::Int; s_var_name::VarName=\"s\", K::Field=QQ, cached=false)\ngens(R::GaussianRing)\ncovariance_matrix(R::GaussianRing)","category":"page"},{"location":"Experimental/AlgebraicStatistics/gaussian_graphical_models/#gaussian_ring-Tuple{Int64}","page":"Gaussian Graphical Models","title":"gaussian_ring","text":"gaussian_ring(n::Int; s_var_name::VarName=\"s\", K::Field=QQ, cached=false)\n\nA polynomial ring whose variables correspond to the entries of a covariance matrix of n Gaussian random variables. It is a multivariate polynomial ring whose variables are named s[i,j]and whose coefficient field K is by default QQ.\n\nIf cached is true, the internally generated polynomial ring will be cached.\n\nExamples\n\njulia> R = gaussian_ring(3)\nGaussian ring over Rational field in 6 variables\ns[1, 1], s[1, 2], s[1, 3], s[2, 2], s[2, 3], s[3, 3]\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/AlgebraicStatistics/gaussian_graphical_models/#gens-Tuple{GaussianRing}","page":"Gaussian Graphical Models","title":"gens","text":"gens(R::GaussianRing)\n\nReturn the generators of the multivariate polynomial ring inside the GaussianRing as a dictionary which can be easily indexed\n\nExamples\n\njulia> R = gaussian_ring(3)\nGaussian ring over Rational field in 6 variables\ns[1, 1], s[1, 2], s[1, 3], s[2, 2], s[2, 3], s[3, 3]\n\njulia> gens(R)\nDict{Tuple{Int64, Int64}, QQMPolyRingElem} with 6 entries:\n (1, 2) => s[1, 2]\n (1, 1) => s[1, 1]\n (3, 3) => s[3, 3]\n (1, 3) => s[1, 3]\n (2, 2) => s[2, 2]\n (2, 3) => s[2, 3]\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/AlgebraicStatistics/gaussian_graphical_models/#covariance_matrix-Tuple{GaussianRing}","page":"Gaussian Graphical Models","title":"covariance_matrix","text":"covariance_matrix(R::GaussianRing)\n\nReturn the covariance matrix associated to R as a matrix over the underlying polynomial ring of R\n\nExamples\n\njulia> R = gaussian_ring(3)\nGaussian ring over Rational field in 6 variables\ns[1, 1], s[1, 2], s[1, 3], s[2, 2], s[2, 3], s[3, 3]\n\njulia> covariance_matrix(R)\n[s[1, 1] s[1, 2] s[1, 3]]\n[s[1, 2] s[2, 2] s[2, 3]]\n[s[1, 3] s[2, 3] s[3, 3]]\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/AlgebraicStatistics/gaussian_graphical_models/#Directed-Gaussian-Graphical-Models","page":"Gaussian Graphical Models","title":"Directed Gaussian Graphical Models","text":"","category":"section"},{"location":"Experimental/AlgebraicStatistics/gaussian_graphical_models/","page":"Gaussian Graphical Models","title":"Gaussian Graphical Models","text":"A directed Gaussian graphical model is constructed from G::Graph{Directed} and S::GaussianRing. Optionally, the user may specify a string l_var_name::String which corresponds to the edge weights in the parametrization of the model and a string w_var_name::String for labeling the error covariance parameters.","category":"page"},{"location":"Experimental/AlgebraicStatistics/gaussian_graphical_models/","page":"Gaussian Graphical Models","title":"Gaussian Graphical Models","text":"graphical_model(G::Graph{Directed}, S::GaussianRing; l_var_name::VarName=\"l\", w_var_name::VarName=\"w\", cached=false)","category":"page"},{"location":"Experimental/AlgebraicStatistics/gaussian_graphical_models/#graphical_model-Tuple{Graph{Directed}, GaussianRing}","page":"Gaussian Graphical Models","title":"graphical_model","text":"graphical_model(G::Graph{Directed}, S::GaussianRing; l_var_name::VarName=\"l\", w_var_name::VarName=\"w\", cached=false)\n\nA parametric statistical model associated to a directed acyclic graph. It contains a directed acylic graph G, a GaussianRing S where the vanishing ideal of the model naturally lives, and a parameter ring whose variables l[i,j] correspond to the directed edges i -> j in G. \n\nIf cached is true, the internally generated polynomial ring will be cached.\n\nExamples\n\njulia> M = graphical_model(graph_from_edges(Directed, [[1,2], [2,3]]), gaussian_ring(3))\nGaussian graphical model on a directed graph with edges:\n(1, 2), (2, 3)\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/AlgebraicStatistics/gaussian_graphical_models/","page":"Gaussian Graphical Models","title":"Gaussian Graphical Models","text":"The parametrization for a directed Gaussian graphical model on a DAG G is built from the weighted adjacency matrix Lambda and the covariance matrix Omega of the error terms. The model is then the set of all covariance matrices Sigma = (Id - Lambda)^-T Omega (Id - Lambda)^-1. Lambda and Omega can be built with the following functions:","category":"page"},{"location":"Experimental/AlgebraicStatistics/gaussian_graphical_models/","page":"Gaussian Graphical Models","title":"Gaussian Graphical Models","text":"directed_edges_matrix(M::GraphicalModel{Graph{Directed}, GaussianRing})\nerror_covariance_matrix(M::GraphicalModel{Graph{Directed}, GaussianRing})","category":"page"},{"location":"Experimental/AlgebraicStatistics/gaussian_graphical_models/#directed_edges_matrix-Tuple{GraphicalModel{Graph{Directed}, GaussianRing}}","page":"Gaussian Graphical Models","title":"directed_edges_matrix","text":"directed_edges_matrix(M::GraphicalModel{Graph{Directed}, GaussianRing})\n\nCreates the weighted adjacency matrix Lambda of a directed graph G whose entries are the parameter ring of the graphical model M.\n\nExamples\n\njulia> M = graphical_model(graph_from_edges(Directed, [[1,2], [2,3]]), gaussian_ring(3))\nGaussian graphical model on a directed graph with edges:\n(1, 2), (2, 3)\n\njulia> directed_edges_matrix(M)\n[0 l[1, 2] 0]\n[0 0 l[2, 3]]\n[0 0 0]\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/AlgebraicStatistics/gaussian_graphical_models/#error_covariance_matrix-Tuple{GraphicalModel{Graph{Directed}, GaussianRing}}","page":"Gaussian Graphical Models","title":"error_covariance_matrix","text":"error_covariance_matrix(M::GraphicalModel{Graph{Directed}, GaussianRing})\n\nCreates the covariance matrix $ \\Omega $ of the independent error terms in a directed Gaussian graphical model M\n\nExamples\n\njulia> M = graphical_model(graph_from_edges(Directed, [[1,2], [2,3]]), gaussian_ring(3))\nGaussian graphical model on a directed graph with edges:\n(1, 2), (2, 3)\n\njulia> error_covariance_matrix(M)\n[w[1] 0 0]\n[ 0 w[2] 0]\n[ 0 0 w[3]]\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/AlgebraicStatistics/gaussian_graphical_models/","page":"Gaussian Graphical Models","title":"Gaussian Graphical Models","text":"It is easy to create new types of graphical models by overloading the methods directed_edges_matrix and error_covariance_matrix. For instance, colored graphical models may easily be created by creating a new type of GraphicalModel{G, T} and a new directed_edges_matrix function. The following two functions will then work almost immediately on this new type.","category":"page"},{"location":"Experimental/AlgebraicStatistics/gaussian_graphical_models/","page":"Gaussian Graphical Models","title":"Gaussian Graphical Models","text":"parametrization(M::GraphicalModel{Graph{Directed}, GaussianRing})\nvanishing_ideal(M::GraphicalModel{Graph{Directed}, GaussianRing})","category":"page"},{"location":"Experimental/AlgebraicStatistics/gaussian_graphical_models/#parametrization-Tuple{GraphicalModel{Graph{Directed}, GaussianRing}}","page":"Gaussian Graphical Models","title":"parametrization","text":"parametrization(M::GraphicalModel{Graph{Directed}, GaussianRing})\n\nCreates the polynomial map which parametrizes the vanishing ideal of the directed Gaussian graphical model M. The vanishing ideal of the statistical model is the kernel of this map. This ring map is the pull back of the parametrization phi_G given by (Id - Lambda)^-T Omega (Id - Lambda)^T mapsto Sigma where Lambda = directed_edges_matrix(M) and $ \\Omega = $ error_covariance_matrix(M).\n\nExamples\n\njulia> M = graphical_model(graph_from_edges(Directed, [[1,2], [2,3]]), gaussian_ring(3))\nGaussian graphical model on a directed graph with edges:\n(1, 2), (2, 3)\n\njulia> parametrization(M)\nRing homomorphism\n from multivariate polynomial ring in 6 variables over QQ\n to multivariate polynomial ring in 5 variables over QQ\ndefined by\n s[1, 1] -> w[1]\n s[1, 2] -> l[1, 2]*w[1]\n s[1, 3] -> l[1, 2]*l[2, 3]*w[1]\n s[2, 2] -> l[1, 2]^2*w[1] + w[2]\n s[2, 3] -> l[1, 2]^2*l[2, 3]*w[1] + l[2, 3]*w[2]\n s[3, 3] -> l[1, 2]^2*l[2, 3]^2*w[1] + l[2, 3]^2*w[2] + w[3]\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/AlgebraicStatistics/gaussian_graphical_models/#vanishing_ideal-Tuple{GraphicalModel{Graph{Directed}, GaussianRing}}","page":"Gaussian Graphical Models","title":"vanishing_ideal","text":"vanishing_ideal(M::GraphicalModel)\n\nComputes the vanishing ideal for a graphical model M. This is done by computing the kernel of the parametrization.\n\nExamples\n\njulia> M = graphical_model(graph_from_edges(Directed, [[1,2], [2,3]]), gaussian_ring(3))\nGaussian graphical model on a directed graph with edges:\n(1, 2), (2, 3)\n\njulia> vanishing_ideal(M)\nIdeal generated by\n -s[1, 2]*s[2, 3] + s[1, 3]*s[2, 2]\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/AlgebraicStatistics/gaussian_graphical_models/","page":"Gaussian Graphical Models","title":"Gaussian Graphical Models","text":"With almost all graphical models, the vanishing ideal is computed by taking the kernel of the ring map given by parametrization(M:GraphicalModel{G, T}). ","category":"page"},{"location":"Experimental/AlgebraicStatistics/gaussian_graphical_models/#Undirected-Gaussian-Graphical-Models","page":"Gaussian Graphical Models","title":"Undirected Gaussian Graphical Models","text":"","category":"section"},{"location":"Experimental/AlgebraicStatistics/gaussian_graphical_models/","page":"Gaussian Graphical Models","title":"Gaussian Graphical Models","text":"A undirected Gaussian graphical model is constructed from G::Graph{Undirected}, S::GaussianRing. Optionally, the user may specify a string k_var_name::String which corresponds to the entries of the concentration matrix.","category":"page"},{"location":"Experimental/AlgebraicStatistics/gaussian_graphical_models/","page":"Gaussian Graphical Models","title":"Gaussian Graphical Models","text":"graphical_model(G::Graph{Undirected}, S::GaussianRing; k_var_name::VarName=\"k\", cached=false)","category":"page"},{"location":"Experimental/AlgebraicStatistics/gaussian_graphical_models/#graphical_model-Tuple{Graph{Undirected}, GaussianRing}","page":"Gaussian Graphical Models","title":"graphical_model","text":"graphical_model(G::Graph{Undirected}, S::GaussianRing; k_var_name::VarName=\"k\", cached=false)\n\nA parametric statistical model associated to an undirected graph. It contains an undirected graph G, a GaussianRing S where the vanishing ideal of the model naturally lives, and a parameter ring whose variables k[i,j] correspond to the edges i - j in G. \n\nIf cached is true, the internally generated polynomial ring will be cached.\n\nExamples\n\njulia> M = graphical_model(graph_from_edges([[1,2], [2,3]]), gaussian_ring(3))\nGaussian graphical model on an undirected graph with edges:\n(1, 2), (2, 3)\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/AlgebraicStatistics/gaussian_graphical_models/","page":"Gaussian Graphical Models","title":"Gaussian Graphical Models","text":"As with their directed counterpart, it is very easy to create new subtypes of graphical models by overloading the function concentration_matrix below. Unlike most other types of graphical models though, the vanishing ideal computation of an undirected graphical model is done by eliminating all concentration variables k_ij from the ideal given by the equations Sigma K - Id after saturating by det(K). ","category":"page"},{"location":"Experimental/AlgebraicStatistics/gaussian_graphical_models/","page":"Gaussian Graphical Models","title":"Gaussian Graphical Models","text":"concentration_matrix(M::GraphicalModel{Graph{Undirected}, GaussianRing})\nparametrization(M::GraphicalModel{Graph{Undirected}, GaussianRing})\nvanishing_ideal(M::GraphicalModel{Graph{Undirected}, GaussianRing})","category":"page"},{"location":"Experimental/AlgebraicStatistics/gaussian_graphical_models/#concentration_matrix-Tuple{GraphicalModel{Graph{Undirected}, GaussianRing}}","page":"Gaussian Graphical Models","title":"concentration_matrix","text":"concentration_matrix(M::GraphicalModel{Graph{Undirected}, GaussianRing})\n\nCreates the concentration matrix K of an undirected Gaussian graphical model which is a symmetric positive definite matrix whose nonzero entries correspond to the edges of the associated graph.\n\nExamples\n\njulia> M = graphical_model(graph_from_edges([[1,2], [2,3]]), gaussian_ring(3))\nGaussian graphical model on an undirected graph with edges:\n(1, 2), (2, 3)\n\njulia> concentration_matrix(M)\n[k[1, 1] k[1, 2] 0]\n[k[1, 2] k[2, 2] k[2, 3]]\n[ 0 k[2, 3] k[3, 3]]\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/AlgebraicStatistics/gaussian_graphical_models/#parametrization-Tuple{GraphicalModel{Graph{Undirected}, GaussianRing}}","page":"Gaussian Graphical Models","title":"parametrization","text":"parametrization(M::GraphicalModel{Graph{Undirected}, GaussianRing})\n\nCreates the polynomial map which parametrizes the vanishing ideal of the undirected Gaussian graphical model M. The vanishing ideal of the statistical model is the kernel of this map. This ring map is the pull back of the parametrization phi_G given by $ K \\mapsto K^{-1}$ where $ K = $ concentration_matrix(M) and the entries of $ K^{-1} $ are given by the standard cofactor formula.\n\nExamples\n\njulia> M = graphical_model(graph_from_edges([[1,2], [2,3]]), gaussian_ring(3))\nGaussian graphical model on an undirected graph with edges:\n(1, 2), (2, 3)\n\njulia> parametrization(M)\nRing homomorphism\n from multivariate polynomial ring in 6 variables over QQ\n to fraction field of multivariate polynomial ring\ndefined by\n s[1, 1] -> (k[2, 2]*k[3, 3] - k[2, 3]^2)//(k[1, 1]*k[2, 2]*k[3, 3] - k[1, 1]*k[2, 3]^2 - k[1, 2]^2*k[3, 3])\n s[1, 2] -> (-k[1, 2]*k[3, 3])//(k[1, 1]*k[2, 2]*k[3, 3] - k[1, 1]*k[2, 3]^2 - k[1, 2]^2*k[3, 3])\n s[1, 3] -> (k[1, 2]*k[2, 3])//(k[1, 1]*k[2, 2]*k[3, 3] - k[1, 1]*k[2, 3]^2 - k[1, 2]^2*k[3, 3])\n s[2, 2] -> (k[1, 1]*k[3, 3])//(k[1, 1]*k[2, 2]*k[3, 3] - k[1, 1]*k[2, 3]^2 - k[1, 2]^2*k[3, 3])\n s[2, 3] -> (-k[1, 1]*k[2, 3])//(k[1, 1]*k[2, 2]*k[3, 3] - k[1, 1]*k[2, 3]^2 - k[1, 2]^2*k[3, 3])\n s[3, 3] -> (k[1, 1]*k[2, 2] - k[1, 2]^2)//(k[1, 1]*k[2, 2]*k[3, 3] - k[1, 1]*k[2, 3]^2 - k[1, 2]^2*k[3, 3])\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/AlgebraicStatistics/gaussian_graphical_models/#vanishing_ideal-Tuple{GraphicalModel{Graph{Undirected}, GaussianRing}}","page":"Gaussian Graphical Models","title":"vanishing_ideal","text":"vanishing_ideal(M::GraphicalModel{Graph{Undirected}, GaussianRing})\n\nComputes the vanishing ideal of the undirected Gaussian graphical model M. This is done by saturating the ideal given by $ \\Sigma K - Id $ by the determinant of $ K $ and then eliminating all variables k[i,j] where $ K =$ concentration_matrix(M).\n\nExamples\n\njulia> M = graphical_model(graph_from_edges([[1,2], [2,3]]), gaussian_ring(3))\nGaussian graphical model on an undirected graph with edges:\n(1, 2), (2, 3)\n\njulia> vanishing_ideal(M)\nIdeal generated by\n -s[1, 2]*s[2, 3] + s[1, 3]*s[2, 2]\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"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":"number_of_generators(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 = free_module(QQ, 2)\nVector space of dimension 2 over rationals\n\njulia> n = number_of_generators(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 = free_module(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 = free_module(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 = free_module(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::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\ngetindex(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\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 = free_module(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 = free_module(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 = free_module(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 = free_module(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], Hom: invariant factor decomposed module over integers with invariant factors BigInt[0] -> 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":"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 [Wei18] 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::NormalToricVariety; completeness_check::Bool = true)\nweierstrass_model(base::NormalToricVariety, f::MPolyRingElem, g::MPolyRingElem; completeness_check::Bool = true)","category":"page"},{"location":"Experimental/FTheoryTools/weierstrass/#weierstrass_model-Tuple{NormalToricVariety}","page":"Weierstrass models","title":"weierstrass_model","text":"weierstrass_model(base::NormalToricVariety; 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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/weierstrass/#weierstrass_model-Tuple{NormalToricVariety, MPolyRingElem, MPolyRingElem}","page":"Weierstrass models","title":"weierstrass_model","text":"weierstrass_model(base::NormalToricVariety, f::MPolyRingElem, g::MPolyRingElem; completeness_check::Bool = true)\n\nThis method operates analogously to weierstrass_model(base::NormalToricVarietyType). 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 = generic_section(anticanonical_bundle(base)^4);\n\njulia> g = generic_section(anticanonical_bundle(base)^6);\n\njulia> w = weierstrass_model(base, f, g; completeness_check = false)\nWeierstrass model over a concrete base\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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 serves as the coordinate ring of a family of base spaces. 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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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. [Wei18] 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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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)\nweierstrass_ideal_sheaf(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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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\nFor convenience and uniformity with (general) hypersurface models, we also support the method hypersurface_equation to access the Weierstrass polynomial.\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\njulia> weierstrass_polynomial(w) == hypersurface_equation(w)\ntrue\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/weierstrass/#weierstrass_ideal_sheaf-Tuple{WeierstrassModel}","page":"Weierstrass models","title":"weierstrass_ideal_sheaf","text":"weierstrass_ideal_sheaf(w::WeierstrassModel)\n\nReturn the Weierstrass ideal sheaf of the Weierstrass model.\n\njulia> B3 = projective_space(NormalToricVariety, 3)\nNormal toric variety\n\njulia> w = 2 * torusinvariant_prime_divisors(B3)[1]\nTorus-invariant, non-prime divisor on a normal toric variety\n\njulia> t = literature_model(arxiv_id = \"1109.3454\", equation = \"3.1\", base_space = B3, defining_classes = Dict(\"w\" => w), completeness_check = false)\nConstruction over concrete base may lead to singularity enhancement. Consider computing singular_loci. However, this may take time!\n\nGlobal Tate model over a concrete base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)\n\njulia> w = weierstrass_model(t)\nWeierstrass model over a concrete base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)\n\njulia> weierstrass_ideal_sheaf(w)\nSheaf of ideals\n on normal, simplicial toric variety\nwith restrictions\n 1: Ideal with 1 generator\n 2: Ideal with 1 generator\n 3: Ideal with 1 generator\n 4: Ideal with 1 generator\n 5: Ideal with 2 generators\n 6: Ideal with 2 generators\n 7: Ideal with 2 generators\n 8: Ideal with 2 generators\n 9: Ideal with 5 generators\n 10: Ideal with 5 generators\n 11: Ideal with 5 generators\n 12: Ideal with 5 generators\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/weierstrass/","page":"Weierstrass models","title":"Weierstrass models","text":"The base space can be obtained with base_space, the ambient space with ambient_space and the fiber ambient space with fiber_ambient_space. Recall that is_base_space_fully_specified will tell if the model has been constructed over a concrete space (in which case the function returns true) or a family of spaces (returning false).","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 = weierstrass_model(sample_toric_variety(); completeness_check = false)\nWeierstrass model over a concrete base\n\njulia> calabi_yau_hypersurface(w)\nClosed subvariety of a normal toric variety\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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. [Wei18] 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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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 [CLS11], 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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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/#Blowup","page":"Weierstrass models","title":"Blowup","text":"","category":"section"},{"location":"Experimental/FTheoryTools/weierstrass/","page":"Weierstrass models","title":"Weierstrass models","text":"We can blow up a Weierstrass model with the blow_up function. The resulting model will thereafter be partially resolved. No checks are currently implemented to test if a model is completely resolved. However, is_partially_resolved will return true if a blowup has been applied to the model in question.","category":"page"},{"location":"Experimental/FTheoryTools/weierstrass/#Tuning","page":"Weierstrass models","title":"Tuning","text":"","category":"section"},{"location":"Experimental/FTheoryTools/weierstrass/","page":"Weierstrass models","title":"Weierstrass models","text":"Often, one wishes to tune an existing model, e.g. in an attempt to engineer a larger gauge group. We support the following functionality:","category":"page"},{"location":"Experimental/FTheoryTools/weierstrass/","page":"Weierstrass models","title":"Weierstrass models","text":"tune(w::WeierstrassModel, special_section_choices::Dict{String, <:MPolyRingElem}; completeness_check::Bool = true)","category":"page"},{"location":"Experimental/FTheoryTools/weierstrass/#tune-Tuple{WeierstrassModel, Dict{String, <:MPolyRingElem}}","page":"Weierstrass models","title":"tune","text":"function tune(w::WeierstrassModel, input_sections::Dict{String, <:Any}; completeness_check::Bool = true)\n\nTune a Weierstrass model by fixing a special choice for the model sections. Note that it is in particular possible to set a section to zero. We anticipate that people might want to be able to come back from this by assigning a non-trivial value to a section that was previously tuned to zero. This is why we keep such trivial sections and do not delete them, say from explicit_model_sections or classes_of_model_sections.\n\nExamples\n\njulia> B2 = projective_space(NormalToricVariety, 2)\nNormal toric variety\n\njulia> b = torusinvariant_prime_divisors(B2)[1]\nTorus-invariant, prime divisor on a normal toric variety\n\njulia> w = literature_model(arxiv_id = \"1208.2695\", equation = \"B.19\", base_space = B2, defining_classes = Dict(\"b\" => b), completeness_check = false)\nConstruction over concrete base may lead to singularity enhancement. Consider computing singular_loci. However, this may take time!\n\nWeierstrass model over a concrete base -- U(1) Weierstrass model based on arXiv paper 1208.2695 Eq. (B.19)\n\njulia> x1, x2, x3 = gens(cox_ring(base_space(w)))\n3-element Vector{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}:\n x1\n x2\n x3\n\njulia> my_choice = Dict(\"f\" => x1^12, \"b\" => x2, \"c2\" => x1^6)\nDict{String, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}} with 3 entries:\n \"c2\" => x1^6\n \"f\" => x1^12\n \"b\" => x2\n\njulia> tuned_w = tune(w, my_choice)\nWeierstrass model over a concrete base\n\njulia> weierstrass_section_f(tuned_w) == my_choice[\"f\"]\ntrue\n\njulia> x1, x2, x3 = gens(cox_ring(base_space(tuned_w)))\n3-element Vector{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}:\n x1\n x2\n x3\n\njulia> my_choice2 = Dict(\"f\" => x1^12, \"b\" => x2, \"c2\" => zero(parent(x1)))\nDict{String, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}} with 3 entries:\n \"c2\" => 0\n \"f\" => x1^12\n \"b\" => x2\n\njulia> tuned_w2 = tune(tuned_w, my_choice2)\nWeierstrass model over a concrete base\n\njulia> is_zero(explicit_model_sections(tuned_w2)[\"c2\"])\ntrue\n\njulia> x1, x2, x3 = gens(cox_ring(base_space(tuned_w2)))\n3-element Vector{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}:\n x1\n x2\n x3\n\njulia> my_choice3 = Dict(\"f\" => x1^12, \"b\" => x2, \"c2\" => x1^6)\nDict{String, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}} with 3 entries:\n \"c2\" => x1^6\n \"f\" => x1^12\n \"b\" => x2\n\njulia> tuned_w3 = tune(tuned_w2, my_choice3)\nWeierstrass model over a concrete base\n\njulia> is_zero(explicit_model_sections(tuned_w3)[\"c2\"])\nfalse\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/weierstrass/","page":"Weierstrass models","title":"Weierstrass models","text":"See also the tune function described in Functionality for all F-theory models.","category":"page"},{"location":"Groups/pcgroup/","page":"Polycyclic groups","title":"Polycyclic groups","text":"CurrentModule = Oscar\nDocTestSetup = Oscar.doctestsetup()","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\nmap_word(g::Union{PcGroupElem, SubPcGroupElem}, genimgs::Vector; genimgs_inv::Vector = Vector(undef, length(genimgs)), init = nothing)","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\nFor a group G of type PcGroup, the elements in gens(G) satisfy the relators of the underlying presentation.\n\nFunctions that compute subgroups of G return groups of type SubPcGroup.\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, 3]);\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/#map_word-Tuple{Union{PcGroupElem, SubPcGroupElem}, Vector}","page":"Polycyclic groups","title":"map_word","text":"map_word(g::Union{PcGroupElem, SubPcGroupElem}, 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, which is a product of the form g_i_1^e_1 g_i_2^e_2 cdots g_i_n^e_n where g_i is the i-th entry in the defining polycyclic generating sequence of full_group(parent(g)) and the e_i are nonzero integers, and R_j = imgs[i_j]^e_j.\n\nExamples\n\njulia> G = dihedral_group(10)\nPc group of order 10\n\njulia> x, y = gens(G); g = x * y^4\nf1*f2^4\n\njulia> map_word(g, gens(free_group(:x, :y)))\nx*y^4\n\n\n\n\n\n","category":"method"},{"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\nelementary_abelian_group\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} = PcGroup, v::Vector{S}) where T <: Group where S <: IntegerUnion\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, SubFPGroup, PcGroup, or SubPcGroup.\n\nThe gens value of the returned group corresponds to v, that is, the number of generators is equal to length(v) and the order of the i-th generator is v[i].\n\nwarning: Warning\nThe type need to be specified in the input of the function abelian_group, otherwise a group of type FinGenAbGroup 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/#elementary_abelian_group","page":"Polycyclic groups","title":"elementary_abelian_group","text":"elementary_abelian_group(::Type{T} = PcGroup, n::S) where T <: Group where S <: IntegerUnion\n\nReturn the elementary abelian group group of order n, as an instance of T. Here, T must be one of PermGroup, FPGroup, SubFPGroup, PcGroup, SubPcGroup, or FinGenAbGroup, and n must be a prime power or 1.\n\nThe gens vector of the result has minimal length.\n\nExamples\n\njulia> g = elementary_abelian_group(27)\nPc group of order 27\n\njulia> g = elementary_abelian_group(PermGroup, 27)\nPermutation group of degree 9 and order 27\n\n\n\n\n\n","category":"function"},{"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)\nPc group of order 5\n\njulia> G = cyclic_group(PermGroup, 5)\nPermutation group of degree 5 and order 5\n\njulia> G = cyclic_group(PosInf())\nPc group of infinite order\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, SubPcGroup, PermGroup, FPGroup, SubFPGroup}.\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)\nPc group of order 6\n\njulia> dihedral_group(PermGroup, 6)\nPermutation group of degree 3\n\njulia> dihedral_group(PosInf())\nPc group of infinite order\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, SubPcGroup, PermGroup,FPGroup, SubFPGroup}.\n\nExamples\n\njulia> g = quaternion_group(8)\nPc group of order 8\n\njulia> quaternion_group(PermGroup, 8)\nPermutation group of degree 8\n\njulia> g = quaternion_group(FPGroup, 8)\nFinitely presented group of order 8\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":"AbstractAlgebra/assertions/#Assertion-and-Verbosity-Macros","page":"Assertion and Verbosity Macros","title":"Assertion and Verbosity Macros","text":"","category":"section"},{"location":"AbstractAlgebra/assertions/","page":"Assertion and Verbosity Macros","title":"Assertion and Verbosity Macros","text":"CurrentModule = AbstractAlgebra\nDocTestSetup = quote\n using AbstractAlgebra\nend","category":"page"},{"location":"AbstractAlgebra/assertions/","page":"Assertion and Verbosity Macros","title":"Assertion and Verbosity Macros","text":"We describe here various macros provided by AbstractAlgebra.","category":"page"},{"location":"AbstractAlgebra/assertions/#Verbosity-macros","page":"Assertion and Verbosity Macros","title":"Verbosity macros","text":"","category":"section"},{"location":"AbstractAlgebra/assertions/","page":"Assertion and Verbosity Macros","title":"Assertion and Verbosity 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":"AbstractAlgebra/assertions/","page":"Assertion and Verbosity Macros","title":"Assertion and Verbosity Macros","text":"add_verbosity_scope(s::Symbol)\nset_verbosity_level(s::Symbol, l::Int)\nget_verbosity_level(s::Symbol)","category":"page"},{"location":"AbstractAlgebra/assertions/#add_verbosity_scope-Tuple{Symbol}","page":"Assertion and Verbosity Macros","title":"add_verbosity_scope","text":"AbstractAlgebra.add_verbosity_scope(s::Symbol) -> Nothing\n\nAdd the symbol s to the list of (global) verbosity scopes.\n\nExamples\n\njulia> AbstractAlgebra.add_verbosity_scope(:MyScope)\n\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/assertions/#set_verbosity_level-Tuple{Symbol, Int64}","page":"Assertion and Verbosity Macros","title":"set_verbosity_level","text":"AbstractAlgebra.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> AbstractAlgebra.add_verbosity_scope(:MyScope)\n\njulia> AbstractAlgebra.set_verbosity_level(:MyScope, 4)\n4\n\njulia> AbstractAlgebra.set_verbosity_level(:MyScope, 0)\n0\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/assertions/#get_verbosity_level-Tuple{Symbol}","page":"Assertion and Verbosity Macros","title":"get_verbosity_level","text":"AbstractAlgebra.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> AbstractAlgebra.add_verbosity_scope(:MyScope)\n\njulia> AbstractAlgebra.get_verbosity_level(:MyScope)\n0\n\njulia> AbstractAlgebra.set_verbosity_level(:MyScope, 4)\n4\n\njulia> AbstractAlgebra.get_verbosity_level(:MyScope)\n4\n\njulia> AbstractAlgebra.set_verbosity_level(:MyScope, 0)\n0\n\njulia> AbstractAlgebra.get_verbosity_level(:MyScope)\n0\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/assertions/#Printings","page":"Assertion and Verbosity Macros","title":"Printings","text":"","category":"section"},{"location":"AbstractAlgebra/assertions/","page":"Assertion and Verbosity Macros","title":"Assertion and Verbosity Macros","text":"@vprintln\n@vprint","category":"page"},{"location":"AbstractAlgebra/assertions/#@vprintln","page":"Assertion and Verbosity 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> AbstractAlgebra.add_verbosity_scope(:Test1);\n\njulia> AbstractAlgebra.add_verbosity_scope(:Test2);\n\njulia> AbstractAlgebra.add_verbosity_scope(:Test3);\n\njulia> AbstractAlgebra.set_verbosity_level(:Test1, 1);\n\njulia> AbstractAlgebra.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":"AbstractAlgebra/assertions/#@vprint","page":"Assertion and Verbosity 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":"AbstractAlgebra/assertions/#Actions","page":"Assertion and Verbosity Macros","title":"Actions","text":"","category":"section"},{"location":"AbstractAlgebra/assertions/","page":"Assertion and Verbosity Macros","title":"Assertion and Verbosity Macros","text":"@v_do","category":"page"},{"location":"AbstractAlgebra/assertions/#@v_do","page":"Assertion and Verbosity 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> AbstractAlgebra.add_verbosity_scope(:Test1);\n\njulia> AbstractAlgebra.add_verbosity_scope(:Test2);\n\njulia> AbstractAlgebra.add_verbosity_scope(:Test3);\n\njulia> AbstractAlgebra.set_verbosity_level(:Test1, 1);\n\njulia> AbstractAlgebra.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":"AbstractAlgebra/assertions/#Assertion-macros","page":"Assertion and Verbosity Macros","title":"Assertion macros","text":"","category":"section"},{"location":"AbstractAlgebra/assertions/","page":"Assertion and Verbosity Macros","title":"Assertion and Verbosity 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":"AbstractAlgebra/assertions/","page":"Assertion and Verbosity Macros","title":"Assertion and Verbosity Macros","text":"add_assertion_scope(s::Symbol)\nset_assertion_level(s::Symbol, l::Int)\nget_assertion_level(s::Symbol)","category":"page"},{"location":"AbstractAlgebra/assertions/#add_assertion_scope-Tuple{Symbol}","page":"Assertion and Verbosity Macros","title":"add_assertion_scope","text":"AbstractAlgebra.add_assertion_scope(s::Symbol) -> Nothing\n\nAdd the symbol s to the list of (global) assertion scopes.\n\nExamples\n\njulia> AbstractAlgebra.add_assertion_scope(:MyScope)\n\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/assertions/#set_assertion_level-Tuple{Symbol, Int64}","page":"Assertion and Verbosity Macros","title":"set_assertion_level","text":"AbstractAlgebra.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> AbstractAlgebra.add_assertion_scope(:MyScope)\n\njulia> AbstractAlgebra.set_assertion_level(:MyScope, 4)\n4\n\njulia> AbstractAlgebra.set_assertion_level(:MyScope, 0)\n0\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/assertions/#get_assertion_level-Tuple{Symbol}","page":"Assertion and Verbosity Macros","title":"get_assertion_level","text":"AbstractAlgebra.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> AbstractAlgebra.add_assertion_scope(:MyScope)\n\njulia> AbstractAlgebra.get_assertion_level(:MyScope)\n0\n\njulia> AbstractAlgebra.set_assertion_level(:MyScope, 1)\n1\n\njulia> AbstractAlgebra.get_assertion_level(:MyScope)\n1\n\njulia> AbstractAlgebra.set_assertion_level(:MyScope, 0)\n0\n\njulia> AbstractAlgebra.get_assertion_level(:MyScope)\n0\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/assertions/#Check","page":"Assertion and Verbosity Macros","title":"Check","text":"","category":"section"},{"location":"AbstractAlgebra/assertions/","page":"Assertion and Verbosity Macros","title":"Assertion and Verbosity Macros","text":"@hassert","category":"page"},{"location":"AbstractAlgebra/assertions/#@hassert","page":"Assertion and Verbosity 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> AbstractAlgebra.add_assertion_scope(:MyScope)\n\njulia> AbstractAlgebra.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> AbstractAlgebra.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> AbstractAlgebra.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":"AbstractAlgebra/assertions/#Miscellaneous","page":"Assertion and Verbosity Macros","title":"Miscellaneous","text":"","category":"section"},{"location":"AbstractAlgebra/assertions/","page":"Assertion and Verbosity Macros","title":"Assertion and Verbosity Macros","text":"@req","category":"page"},{"location":"AbstractAlgebra/assertions/#@req","page":"Assertion and Verbosity 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":"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}}\ndual_graph(p::Polyhedron)\nvertex_edge_graph(p::Polyhedron; modulo_lineality=false)\ngraph_from_adjacency_matrix\ngraph_from_edges","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> n_vertices(g)\n5\n\njulia> n_edges(g)\n0\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/graphs/#dual_graph-Tuple{Polyhedron}","page":"Graphs","title":"dual_graph","text":"dual_graph(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 = dual_graph(c);\n\njulia> n_vertices(g)\n6\n\njulia> n_edges(g)\n12\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/graphs/#vertex_edge_graph-Tuple{Polyhedron}","page":"Graphs","title":"vertex_edge_graph","text":"vertex_edge_graph(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. If the polyhedron has lineality, then it has no vertices or bounded edges, so the vertex_edge_graph will be the empty graph. In this case, the keyword argument can be used to consider the polyhedron modulo its lineality space.\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 = vertex_edge_graph(c);\n\njulia> n_vertices(g)\n8\n\njulia> n_edges(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)\nDirected graph with 2 nodes and the following edges:\n(2, 1)\n\njulia> graph_from_adjacency_matrix(Undirected, G)\nUndirected graph with 2 nodes and the following edges:\n(2, 1)\n\n\n\n\n\n\n","category":"function"},{"location":"Combinatorics/graphs/#graph_from_edges","page":"Graphs","title":"graph_from_edges","text":"graph_from_edges(edges::Vector{Vector{Int}})\ngraph_from_edges(::Type{T}, edges::Vector{Vector{Int}}, n_vertices::Int=-1) where {T <:Union{Directed, Undirected}}\n\nCreates a graph from a vector of edges. There is an optional input for number of vertices, graph_from_edges will ignore any negative integers and throw an error when the input is less than the maximum vertex index in edges.\n\nExamples\n\njulia> G = graph_from_edges([[1,3],[3,5],[4,5],[2,4],[2,3]])\nUndirected graph with 5 nodes and the following edges:\n(3, 1)(3, 2)(4, 2)(5, 3)(5, 4)\n\njulia> G = graph_from_edges(Directed, [[1,3]], 4)\nDirected graph with 4 nodes and the following edges:\n(1, 3)\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}}\nrem_vertices!(g::Graph{T}, a::AbstractVector{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. Return true if a new edge (s,t) was added, false otherwise.\n\nExamples\n\njulia> g = Graph{Directed}(2);\n\njulia> add_edge!(g, 1, 2)\ntrue\n\njulia> add_edge!(g, 1, 2)\nfalse\n\njulia> n_edges(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. Return the number of vertices that were actually added to the graph g.\n\nExamples\n\njulia> g = Graph{Directed}(2);\n\njulia> n_vertices(g)\n2\n\njulia> add_vertices!(g, 5);\n\njulia> n_vertices(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. Return true if there a new vertex was actually added.\n\nExamples\n\njulia> g = Graph{Directed}(2);\n\njulia> n_vertices(g)\n2\n\njulia> add_vertex!(g)\ntrue\n\njulia> n_vertices(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}}\nrem_edge!(g::Graph{T}, e::Edge) where {T <: Union{Directed, Undirected}}\n\nRemove edge (s,t) from the graph g. Return true if there was an edge from s to t and it got removed, false otherwise.\n\nExamples\n\njulia> g = Graph{Directed}(2);\n\njulia> add_edge!(g, 1, 2)\ntrue\n\njulia> n_edges(g)\n1\n\njulia> rem_edge!(g, 1, 2)\ntrue\n\njulia> n_edges(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. Return true if node v existed and was actually removed, false otherwise. Please note that this will shift the indices of the vertices with index larger than v, but it will preserve the vertex ordering.\n\nExamples\n\njulia> g = Graph{Directed}(2);\n\njulia> n_vertices(g)\n2\n\njulia> rem_vertex!(g, 1)\ntrue\n\njulia> n_vertices(g)\n1\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/graphs/#rem_vertices!-Union{Tuple{T}, Tuple{Graph{T}, AbstractVector{Int64}}} where T<:Union{Directed, Undirected}","page":"Graphs","title":"rem_vertices!","text":"rem_vertices!(g::Graph{T}, a::AbstractArray{Int64}) where {T <: Union{Directed, Undirected}}\n\nRemove the vertices in a from the graph g. Return true if at least one vertex was removed. Please note that this will shift the indices of some of the remaining vertices, but it will preserve the vertex ordering.\n\nExamples\n\njulia> g = Graph{Directed}(2);\n\njulia> n_vertices(g)\n2\n\njulia> rem_vertices!(g, [1, 2])\ntrue\n\njulia> n_vertices(g)\n0\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":"adjacency_matrix(g::Graph)\nall_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)\ndegree(g::Graph, v::Int)\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}}\nlaplacian_matrix(g::Graph)\nn_edges(g::Graph{T}) where {T <: Union{Directed, Undirected}}\nn_vertices(g::Graph{T}) where {T <: Union{Directed, Undirected}}\ninneighbors(g::Graph{T}, v::Int64) where {T <: Union{Directed, Undirected}}\nneighbors(g::Graph{T}, v::Int64) 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/#adjacency_matrix-Tuple{Graph}","page":"Graphs","title":"adjacency_matrix","text":"adjacency_matrix(g::Graph{T}) where {T <: Union{Directed, Undirected}}\n\nReturn an unsigned (boolean) adjacency matrix representing a graph g. If g is undirected, the adjacency matrix will be symmetric. For g being directed, the adjacency matrix has a 1 at (u,v) if there is an edge u->v.\n\nExamples\n\nAdjacency matrix for a directed graph:\n\njulia> G = Graph{Directed}(3)\nDirected graph with 3 nodes and no edges\n\njulia> add_edge!(G,1,3)\ntrue\n\njulia> add_edge!(G,1,2)\ntrue\n\njulia> adjacency_matrix(G)\n3×3 IncidenceMatrix\n[2, 3]\n[]\n[]\n\n\njulia> matrix(ZZ, adjacency_matrix(G))\n[0 1 1]\n[0 0 0]\n[0 0 0]\n\nAdjacency matrix for an undirected graph:\n\njulia> G = vertex_edge_graph(cube(2))\nUndirected graph with 4 nodes and the following edges:\n(2, 1)(3, 1)(4, 2)(4, 3)\n\njulia> adjacency_matrix(G)\n4×4 IncidenceMatrix\n[2, 3]\n[1, 4]\n[1, 4]\n[2, 3]\n\n\njulia> matrix(ZZ, adjacency_matrix(G))\n[0 1 1 0]\n[1 0 0 1]\n[1 0 0 1]\n[0 1 1 0]\n\n\n\n\n\n","category":"method"},{"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/#degree-Tuple{Graph, Int64}","page":"Graphs","title":"degree","text":"degree(g::Graph{T} [, v::Int64]) where {T <: Union{Directed, Undirected}}\n\nReturn the degree of the vertex v in the graph g. If v is missing, return the list of degrees of all vertices.\n\nExamples\n\njulia> g = vertex_edge_graph(icosahedron());\n\njulia> degree(g, 1)\n5\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 = vertex_edge_graph(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 = vertex_edge_graph(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 = vertex_edge_graph(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/#laplacian_matrix-Tuple{Graph}","page":"Graphs","title":"laplacian_matrix","text":"laplacian_matrix(g::Graph{T}) where {T <: Union{Directed, Undirected}}\n\nReturn the Laplacian matrix of the graph g. The Laplacian matrix of a graph can be written as the difference of D, where D is a quadratic matrix with the degrees of g on the diagonal, and the adjacency matrix of g. For an undirected graph, the Laplacian matrix is symmetric.\n\nExamples\n\njulia> G = vertex_edge_graph(cube(2))\nUndirected graph with 4 nodes and the following edges:\n(2, 1)(3, 1)(4, 2)(4, 3)\n\njulia> laplacian_matrix(G)\n[ 2 -1 -1 0]\n[-1 2 0 -1]\n[-1 0 2 -1]\n[ 0 -1 -1 2]\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/graphs/#n_edges-Union{Tuple{Graph{T}}, Tuple{T}} where T<:Union{Directed, Undirected}","page":"Graphs","title":"n_edges","text":"n_edges(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 = vertex_edge_graph(c);\n\njulia> n_edges(g)\n12\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/graphs/#n_vertices-Union{Tuple{Graph{T}}, Tuple{T}} where T<:Union{Directed, Undirected}","page":"Graphs","title":"n_vertices","text":"n_vertices(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 = vertex_edge_graph(c);\n\njulia> n_vertices(g)\n8\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/#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/#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(vertex_edge_graph(simplex(3)), dual_graph(simplex(3)))\ntrue\n\njulia> is_isomorphic(vertex_edge_graph(cube(3)), dual_graph(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(vertex_edge_graph(simplex(3)), dual_graph(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":"Combinatorics/graphs/#Quantum-Automorphisms","page":"Graphs","title":"Quantum Automorphisms","text":"","category":"section"},{"location":"Combinatorics/graphs/","page":"Graphs","title":"Graphs","text":"quantum_automorphism_group(G::Graph{Undirected})","category":"page"},{"location":"Combinatorics/graphs/#quantum_automorphism_group-Tuple{Graph{Undirected}}","page":"Graphs","title":"quantum_automorphism_group","text":"quantum_automorphism_group(G::Graph{Undirected})\n\nReturn the ideal that defines the quantum automorphism group of the undirected graph G.\n\nExamples\n\njulia> G = graph_from_edges([[1, 2], [2, 4]]);\n\njulia> qAut = quantum_automorphism_group(G);\n\njulia> length(gens(qAut))\n184\n\n\n\n\n\n","category":"method"},{"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\n from integers\n to integers\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\n from integers\n to integers\n\njulia> g = inv(f)\nMap with section\n from integers\n to integers\n\njulia> h = f*g\nComposite map\n from integers\n to integers\nwhich is the composite of\n Map: integers -> integers\n Map: integers -> integers\n\njulia> a = h(ZZ(1))\n1\n","category":"page"},{"location":"Hecke/manual/orders/elements/#Elements","page":"Elements","title":"Elements","text":"","category":"section"},{"location":"Hecke/manual/orders/elements/","page":"Elements","title":"Elements","text":"CurrentModule = Hecke","category":"page"},{"location":"Hecke/manual/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/manual/orders/elements/#Creation","page":"Elements","title":"Creation","text":"","category":"section"},{"location":"Hecke/manual/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 AbsNumFieldOrderElem, 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 AbsSimpleNumFieldOrderElem","category":"page"},{"location":"Hecke/manual/orders/elements/","page":"Elements","title":"Elements","text":"AbsNumFieldOrder","category":"page"},{"location":"Hecke/manual/orders/elements/#AbsNumFieldOrder","page":"Elements","title":"AbsNumFieldOrder","text":" (O::NumFieldOrder)(a::NumFieldElem, check::Bool = true) -> NumFieldOrderElem\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::NumFieldOrder)(a::NumFieldOrderElem, check::Bool = true) -> NumFieldOrderElem\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::NumFieldOrder)(a::IntegerUnion) -> NumFieldOrderElem\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::AbsNumFieldOrder)(arr::Vector{ZZRingElem})\n\nReturns the element of mathcal O with coefficient vector arr.\n\n\n\n\n\n (O::AbsNumFieldOrder)(arr::Vector{Integer})\n\nReturns the element of mathcal O with coefficient vector arr.\n\n\n\n\n\n","category":"type"},{"location":"Hecke/manual/orders/elements/#Basic-properties","page":"Elements","title":"Basic properties","text":"","category":"section"},{"location":"Hecke/manual/orders/elements/","page":"Elements","title":"Elements","text":"parent(::AbsSimpleNumFieldOrderElem)\nelem_in_nf(::AbsSimpleNumFieldOrderElem)\ncoordinates(::AbsSimpleNumFieldOrderElem)\ndiscriminant(::Vector{AbsSimpleNumFieldOrderElem})\n==(::AbsSimpleNumFieldOrderElem, ::AbsSimpleNumFieldOrderElem)","category":"page"},{"location":"Hecke/manual/orders/elements/#parent-Tuple{AbsSimpleNumFieldOrderElem}","page":"Elements","title":"parent","text":"parent(a::NumFieldOrderElem) -> NumFieldOrder\n\nReturns the order of which a is an element.\n\n\n\n\n\nparent(a::MatRingElem{T}) where T <: NCRingElement\n\nReturn the parent object of the given matrix.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/orders/elements/#elem_in_nf-Tuple{AbsSimpleNumFieldOrderElem}","page":"Elements","title":"elem_in_nf","text":"elem_in_nf(a::NumFieldOrderElem) -> 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/manual/orders/elements/#coordinates-Tuple{AbsSimpleNumFieldOrderElem}","page":"Elements","title":"coordinates","text":"coordinates(a::AbsNumFieldOrderElem) -> 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/manual/orders/elements/#discriminant-Tuple{Vector{AbsSimpleNumFieldOrderElem}}","page":"Elements","title":"discriminant","text":"discriminant(B::Vector{NumFieldOrderElem})\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::EllipticCurve) -> 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\ndiscriminant(g::Vector)\n\nCompute the product of all differences of distinct elements in the array. \n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/orders/elements/#==-Tuple{AbsSimpleNumFieldOrderElem, AbsSimpleNumFieldOrderElem}","page":"Elements","title":"==","text":"==(x::NumFieldOrderElem, y::NumFieldOrderElem) -> Bool\n\nReturns whether x and y are equal.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/orders/elements/#Arithmetic","page":"Elements","title":"Arithmetic","text":"","category":"section"},{"location":"Hecke/manual/orders/elements/","page":"Elements","title":"Elements","text":"All the usual arithmetic operatinos are defined:","category":"page"},{"location":"Hecke/manual/orders/elements/","page":"Elements","title":"Elements","text":"-(::NUmFieldOrdElem)\n+(::NumFieldOrderElem, ::NumFieldOrderElem)\n-(::NumFieldOrderElem, ::NumFieldOrderElem)\n*(::NumFieldOrderElem, ::NumFieldOrderElem)\n^(::NumFieldOrderElem, ::Int)\nmod(::AbsNumFieldOrderElem, ::Int)\nmod_sym(::NumFieldOrderElem, ::ZZRingElem)\npowermod(::AbsNumFieldOrderElem, ::ZZRingElem, ::Int)","category":"page"},{"location":"Hecke/manual/orders/elements/#Miscellaneous","page":"Elements","title":"Miscellaneous","text":"","category":"section"},{"location":"Hecke/manual/orders/elements/","page":"Elements","title":"Elements","text":"representation_matrix(::AbsNumFieldOrderElem)\nrepresentation_matrix(::AbsSimpleNumFieldOrderElem, ::AbsSimpleNumField)\ntr(::NumFieldOrderElem)\nnorm(::NumFieldOrderElem)\nabsolute_norm(::AbsNumFieldOrderElem)\nabsolute_tr(::AbsNumFieldOrderElem)\nrand(::AbsSimpleNumFieldOrder, ::Int)\nminkowski_map(::AbsSimpleNumFieldOrderElem, ::Int)\nconjugates_arb(::AbsSimpleNumFieldOrderElem, ::Int)\nconjugates_arb_log(::AbsSimpleNumFieldOrderElem, ::Int)\nt2(::AbsSimpleNumFieldOrderElem, ::Int)\nminpoly(::AbsSimpleNumFieldOrderElem)\ncharpoly(::AbsSimpleNumFieldOrderElem)\nfactor(::AbsSimpleNumFieldOrderElem)\ndenominator(a::NumFieldElem, O::RelNumFieldOrder)\ndiscriminant(::Vector{AbsNumFieldOrderElem})","category":"page"},{"location":"Hecke/manual/orders/elements/#representation_matrix-Tuple{AbsNumFieldOrderElem}","page":"Elements","title":"representation_matrix","text":"representation_matrix(a::AbsNumFieldOrderElem) -> ZZMatrix\n\nReturns the representation matrix of the element a.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/orders/elements/#representation_matrix-Tuple{AbsSimpleNumFieldOrderElem, AbsSimpleNumField}","page":"Elements","title":"representation_matrix","text":"representation_matrix(a::AbsNumFieldOrderElem, K::AbsSimpleNumField) -> 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/manual/orders/elements/#tr-Tuple{NumFieldOrderElem}","page":"Elements","title":"tr","text":"tr(a::NumFieldOrderElem)\n\nReturns the trace of a as an element of the base ring.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/orders/elements/#norm-Tuple{NumFieldOrderElem}","page":"Elements","title":"norm","text":"norm(a::NumFieldOrderElem)\n\nReturns the norm of a as an element in the base ring.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/orders/elements/#absolute_norm-Tuple{AbsNumFieldOrderElem}","page":"Elements","title":"absolute_norm","text":"absolute_norm(a::NumFieldOrderElem) -> ZZRingElem\n\nReturn the absolute norm as an integer.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/orders/elements/#absolute_tr-Tuple{AbsNumFieldOrderElem}","page":"Elements","title":"absolute_tr","text":"absolute_tr(a::NumFieldOrderElem) -> ZZRingElem\n\nReturn the absolute trace as an integer.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/orders/elements/#rand-Tuple{AbsSimpleNumFieldOrder, Int64}","page":"Elements","title":"rand","text":"rand(O::AbsSimpleNumFieldOrder, n::IntegerUnion) -> AbsNumFieldOrderElem\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/manual/orders/elements/#minkowski_map-Tuple{AbsSimpleNumFieldOrderElem, Int64}","page":"Elements","title":"minkowski_map","text":"minkowski_map(a::NumFieldOrderElem, abs_tol::Int) -> Vector{ArbFieldElem}\n\nReturns the image of a under the Minkowski embedding. Every entry of the array returned is of type ArbFieldElem with radius less then 2^-abs_tol.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/orders/elements/#conjugates_arb-Tuple{AbsSimpleNumFieldOrderElem, Int64}","page":"Elements","title":"conjugates_arb","text":"conjugates_arb(x::NumFieldOrderElem, abs_tol::Int) -> Vector{AcbFieldElem}\n\nCompute the conjugates of x as elements of type AcbFieldElem. 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/manual/orders/elements/#conjugates_arb_log-Tuple{AbsSimpleNumFieldOrderElem, Int64}","page":"Elements","title":"conjugates_arb_log","text":"conjugates_arb_log(x::NumFieldOrderElem, abs_tol::Int) -> Vector{ArbFieldElem}\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 ArbFieldElem radius less then 2^-abs_tol.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/orders/elements/#t2-Tuple{AbsSimpleNumFieldOrderElem, Int64}","page":"Elements","title":"t2","text":"t2(x::NumFieldOrderElem, abs_tol::Int = 32) -> ArbFieldElem\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/manual/orders/elements/#minpoly-Tuple{AbsSimpleNumFieldOrderElem}","page":"Elements","title":"minpoly","text":"minpoly(M::MatElem{T}, charpoly_only::Bool = false) where {T <: RingElement}\nminpoly(S::PolyRing{T}, M::MatElem{T}, charpoly_only::Bool = false) where {T <: RingElement}\n\nReturn the minimal polynomial p of the square matrix M. If a polynomial ring S over the same base ring as Y is supplied, the resulting polynomial is an element of it.\n\nExamples\n\njulia> R = GF(13)\nFinite field F_13\n\njulia> S, 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(S, M)\ny^2 + 10*y\n\njulia> A = minpoly(M)\nx^2 + 10*x\n\n\n\n\n\n\nminpoly(a::AbsNumFieldOrderElem) -> ZZPolyRingElem\n\nThe minimal polynomial of a.\n\n\n\n\n\nminpoly(S::Ring, M::MatRingElem{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\n","category":"method"},{"location":"Hecke/manual/orders/elements/#charpoly-Tuple{AbsSimpleNumFieldOrderElem}","page":"Elements","title":"charpoly","text":"charpoly(Y::MatrixElem{T}) where {T <: RingElement}\ncharpoly(S::PolyRing{T}, Y::MatrixElem{T}) where {T <: RingElement}\n\nReturn the characteristic polynomial p of the square matrix Y. If a polynomial ring S over the same base ring as Y is supplied, the resulting polynomial is an element of it.\n\nExamples\n\njulia> R, = residue_ring(ZZ, 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, y = polynomial_ring(R, :y)\n(Univariate polynomial ring in y over residue ring, y)\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)\ny^4 + 2*y^2 + 6*y + 2\n\njulia> A = charpoly(M)\nx^4 + 2*x^2 + 6*x + 2\n\n\n\n\n\n\ncharpoly(a::AbsNumFieldOrderElem) -> ZZPolyRingElem\ncharpoly(a::AbsNumFieldOrderElem, FlintZZ) -> ZZPolyRingElem\n\nThe characteristic polynomial of a.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/orders/elements/#factor-Tuple{AbsSimpleNumFieldOrderElem}","page":"Elements","title":"factor","text":"factor(a::AbsSimpleNumFieldOrderElem) -> Fac{AbsSimpleNumFieldOrderElem}\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/manual/orders/elements/#denominator-Tuple{NumFieldElem, Hecke.RelNumFieldOrder}","page":"Elements","title":"denominator","text":"denominator(a::NumFieldElem, O::AbsSimpleNumFieldOrder) -> 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/manual/orders/elements/#discriminant-Tuple{Vector{AbsNumFieldOrderElem}}","page":"Elements","title":"discriminant","text":"discriminant(B::Vector{NumFieldOrderElem})\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::EllipticCurve) -> 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\ndiscriminant(g::Vector)\n\nCompute the product of all differences of distinct elements in the array. \n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/intro/","page":"Introduction","title":"Introduction","text":"CurrentModule = Oscar","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/intro/#modules_multivariate","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":"Hecke/manual/number_fields/internal/","page":"Internals","title":"Internals","text":"CurrentModule = Hecke","category":"page"},{"location":"Hecke/manual/number_fields/internal/#Internals","page":"Internals","title":"Internals","text":"","category":"section"},{"location":"Hecke/manual/number_fields/internal/#Types-of-number-fields","page":"Internals","title":"Types of number fields","text":"","category":"section"},{"location":"Hecke/manual/number_fields/internal/","page":"Internals","title":"Internals","text":"Number fields, in Hecke, come in several different types:","category":"page"},{"location":"Hecke/manual/number_fields/internal/","page":"Internals","title":"Internals","text":"AbsSimpleNumField: a finite simple extension of the rational numbers mathbfQ\nAbsNonSimpleNumField: 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.\nRelSimpleNumField: 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 (AbsSimpleNumField) is RelSimpleNumField{AbsSimpleNumFieldElem}. The next extension thus will be RelSimpleNumField{RelSimpleNumFieldElem{AbsSimpleNumFieldElem}}.\nRelNonSimpleNumField: extensions of number fields given by several polynomials. This too will be referred to as a non-simple field.","category":"page"},{"location":"Hecke/manual/number_fields/internal/","page":"Internals","title":"Internals","text":"The simple types AbsSimpleNumField and RelSimpleNumField are also called simple fields in the rest of this document, RelSimpleNumField and RelNonSimpleNumField are referred to as relative extensions while AbsSimpleNumField and AbsNonSimpleNumField are called absolute.","category":"page"},{"location":"Hecke/manual/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/manual/number_fields/internal/#Absolute-simple-fields","page":"Internals","title":"Absolute simple fields","text":"","category":"section"},{"location":"Hecke/manual/number_fields/internal/","page":"Internals","title":"Internals","text":"The most basic number field type is that of AbsSimpleNumField. 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":"Rings/integer/","page":"Integers","title":"Integers","text":"CurrentModule = Oscar\nDocTestSetup = Oscar.doctestsetup()","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 behavior 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 behavior.","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) -> ZZRingElem\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 behavior.","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 = Oscar.doctestsetup()","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\nSubFPGroup\nSubFPGroupElem\nfree_group\n@free_group\nfull_group(G::Union{SubFPGroup, SubPcGroup})\nrelators(G::FPGroup)\nlength(g::Union{FPGroupElem, SubFPGroupElem})\nmap_word(g::Union{FPGroupElem, SubFPGroupElem}, genimgs::Vector; genimgs_inv::Vector = Vector(undef, length(genimgs)), init = nothing)","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\nFor a group G of type FPGroup, the elements in gens(G) satisfy the relators of the underlying presentation.\n\nFunctions that compute subgroups of G return groups of type SubFPGroup.\n\n\n\n\n\n","category":"type"},{"location":"Groups/fpgroup/#FPGroupElem","page":"Finitely presented groups","title":"FPGroupElem","text":"FPGroupElem\n\nElement of a finitely presented group.\n\nThe generators of a finitely presented group are displayed as f1, f2, f3, etc., and every element of a finitely presented group is displayed as product of the generators.\n\n\n\n\n\n","category":"type"},{"location":"Groups/fpgroup/#SubFPGroup","page":"Finitely presented groups","title":"SubFPGroup","text":"SubFPGroup\n\nSubgroup of a finitely presented group, a group that is defined by generators that are elements of a group G of type FPGroup.\n\nOperations for computing subgroups of a group of type FPGroup or SubFPGroup, such as derived_subgroup and sylow_subgroup, return groups of type SubFPGroup.\n\nNote that functions such as relators do not make sense for proper subgroups of a finitely presented group.\n\n\n\n\n\n","category":"type"},{"location":"Groups/fpgroup/#SubFPGroupElem","page":"Finitely presented groups","title":"SubFPGroupElem","text":"SubFPGroupElem\n\nElement of a subgroup of a finitely presented group.\n\nThe elements are displayed in the same way as the elements of full finitely presented groups, see FPGroupElem.\n\n\n\n\n\n","category":"type"},{"location":"Groups/fpgroup/#free_group","page":"Finitely presented groups","title":"free_group","text":"free_group(n::Int, s::VarName = :f; eltype::Symbol = :letter) -> FPGroup\nfree_group(L::VarName... ; eltype::Symbol = :letter) -> FPGroup\nfree_group(varnames_specifiers... ; eltype::Symbol = :letter) -> FPGroup\n\nReturn a free group.\n\nThe first form returns a free group of rank n, where the generators are printed as \"$s1\", \"$s2\", ..., the default being f1, f2, ...\n\nThe second form returns a free group of rank n, where n is the length of L, and L consists of strings, symbols or characters giving the variable names.\n\nIn the final form, the argument list consists of a sequence of one or more of the following:\n\nA vector L of variable names.\nA pair of the form A => B, where A is a VarName (so a string, symbol or character) and B is a range or more generally an AbstractVector. Then length(B) generators are defined whose names derive from a combination of A and the respective element of B. For example :x => 1:3 defines three generators x[1], x[2], x[3].\nA pair of the form A => C, where A is again a VarName, and C is a tuple of ranges or v. For example \"a\" => (1:2, 1:2) defines four generators a[1, 1], a[2, 1], a[1, 2], a[2, 2].\n\nFor the second and third type, optionally the A part can contain the placeholder # to modify where the indices are inserted. For example \"a#\" => (1:2, 1:2) defines four generators a11, a21, a12, a22.\n\nAlso, instead of a range, any vector can be used. For example \"#\" => ([:x,:y], [:A, :B]) defines four generators xA, yA, xB, yB.\n\nIn all variants, if the optional keyword argument eltype is given and 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\nwarning: Warning\nJulia variables named like the group generators are not created by this function. However, the macro @free_group does just that.\n\nExamples\n\njulia> F = free_group(:a, :b)\nFree group of rank 2\n\njulia> w = F[1]^3 * F[2]^F[1] * F[-2]^2\na^2*b*a*b^-2\n\nHere we show some of the different ways to create a free group.\n\njulia> gens(free_group(2))\n2-element Vector{FPGroupElem}:\n f1\n f2\n\njulia> gens(free_group(2, :a))\n2-element Vector{FPGroupElem}:\n a1\n a2\n\njulia> gens(free_group(:u, :v))\n2-element Vector{FPGroupElem}:\n u\n v\n\njulia> gens(free_group([:a, :b], \"x\" => 1:2, 'y' => (1:2, 1:2)))\n8-element Vector{FPGroupElem}:\n a\n b\n x[1]\n x[2]\n y[1, 1]\n y[2, 1]\n y[1, 2]\n y[2, 2]\n\n\n\n\n\n","category":"function"},{"location":"Groups/fpgroup/#@free_group","page":"Finitely presented groups","title":"@free_group","text":"@free_group(args...)\n\nReturn the free group obtained from free_group(args...) and introduce its generators as Julia variables into the current scope.\n\nExamples\n\njulia> F = @free_group(:a, :b)\nFree group of rank 2\n\njulia> a^2*b*a*b^-2\na^2*b*a*b^-2\n\nNote that the varname => vector syntax for specifying a vector or matrix or general array of variables behaves slightly differently compared to free_group, as the following example demonstrates.\n\njulia> U1 = free_group(\"x\" => 1:3); gens(U1)\n3-element Vector{FPGroupElem}:\n x[1]\n x[2]\n x[3]\n\njulia> U2 = @free_group(\"x\" => 1:3); gens(U2)\n3-element Vector{FPGroupElem}:\n x1\n x2\n x3\n\njulia> (x2^x1)^-1\nx1^-1*x2^-1*x1\n\n\n\n\n\n","category":"macro"},{"location":"Groups/fpgroup/#full_group-Tuple{Union{SubFPGroup, SubPcGroup}}","page":"Finitely presented groups","title":"full_group","text":"full_group(G::T) where T <: Union{SubFPGroup, SubPcGroup}\nfull_group(G::T) where T <: Union{FPGroup, PcGroup}\n\nReturn F, emb where F is the full pc group of f.p. group of which G is a subgroup, and emb is an embedding of G into F.\n\nExamples\n\njulia> G = perfect_group(FPGroup, 60, 1);\n\njulia> H = sylow_subgroup(G, 2)[1];\n\njulia> full_group(H)[1] == G\ntrue\n\njulia> full_group(G)[1] == G\ntrue\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 w_1 w_2 ldots w_n in F = free_group(ngens(G)) such that G is isomorphic with Fw_1 w_2 ldots w_n.\n\nExamples\n\njulia> f = @free_group(:x, :y);\n\njulia> q = quo(f, [x^2, y^2, comm(x, y)])[1]; relators(q)\n3-element Vector{FPGroupElem}:\n x^2\n y^2\n x^-1*y^-1*x*y\n\n\n\n\n\n","category":"method"},{"location":"Groups/fpgroup/#length-Tuple{Union{FPGroupElem, SubFPGroupElem}}","page":"Finitely presented groups","title":"length","text":"length(g::Union{FPGroupElem, SubFPGroupElem})\n\nReturn the length of g as a word in terms of the generators of its parent or of the full group of its parent if g is an element of a free group, otherwise an exception is thrown.\n\nExamples\n\njulia> F = @free_group(:F1, :F2);\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-Tuple{Union{FPGroupElem, SubFPGroupElem}, Vector}","page":"Finitely presented groups","title":"map_word","text":"map_word(g::Union{FPGroupElem, SubFPGroupElem}, 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_1 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[i_j]^e_j.\n\nIf g is an element of (a subgroup of) a finitely presented group then the result is defined as map_word applied to a representing element of the underlying free group of full_group(parent(g)). In particular, genimgs are interpreted as the images of the generators of this free group, not of gens(parent(g)).\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[k_i]^epsilon_i 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 init is different from nothing then the product gets initialized with init.\n\nIf v has length zero then init is returned if also genimgs has length zero, otherwise one(genimgs[1]) is returned. Thus the intended value for the empty word must be specified as init whenever it is possible that the elements in genimgs do not support one.\n\nExamples\n\njulia> F = @free_group(:F1, :F2);\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> map_word(one(F), imgs, init = imgs[1])\n(1,2,3,4)\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","category":"method"},{"location":"Experimental/LieAlgebras/introduction/","page":"Introduction","title":"Introduction","text":"CurrentModule = Oscar\nDocTestSetup = Oscar.doctestsetup()","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 [Hum72].","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\nLaura Voggesberger","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":"Hecke/manual/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":"AlgebraicGeometry/Curves/AffinePlaneCurves/","page":"Affine plane curves","title":"Affine plane curves","text":"CurrentModule = Oscar","category":"page"},{"location":"AlgebraicGeometry/Curves/AffinePlaneCurves/#Affine-plane-curves","page":"Affine plane curves","title":"Affine plane curves","text":"","category":"section"},{"location":"AlgebraicGeometry/Curves/AffinePlaneCurves/","page":"Affine plane curves","title":"Affine plane curves","text":"AffinePlaneCurve\ndefining_equation(C::AffinePlaneCurve{S, MPolyQuoRing{E}}) where {S, E}\ncommon_components(C::S, D::S) where {S<:AffinePlaneCurve}\nmultiplicity(C::AffinePlaneCurve, P::AbsAffineRationalPoint)\ntangent_lines(C::AffinePlaneCurve, P::AbsAffineRationalPoint)\nintersection_multiplicity(C::AffinePlaneCurve, D::AffinePlaneCurve, P::AbsAffineRationalPoint)\nis_transverse_intersection(C::AffinePlaneCurve, D::AffinePlaneCurve, P::AbsAffineRationalPoint)\nprojective_closure(C::AffinePlaneCurve)","category":"page"},{"location":"AlgebraicGeometry/Curves/AffinePlaneCurves/#AffinePlaneCurve","page":"Affine plane curves","title":"AffinePlaneCurve","text":"AffinePlaneCurve{BaseField<:Field, RingType<:Ring} <: AbsAffineCurve{BaseField, RingType}\n\nType for reduced affine plane curves.\n\nExamples\n\njulia> R, (x, y) = polynomial_ring(QQ, [:x, :y]);\n\njulia> F = y^3*x^6 - y^6*x^2;\n\njulia> C = plane_curve(F)\nAffine plane curve\n defined by 0 = x^5*y - x*y^4\n\n\n\n\n\n\n","category":"type"},{"location":"AlgebraicGeometry/Curves/AffinePlaneCurves/#defining_equation-Union{Tuple{AffinePlaneCurve{S, MPolyQuoRing{E}}}, Tuple{E}, Tuple{S}} where {S, E}","page":"Affine plane curves","title":"defining_equation","text":"defining_equation(C::AffinePlaneCurve)\n\nReturn the defining equation of C.\n\n\n\n\n\ndefining_equation(C::ProjectivePlaneCurve)\n\nReturn the defining equation of the (reduced) plane curve C.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Curves/AffinePlaneCurves/#common_components-Union{Tuple{S}, Tuple{S, S}} where S<:AffinePlaneCurve","page":"Affine plane curves","title":"common_components","text":"common_components(C::AffinePlaneCurve, D::AffinePlaneCurve)\n\nReturn the affine plane curve consisting of the common components of C and D, or an empty vector if they do not have a common component. This component can be reducible.\n\nExamples\n\njulia> R, (x, y) = polynomial_ring(QQ, [:x, :y]);\n\njulia> C = plane_curve(x*(x+y)*(x^2 + x + 1));\n\njulia> D = plane_curve(x*(x+y)*(x-y));\n\njulia> common_components(C, D)\n1-element Vector{AffinePlaneCurve{QQField, MPolyQuoRing{QQMPolyRingElem}}}:\n scheme(x^2 + x*y)\n\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Curves/AffinePlaneCurves/#multiplicity-Tuple{AffinePlaneCurve, AbsAffineRationalPoint}","page":"Affine plane curves","title":"multiplicity","text":"multiplicity(C::AffinePlaneCurve, P::AbsAffineRationalPoint)\n\nReturn the multiplicity of C at P.\n\nExamples\n\njulia> R, (x, y) = polynomial_ring(QQ, [:x, :y]);\n\njulia> C = plane_curve(x^2*(x+y)*(y^3-x^2));\n\njulia> P = C([2,-2])\nRational point\n of scheme(-x^4 - x^3*y + x^2*y^3 + x*y^4)\nwith coordinates (2, -2)\n\njulia> multiplicity(C, P)\n1\n\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Curves/AffinePlaneCurves/#tangent_lines-Tuple{AffinePlaneCurve, AbsAffineRationalPoint}","page":"Affine plane curves","title":"tangent_lines","text":"tangent_lines(C::AffinePlaneCurve, P::AbsAffineRationalPoint)\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\njulia> C = plane_curve(x^2*(x+y)*(y^3-x^2));\n\njulia> P = C([0, 0])\nRational point\n of scheme(-x^4 - x^3*y + x^2*y^3 + x*y^4)\nwith coordinates (0, 0)\n\njulia> tangent_lines(C, P)\nDict{AffinePlaneCurve{QQField, MPolyQuoRing{QQMPolyRingElem}}, Int64} with 2 entries:\n scheme(x) => 3\n scheme(x + y) => 1\n\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Curves/AffinePlaneCurves/#intersection_multiplicity-Tuple{AffinePlaneCurve, AffinePlaneCurve, AbsAffineRationalPoint}","page":"Affine plane curves","title":"intersection_multiplicity","text":"intersection_multiplicity(C::AffinePlaneCurve, D::AffinePlaneCurve, P::AbsAffineRationalPoint)\n\nReturn the intersection multiplicity of C and D at P.\n\nExamples\n\njulia> R, (x, y) = polynomial_ring(QQ, [:x, :y]);\n\njulia> C = plane_curve((x^2+y^2)*(x^2 + y^2 + 2*y))\nAffine plane curve\n defined by 0 = x^4 + 2*x^2*y^2 + 2*x^2*y + y^4 + 2*y^3\n\njulia> D = plane_curve((x^2+y^2)*(y^3*x^6 - y^6*x^2))\nAffine plane curve\n defined by 0 = x^7*y + x^5*y^3 - x^3*y^4 - x*y^6\n\njulia> Q = D([0, -2]);\n\njulia> intersection_multiplicity(C, D, Q)\n1\n\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Curves/AffinePlaneCurves/#is_transverse_intersection-Tuple{AffinePlaneCurve, AffinePlaneCurve, AbsAffineRationalPoint}","page":"Affine plane curves","title":"is_transverse_intersection","text":"is_transverse_intersection(C::AffinePlaneCurve, D::AffinePlaneCurve, P::AbsAffineRationalPoint)\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 = plane_curve(x*(x+y))\nAffine plane curve\n defined by 0 = x^2 + x*y\n\njulia> D = plane_curve((x-y)*(x-2))\nAffine plane curve\n defined by 0 = x^2 - x*y - 2*x + 2*y\n\njulia> P = C([QQ(0), QQ(0)])\nRational point\n of scheme(x^2 + x*y)\nwith coordinates (0, 0)\n\njulia> Q = C([QQ(2), QQ(-2)])\nRational point\n of scheme(x^2 + x*y)\nwith coordinates (2, -2)\n\njulia> is_transverse_intersection(C, D, P)\nfalse\n\njulia> is_transverse_intersection(C, D, Q)\ntrue\n\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Curves/AffinePlaneCurves/#projective_closure-Tuple{AffinePlaneCurve}","page":"Affine plane curves","title":"projective_closure","text":"projective_closure(C::AffinePlaneCurve) -> ProjectivePlaneCurve\n\nReturn the projective closure of C.\n\n\n\n\n\n","category":"method"},{"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 FreeAssociativeAlgebraIdeal{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::FreeAssociativeAlgebra, g::Vector{T}) where T <: FreeAssociativeAlgebraElem\nideal(g::Vector{T}) where T <: FreeAssociativeAlgebraElem","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":"Non-commutative polynomial rings are not Noetherian. Hence, in general, Groebner bases do not exist. Hence calling the functions below may not terminate. Picking suitable term orders is difficult in the noncommutative case. Therefore, we fix the term order to be degree reverse lexicographic.","category":"page"},{"location":"NoncommutativeAlgebra/free_associative_algebra/","page":"Free Associative Algebras","title":"Free Associative Algebras","text":"Setting the parameter deg_bound to a positive value yields the truncation of the Groebner bases to a fixed degree. Such a truncation is always finite.","category":"page"},{"location":"NoncommutativeAlgebra/free_associative_algebra/","page":"Free Associative Algebras","title":"Free Associative Algebras","text":"groebner_basis(I::FreeAssociativeAlgebraIdeal, deg_bound::Int=-1; protocol::Bool=false)","category":"page"},{"location":"NoncommutativeAlgebra/free_associative_algebra/#groebner_basis","page":"Free Associative Algebras","title":"groebner_basis","text":"groebner_basis(I::FreeAssociativeAlgebraIdeal, deg_bound::Int=-1; protocol::Bool=false)\n\nReturn the Groebner basis of I with respect to the degree bound deg_bound. If protocol is true, the protocol of the computation is also returned. The default value of deg_bound is -1, which means that no degree bound is imposed, resulting in a computation that is usually slower, but will return a full Groebner basis if there exists a finite one.\n\njulia> free, (x,y,z) = free_associative_algebra(QQ, [:x, :y, :z]);\n\njulia> f1 = x*y + y*z;\n\njulia> f2 = x^2 + y^2;\n\njulia> I = ideal([f1, f2]);\n\njulia> gb = groebner_basis(I, 3; protocol=false)\nIdeal generating system with elements\n 1 -> x*y + y*z\n 2 -> x^2 + y^2\n 3 -> y^3 + y*z^2\n 4 -> y^2*x + y*z*y\n\n\n\n\n\n","category":"function"},{"location":"NoncommutativeAlgebra/free_associative_algebra/","page":"Free Associative Algebras","title":"Free Associative Algebras","text":"If a finite Gröbner basis exists, it solves the ideal membership problem.","category":"page"},{"location":"NoncommutativeAlgebra/free_associative_algebra/","page":"Free Associative Algebras","title":"Free Associative Algebras","text":"ideal_membership(a::FreeAssociativeAlgebraElem, I::FreeAssociativeAlgebraIdeal, deg_bound::Int)","category":"page"},{"location":"NoncommutativeAlgebra/free_associative_algebra/#ideal_membership-Tuple{FreeAssociativeAlgebraElem, Oscar.FreeAssociativeAlgebraIdeal, Int64}","page":"Free Associative Algebras","title":"ideal_membership","text":"ideal_membership(a::FreeAssociativeAlgebraElem, I::FreeAssociativeAlgebraIdeal, deg_bound::Int)\n\nReturns true if intermediate degree calculations bounded by deg_bound prove that a is in I. Otherwise, returning false indicates an inconclusive answer, but larger deg_bounds give more confidence in a negative answer. If deg_bound is not specified, the default value is -1, which means that no degree bound is imposed, resulting in a calculation using a much slower algorithm that may not terminate, but will return a full Groebner basis if it does.\n\njulia> free, (x,y,z) = free_associative_algebra(QQ, [:x, :y, :z]);\n\njulia> f1 = x*y + y*z;\n\njulia> I = ideal([f1]);\n\njulia> ideal_membership(f1, I, 4)\ntrue\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)\nbase_scheme(X::AbsProjectiveScheme)\nhomogeneous_coordinate_ring(P::AbsProjectiveScheme)\nrelative_ambient_dimension(X::AbsProjectiveScheme)\nambient_coordinate_ring(P::AbsProjectiveScheme)\nambient_space(P::AbsProjectiveScheme)\ndefining_ideal(X::AbsProjectiveScheme)\naffine_cone(X::AbsProjectiveScheme)\nhomogeneous_coordinates_on_affine_cone(X::AbsProjectiveScheme)\ncovered_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 = proj(S, I)\nProjective scheme\n over rational field\ndefined by ideal (x + y)\n\njulia> homogeneous_coordinate_ring(X)\nQuotient\n of multivariate polynomial ring in 3 variables over QQ graded by\n x -> [1]\n y -> [1]\n z -> [1]\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 generated by\n x + y\n\njulia> X = proj(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 generated by\n x + y\n\njulia> X = proj(S, I)\nProjective scheme\n over rational field\ndefined by ideal (x + y)\n\njulia> homogeneous_coordinate_ring(X)\nQuotient\n of multivariate polynomial ring in 3 variables over QQ graded by\n x -> [1]\n y -> [1]\n z -> [1]\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 = proj(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 = proj(S)\nProjective space of dimension 2\n over quotient of multivariate polynomial ring by ideal (u^2 + v^2)\nwith homogeneous coordinates [x, y, z]\n\njulia> defining_ideal(P)\nIdeal with 0 generators\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 = proj(S)\nProjective space of dimension 2\n over quotient of multivariate polynomial ring by ideal (u^2 + v^2)\nwith homogeneous coordinates [x, y, z]\n\njulia> affine_cone(P)\n(scheme(u^2 + v^2), Map: S -> quotient of multivariate polynomial ring)\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 = proj(S)\nProjective space of dimension 2\n over quotient of multivariate polynomial ring by ideal (u^2 + v^2)\nwith homogeneous coordinates [x, y, z]\n\njulia> Oscar.homogeneous_coordinates_on_affine_cone(P)\n3-element Vector{MPolyQuoRingElem{MPolyDecRingElem{QQFieldElem, 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{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}}:\n x\n y\n z\n u\n v\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: affine 2-space\n 2: affine 2-space\n 3: affine 2-space\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 proj(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":"proj(S::MPolyDecRing)\nproj(S::MPolyDecRing, I::MPolyIdeal{T}) where {T<:MPolyDecRingElem}\nproj(I::MPolyIdeal{<:MPolyDecRingElem})\nproj(Q::MPolyQuoRing{<:MPolyDecRingElem})","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})\nprojective_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})\nhilbert_polynomial(P::AbsProjectiveScheme{<:Field})\ndegree(P::AbsProjectiveScheme{<:Field})","category":"page"},{"location":"AlgebraicGeometry/Schemes/ProjectiveSchemes/","page":"Projective schemes","title":"Projective schemes","text":"arithmetic_genus(P::AbsProjectiveScheme{<:Field})","category":"page"},{"location":"AlgebraicGeometry/Schemes/ProjectiveSchemes/#arithmetic_genus-Tuple{AbsProjectiveScheme{<:Field}}","page":"Projective schemes","title":"arithmetic_genus","text":"arithmetic_genus(X::AbsProjectiveScheme{<:Field}) -> Int\n\nReturn the arithmetic genus of X, i.e. the integer (-1)^n (h_X(0) - 1) where h_X is the Hilbert polynomial of X and n its dimension.\n\n\n\n\n\n","category":"method"},{"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::AbsAffineScheme)\nhomogenization_map(P::AbsProjectiveScheme, U::AbsAffineScheme)","category":"page"},{"location":"AlgebraicGeometry/Schemes/ProjectiveSchemes/#dehomogenization_map-Tuple{AbsProjectiveScheme, AbsAffineScheme}","page":"Projective schemes","title":"dehomogenization_map","text":"dehomogenization_map(X::AbsProjectiveScheme, U::AbsAffineScheme)\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/#homogenization_map-Tuple{AbsProjectiveScheme, AbsAffineScheme}","page":"Projective schemes","title":"homogenization_map","text":"homogenization_map(P::AbsProjectiveScheme, U::AbsAffineScheme)\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 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: affine 4-space\n 2: affine 4-space\n 3: affine 4-space\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:","category":"page"},{"location":"AlgebraicGeometry/Schemes/ProjectiveSchemes/","page":"Projective schemes","title":"Projective schemes","text":"is_smooth(P::AbsProjectiveScheme{<:Any, <:MPolyQuoRing}; algorithm=:default)","category":"page"},{"location":"AlgebraicGeometry/Schemes/ProjectiveSchemes/#is_smooth-Tuple{AbsProjectiveScheme{<:Any, <:MPolyQuoRing}}","page":"Projective schemes","title":"is_smooth","text":"is_smooth(P::AbsProjectiveScheme; algorithm::Symbol=:default) -> Bool\n\nCheck whether the scheme P is smooth.\n\nAlgorithms\n\nThere are three possible algorithms for checking smoothness, determined by the value of the keyword argument algorithm:\n\n:projective_jacobian - uses the Jacobian criterion for projective schemes, see Exercise 4.2.10 of [Liu06],\n:covered_jacobian - uses covered version of the Jacobian criterion,\n:affine_cone - checks that the affine cone is smooth outside the origin.\n\nThe :projective_jacobian and the :covered algorithms only work for equidimensional schemes. The algorithms first check for equidimensionality, which can be expensive. If you already know that the scheme is equidimensional, then you can avoid recomputing that by writing set_attribute!(P, :is_equidimensional, true) before checking for smoothness.\n\nThe algorithms :covered_jacobian and :affine_cone only work when the base ring is a field.\n\nThe default algorithm is :projective_jacobian if the scheme is equidimensional, otherwise it is :affine_cone.\n\nExamples\n\njulia> A, (x, y, z) = grade(QQ[:x, :y, :z][1]);\n\njulia> B, _ = quo(A, ideal(A, [x^2 + y^2]));\n\njulia> C = proj(B)\nProjective scheme\n over rational field\ndefined by ideal (x^2 + y^2)\n\njulia> is_smooth(C)\nfalse\n\njulia> is_smooth(C; algorithm=:covered_jacobian)\nfalse\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/ProjectiveSchemes/","page":"Projective schemes","title":"Projective schemes","text":"is_empty(P::AbsProjectiveScheme{<:Field})\nis_irreducible(P::AbsProjectiveScheme)\nis_reduced(P::AbsProjectiveScheme)\nis_geometrically_reduced(P::AbsProjectiveScheme{<:Field})\nis_geometrically_irreducible(P::AbsProjectiveScheme{<:Field})\nis_integral(X::AbsProjectiveScheme{<:Field})\nis_geometrically_integral(X::AbsProjectiveScheme{<:Field})","category":"page"},{"location":"Experimental/LieAlgebras/lie_algebra_homs/","page":"Lie algebra homomorphisms","title":"Lie algebra homomorphisms","text":"CurrentModule = Oscar\nDocTestSetup = Oscar.doctestsetup()","category":"page"},{"location":"Experimental/LieAlgebras/lie_algebra_homs/#Lie-algebra-homomorphisms","page":"Lie algebra homomorphisms","title":"Lie algebra homomorphisms","text":"","category":"section"},{"location":"Experimental/LieAlgebras/lie_algebra_homs/","page":"Lie algebra homomorphisms","title":"Lie algebra homomorphisms","text":"Homomorphisms of Lie algebras in Oscar are represented by the type LieAlgebraHom.","category":"page"},{"location":"Experimental/LieAlgebras/lie_algebra_homs/#Constructors","page":"Lie algebra homomorphisms","title":"Constructors","text":"","category":"section"},{"location":"Experimental/LieAlgebras/lie_algebra_homs/","page":"Lie algebra homomorphisms","title":"Lie algebra homomorphisms","text":"Lie algebra homomorphisms h L_1 to L_2 are constructed by providing either the images of the basis elements of L_1 or a dim L_1 times dim L_2 matrix.","category":"page"},{"location":"Experimental/LieAlgebras/lie_algebra_homs/","page":"Lie algebra homomorphisms","title":"Lie algebra homomorphisms","text":"hom(::LieAlgebra{C}, ::LieAlgebra{C}, ::Vector{<:LieAlgebraElem{C}}; check::Bool=true) where {C<:FieldElem}\nhom(::LieAlgebra{C}, ::LieAlgebra{C}, ::MatElem{C}; check::Bool=true) where {C<:FieldElem}\nidentity_map(::LieAlgebra)\nzero_map(::LieAlgebra{C}, ::LieAlgebra{C}) where {C<:FieldElem}","category":"page"},{"location":"Experimental/LieAlgebras/lie_algebra_homs/#hom-Union{Tuple{C}, Tuple{LieAlgebra{C}, LieAlgebra{C}, Vector{<:LieAlgebraElem{C}}}} where C<:FieldElem","page":"Lie algebra homomorphisms","title":"hom","text":"hom(L1::LieAlgebra, L2::LieAlgebra, imgs::Vector{<:LieAlgebraElem}; check::Bool=true) -> LieAlgebraHom\n\nConstruct the homomorphism from L1 to L2 by sending the i-th basis element of L1 to imgs[i] and extending linearly. All elements of imgs must lie in L2.\n\nBy setting check=false, the linear map is not checked to be compatible with the Lie bracket.\n\nExamples\n\njulia> L1 = special_linear_lie_algebra(QQ, 2);\n\njulia> L2 = special_linear_lie_algebra(QQ, 3);\n\njulia> h = hom(L1, L2, [basis(L2, 1), basis(L2, 4), basis(L2, 7)]) # embed sl_2 into sl_3\nLie algebra morphism\n from special linear Lie algebra of degree 2 over QQ\n to special linear Lie algebra of degree 3 over QQ\n \njulia> [(x, h(x)) for x in basis(L1)]\n3-element Vector{Tuple{LinearLieAlgebraElem{QQFieldElem}, LinearLieAlgebraElem{QQFieldElem}}}:\n (e_1_2, e_1_2)\n (f_1_2, f_1_2)\n (h_1, h_1)\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/lie_algebra_homs/#hom-Union{Tuple{C}, Tuple{LieAlgebra{C}, LieAlgebra{C}, MatElem{C}}} where C<:FieldElem","page":"Lie algebra homomorphisms","title":"hom","text":"hom(L1::LieAlgebra, L2::LieAlgebra, mat::MatElem; check::Bool=true) -> LieAlgebraHom\n\nConstruct the homomorphism from L1 to L2 by acting with the matrix mat from the right on the coefficient vector w.r.t. the basis of L1. mat must be a matrix of size dim(L1) \\times dim(L2) over coefficient_ring(L2).\n\nBy setting check=false, the linear map is not checked to be compatible with the Lie bracket.\n\nExamples\n\njulia> L1 = special_linear_lie_algebra(QQ, 2);\n\njulia> L2 = general_linear_lie_algebra(QQ, 2);\n\njulia> h = hom(L1, L2, matrix(QQ, [0 1 0 0; 0 0 1 0; 1 0 0 -1]))\nLie algebra morphism\n from special linear Lie algebra of degree 2 over QQ\n to general linear Lie algebra of degree 2 over QQ\n\njulia> [(x, h(x)) for x in basis(L1)]\n3-element Vector{Tuple{LinearLieAlgebraElem{QQFieldElem}, LinearLieAlgebraElem{QQFieldElem}}}:\n (e_1_2, x_1_2)\n (f_1_2, x_2_1)\n (h_1, x_1_1 - x_2_2)\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/lie_algebra_homs/#identity_map-Tuple{LieAlgebra}","page":"Lie algebra homomorphisms","title":"identity_map","text":"identity_map(L::LieAlgebra) -> LieAlgebraHom\n\nConstruct the identity map on L.\n\nExamples\n\njulia> L = special_linear_lie_algebra(QQ, 3)\nSpecial linear Lie algebra of degree 3\n of dimension 8\nover rational field\n\njulia> identity_map(L)\nLie algebra morphism\n from special linear Lie algebra of degree 3 over QQ\n to special linear Lie algebra of degree 3 over QQ\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/lie_algebra_homs/#zero_map-Union{Tuple{C}, Tuple{LieAlgebra{C}, LieAlgebra{C}}} where C<:FieldElem","page":"Lie algebra homomorphisms","title":"zero_map","text":"zero_map(L1::LieAlgebra, L2::LieAlgebra) -> LieAlgebraHom\nzero_map(L::LieAlgebra) -> LieAlgebraHom\n\nConstruct the zero map from L1 to L2 or from L to L.\n\nExamples\n\njulia> L = special_linear_lie_algebra(QQ, 3)\nSpecial linear Lie algebra of degree 3\n of dimension 8\nover rational field\n\njulia> zero_map(L)\nLie algebra morphism\n from special linear Lie algebra of degree 3 over QQ\n to special linear Lie algebra of degree 3 over QQ\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/lie_algebra_homs/#Functions","page":"Lie algebra homomorphisms","title":"Functions","text":"","category":"section"},{"location":"Experimental/LieAlgebras/lie_algebra_homs/","page":"Lie algebra homomorphisms","title":"Lie algebra homomorphisms","text":"The following functions are available for LieAlgebraHoms:","category":"page"},{"location":"Experimental/LieAlgebras/lie_algebra_homs/#Basic-properties","page":"Lie algebra homomorphisms","title":"Basic properties","text":"","category":"section"},{"location":"Experimental/LieAlgebras/lie_algebra_homs/","page":"Lie algebra homomorphisms","title":"Lie algebra homomorphisms","text":"For a homomorphism h L_1 to L_2, domain(h) and codomain(h) return L_1 and L_2 respectively.","category":"page"},{"location":"Experimental/LieAlgebras/lie_algebra_homs/","page":"Lie algebra homomorphisms","title":"Lie algebra homomorphisms","text":"matrix(::LieAlgebraHom{<:LieAlgebra,<:LieAlgebra{C2}}) where {C2<:FieldElem}","category":"page"},{"location":"Experimental/LieAlgebras/lie_algebra_homs/#matrix-Union{Tuple{LieAlgebraHom{<:LieAlgebra, <:LieAlgebra{C2}}}, Tuple{C2}} where C2<:FieldElem","page":"Lie algebra homomorphisms","title":"matrix","text":"matrix(R::Ring, arr::AbstractMatrix{T}) where {T}\n\nConstructs the matrix over R with entries as in arr.\n\n\n\n\n\nmatrix(R::Ring, r::Int, c::Int, arr::AbstractVector{T}) where {T}\n\nConstructs the r times c matrix over R, where the entries are taken row-wise from arr.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/lie_algebra_homs/#Image","page":"Lie algebra homomorphisms","title":"Image","text":"","category":"section"},{"location":"Experimental/LieAlgebras/lie_algebra_homs/","page":"Lie algebra homomorphisms","title":"Lie algebra homomorphisms","text":"image(::LieAlgebraHom, ::LieAlgebraElem)\nimage(::LieAlgebraHom)\nimage(::LieAlgebraHom, ::LieAlgebraIdeal)\nimage(::LieAlgebraHom, ::LieSubalgebra)","category":"page"},{"location":"Experimental/LieAlgebras/lie_algebra_homs/#image-Tuple{LieAlgebraHom, LieAlgebraElem}","page":"Lie algebra homomorphisms","title":"image","text":"image(h::LieAlgebraHom, x::LieAlgebraElem) -> LieAlgebraElem\n\nReturn the image of x under h.\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/lie_algebra_homs/#image-Tuple{LieAlgebraHom}","page":"Lie algebra homomorphisms","title":"image","text":"image(h::LieAlgebraHom) -> LieSubalgebra\n\nReturn the image of h as a Lie subalgebra of the codomain.\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/lie_algebra_homs/#image-Tuple{LieAlgebraHom, LieAlgebraIdeal}","page":"Lie algebra homomorphisms","title":"image","text":"image(h::LieAlgebraHom, I::LieAlgebraIdeal) -> LieSubalgebra\n\nReturn the image of I under h as a Lie subalgebra of the codomain.\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/lie_algebra_homs/#image-Tuple{LieAlgebraHom, LieSubalgebra}","page":"Lie algebra homomorphisms","title":"image","text":"image(h::LieAlgebraHom, S::LieSubalgebra) -> LieSubalgebra\n\nReturn the image of S under h as a Lie subalgebra of the codomain.\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/lie_algebra_homs/#Kernel","page":"Lie algebra homomorphisms","title":"Kernel","text":"","category":"section"},{"location":"Experimental/LieAlgebras/lie_algebra_homs/","page":"Lie algebra homomorphisms","title":"Lie algebra homomorphisms","text":"kernel(::LieAlgebraHom)","category":"page"},{"location":"Experimental/LieAlgebras/lie_algebra_homs/#kernel-Tuple{LieAlgebraHom}","page":"Lie algebra homomorphisms","title":"kernel","text":"kernel(h::LieAlgebraHom) -> LieAlgebraIdeal\n\nReturn the kernel of h as an ideal of the domain.\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/lie_algebra_homs/#Composition","page":"Lie algebra homomorphisms","title":"Composition","text":"","category":"section"},{"location":"Experimental/LieAlgebras/lie_algebra_homs/","page":"Lie algebra homomorphisms","title":"Lie algebra homomorphisms","text":"compose(::LieAlgebraHom{T1,T2}, ::LieAlgebraHom{T2,T3}) where {T1<:LieAlgebra,T2<:LieAlgebra,T3<:LieAlgebra}","category":"page"},{"location":"Experimental/LieAlgebras/lie_algebra_homs/#compose-Union{Tuple{T3}, Tuple{T2}, Tuple{T1}, Tuple{LieAlgebraHom{T1, T2}, LieAlgebraHom{T2, T3}}} where {T1<:LieAlgebra, T2<:LieAlgebra, T3<:LieAlgebra}","page":"Lie algebra homomorphisms","title":"compose","text":"compose(f::LieAlgebraHom, g::LieAlgebraHom) -> LieAlgebraHom\n\nReturn the composition of f and g, i.e. the homomorphism h such that h(x) = g(f(x)) for all x in the domain of f. The codomain of f must be identical to the domain of g.\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/lie_algebra_homs/#Inverses","page":"Lie algebra homomorphisms","title":"Inverses","text":"","category":"section"},{"location":"Experimental/LieAlgebras/lie_algebra_homs/","page":"Lie algebra homomorphisms","title":"Lie algebra homomorphisms","text":"is_isomorphism(::LieAlgebraHom)\ninv(::LieAlgebraHom)","category":"page"},{"location":"Experimental/LieAlgebras/lie_algebra_homs/#is_isomorphism-Tuple{LieAlgebraHom}","page":"Lie algebra homomorphisms","title":"is_isomorphism","text":"is_isomorphism(h::LieAlgebraHom) -> Bool\n\nReturn true if h is an isomorphism. This function tries to invert the transformation matrix of h and caches the result. The inverse isomorphism can be cheaply accessed via inv(h) after calling this function.\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/lie_algebra_homs/#inv-Tuple{LieAlgebraHom}","page":"Lie algebra homomorphisms","title":"inv","text":"inv(h::LieAlgebraHom) -> LieAlgebraHom\n\nReturn the inverse of h. Requires h to be an isomorphism.\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"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, ...} <: LaurentPolyRing{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 LaurentPolyRing{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":"laurent_polynomial_ring","category":"page"},{"location":"AbstractAlgebra/laurent_polynomial/#laurent_polynomial_ring","page":"Generic Laurent polynomials","title":"laurent_polynomial_ring","text":"laurent_polynomial_ring(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 = laurent_polynomial_ring(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\nlaurent_polynomial_ring(R::Ring, varnames...; cached::Bool = true)\n\nGiven a base ring R and variable names varnames..., say :x, :y, :z, return a tuple S, x, y, z representing the new ring S = Rx 1x y 1y z 1z and the generators x y z of the ring.\n\nBy default (cached=true), the output S will be cached, i.e. if laurent_polynomial_ring is invoked again with the same arguments, the same (identical) ring is returned. Setting cached to false ensures a distinct new ring is returned, and will also prevent it from being cached.\n\nFor information about the many ways to specify varnames... refer to polynomial_ring or the specification in AbstractAlgebra.@varnames_interface.\n\n\n\n\n\n","category":"function"},{"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 = laurent_polynomial_ring(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> number_of_variables(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 precision complex balls","title":"Fixed precision complex balls","text":"CurrentModule = Nemo\nDocTestSetup = quote\n using Nemo\nend","category":"page"},{"location":"Nemo/acb/#Fixed-precision-complex-balls","page":"Fixed precision complex balls","title":"Fixed precision complex balls","text":"","category":"section"},{"location":"Nemo/acb/","page":"Fixed precision complex balls","title":"Fixed 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 ArbFieldElem balls.","category":"page"},{"location":"Nemo/acb/","page":"Fixed precision complex balls","title":"Fixed precision complex 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 precision complex balls","title":"Fixed 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/acb/","page":"Fixed precision complex balls","title":"Fixed precision complex balls","text":"Library Field Element type Parent type\nArb mathbbC (boxes) AcbFieldElem AcbField","category":"page"},{"location":"Nemo/acb/","page":"Fixed precision complex balls","title":"Fixed 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/acb/#Complex-ball-functionality","page":"Fixed precision complex balls","title":"Complex ball functionality","text":"","category":"section"},{"location":"Nemo/acb/","page":"Fixed precision complex balls","title":"Fixed precision complex balls","text":"The complex balls in Nemo provide all the field functionality defined by AbstractAlgebra:.","category":"page"},{"location":"Nemo/acb/","page":"Fixed precision complex balls","title":"Fixed precision complex balls","text":"https://nemocas.github.io/AbstractAlgebra.jl/stable/field","category":"page"},{"location":"Nemo/acb/","page":"Fixed precision complex balls","title":"Fixed precision complex balls","text":"Below, we document the additional functionality provided for complex balls.","category":"page"},{"location":"Nemo/acb/#Complex-field-constructors","page":"Fixed precision complex balls","title":"Complex field constructors","text":"","category":"section"},{"location":"Nemo/acb/","page":"Fixed precision complex balls","title":"Fixed 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/acb/","page":"Fixed precision complex balls","title":"Fixed precision complex balls","text":"AcbField(prec::Int)","category":"page"},{"location":"Nemo/acb/","page":"Fixed precision complex balls","title":"Fixed precision complex 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 precision complex balls","title":"Fixed 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/acb/","page":"Fixed precision complex balls","title":"Fixed precision complex balls","text":"Examples","category":"page"},{"location":"Nemo/acb/","page":"Fixed precision complex balls","title":"Fixed precision complex 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 precision complex balls","title":"Fixed 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/acb/","page":"Fixed precision complex balls","title":"Fixed 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/acb/","page":"Fixed precision complex balls","title":"Fixed 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/acb/#Constructors","page":"Fixed precision complex balls","title":"Constructors","text":"","category":"section"},{"location":"Nemo/acb/","page":"Fixed precision complex balls","title":"Fixed precision complex balls","text":"onei(::AcbField)","category":"page"},{"location":"Nemo/acb/#onei-Tuple{AcbField}","page":"Fixed precision complex 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 precision complex balls","title":"Fixed precision complex balls","text":"Examples","category":"page"},{"location":"Nemo/acb/","page":"Fixed precision complex balls","title":"Fixed precision complex 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 precision complex balls","title":"Basic functionality","text":"","category":"section"},{"location":"Nemo/acb/","page":"Fixed precision complex balls","title":"Fixed 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/acb/","page":"Fixed precision complex balls","title":"Fixed precision complex balls","text":"parent_type(::Type{AcbFieldElem})","category":"page"},{"location":"Nemo/acb/","page":"Fixed precision complex balls","title":"Fixed precision complex balls","text":"Gives the type of the parent object of an Arb complex field element.","category":"page"},{"location":"Nemo/acb/","page":"Fixed precision complex balls","title":"Fixed precision complex balls","text":"elem_type(R::AcbField)","category":"page"},{"location":"Nemo/acb/","page":"Fixed precision complex balls","title":"Fixed 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/acb/","page":"Fixed precision complex balls","title":"Fixed precision complex balls","text":"mul!(c::AcbFieldElem, a::AcbFieldElem, b::AcbFieldElem)","category":"page"},{"location":"Nemo/acb/","page":"Fixed precision complex balls","title":"Fixed 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/acb/","page":"Fixed precision complex balls","title":"Fixed precision complex balls","text":"deepcopy(a::AcbFieldElem)","category":"page"},{"location":"Nemo/acb/","page":"Fixed precision complex balls","title":"Fixed 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/acb/","page":"Fixed precision complex balls","title":"Fixed 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/acb/","page":"Fixed precision complex balls","title":"Fixed precision complex balls","text":"R()","category":"page"},{"location":"Nemo/acb/","page":"Fixed precision complex balls","title":"Fixed precision complex balls","text":"Coerce zero into the Arb complex field.","category":"page"},{"location":"Nemo/acb/","page":"Fixed precision complex balls","title":"Fixed precision complex balls","text":"R(n::Integer)\nR(f::ZZRingElem)\nR(q::QQFieldElem)","category":"page"},{"location":"Nemo/acb/","page":"Fixed precision complex balls","title":"Fixed precision complex balls","text":"Coerce an integer or rational value into the Arb complex field.","category":"page"},{"location":"Nemo/acb/","page":"Fixed precision complex balls","title":"Fixed precision complex balls","text":"R(f::Float64)\nR(f::BigFloat)","category":"page"},{"location":"Nemo/acb/","page":"Fixed precision complex balls","title":"Fixed precision complex balls","text":"Coerce the given floating point number into the Arb complex field.","category":"page"},{"location":"Nemo/acb/","page":"Fixed precision complex balls","title":"Fixed precision complex balls","text":"R(f::AbstractString)\nR(f::AbstractString, g::AbstractString)","category":"page"},{"location":"Nemo/acb/","page":"Fixed precision complex balls","title":"Fixed 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/acb/","page":"Fixed precision complex balls","title":"Fixed precision complex balls","text":"R(f::ArbFieldElem)","category":"page"},{"location":"Nemo/acb/","page":"Fixed precision complex balls","title":"Fixed precision complex balls","text":"Coerce the given Arb real ball into the Arb complex field.","category":"page"},{"location":"Nemo/acb/","page":"Fixed precision complex balls","title":"Fixed precision complex balls","text":"R(f::AcbFieldElem)","category":"page"},{"location":"Nemo/acb/","page":"Fixed precision complex balls","title":"Fixed 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/acb/","page":"Fixed precision complex balls","title":"Fixed precision complex balls","text":"Here are some examples of coercing elements into the Arb complex field.","category":"page"},{"location":"Nemo/acb/","page":"Fixed precision complex balls","title":"Fixed precision complex 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 precision complex balls","title":"Fixed 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::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::AcbFieldElem) to return the parent object of a complex field element.","category":"page"},{"location":"Nemo/acb/#Basic-manipulation","page":"Fixed precision complex balls","title":"Basic manipulation","text":"","category":"section"},{"location":"Nemo/acb/","page":"Fixed precision complex balls","title":"Fixed precision complex balls","text":"isfinite(::AcbFieldElem)","category":"page"},{"location":"Nemo/acb/#isfinite-Tuple{AcbFieldElem}","page":"Fixed precision complex balls","title":"isfinite","text":"isfinite(x::AcbFieldElem)\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 precision complex balls","title":"Fixed precision complex balls","text":"is_exact(::AcbFieldElem)","category":"page"},{"location":"Nemo/acb/#is_exact-Tuple{AcbFieldElem}","page":"Fixed precision complex balls","title":"is_exact","text":"is_exact(x::AcbFieldElem)\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 precision complex balls","title":"Fixed precision complex balls","text":"isinteger(::AcbFieldElem)","category":"page"},{"location":"Nemo/acb/#isinteger-Tuple{AcbFieldElem}","page":"Fixed precision complex balls","title":"isinteger","text":"isinteger(x::AcbFieldElem)\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 precision complex balls","title":"Fixed precision complex balls","text":"accuracy_bits(::AcbFieldElem)","category":"page"},{"location":"Nemo/acb/#accuracy_bits-Tuple{AcbFieldElem}","page":"Fixed precision complex balls","title":"accuracy_bits","text":"accuracy_bits(x::AcbFieldElem)\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 precision complex balls","title":"Fixed precision complex balls","text":"Examples","category":"page"},{"location":"Nemo/acb/","page":"Fixed precision complex balls","title":"Fixed precision complex 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 precision complex balls","title":"Containment","text":"","category":"section"},{"location":"Nemo/acb/","page":"Fixed precision complex balls","title":"Fixed 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/acb/","page":"Fixed precision complex balls","title":"Fixed precision complex balls","text":"overlaps(::AcbFieldElem, ::AcbFieldElem)","category":"page"},{"location":"Nemo/acb/#overlaps-Tuple{AcbFieldElem, AcbFieldElem}","page":"Fixed precision complex balls","title":"overlaps","text":"overlaps(x::AcbFieldElem, y::AcbFieldElem)\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 precision complex balls","title":"Fixed precision complex balls","text":"contains(::AcbFieldElem, ::AcbFieldElem)","category":"page"},{"location":"Nemo/acb/#contains-Tuple{AcbFieldElem, AcbFieldElem}","page":"Fixed precision complex balls","title":"contains","text":"contains(x::AcbFieldElem, y::AcbFieldElem)\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 precision complex balls","title":"Fixed precision complex balls","text":"contains(::AcbFieldElem, ::Integer)\ncontains(::AcbFieldElem, ::ZZRingElem)\ncontains(::AcbFieldElem, ::QQFieldElem)","category":"page"},{"location":"Nemo/acb/#contains-Tuple{AcbFieldElem, Integer}","page":"Fixed precision complex balls","title":"contains","text":"contains(x::AcbFieldElem, 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{AcbFieldElem, ZZRingElem}","page":"Fixed precision complex balls","title":"contains","text":"contains(x::AcbFieldElem, 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{AcbFieldElem, QQFieldElem}","page":"Fixed precision complex balls","title":"contains","text":"contains(x::AcbFieldElem, 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 precision complex balls","title":"Fixed 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/acb/","page":"Fixed precision complex balls","title":"Fixed precision complex balls","text":"contains_zero(::AcbFieldElem)","category":"page"},{"location":"Nemo/acb/#contains_zero-Tuple{AcbFieldElem}","page":"Fixed precision complex balls","title":"contains_zero","text":"contains_zero(x::AcbFieldElem)\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 precision complex balls","title":"Fixed precision complex balls","text":"Examples","category":"page"},{"location":"Nemo/acb/","page":"Fixed precision complex balls","title":"Fixed precision complex 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 precision complex balls","title":"Comparison","text":"","category":"section"},{"location":"Nemo/acb/","page":"Fixed precision complex balls","title":"Fixed precision complex balls","text":"Nemo provides a full range of comparison operations for Arb complex boxes. ","category":"page"},{"location":"Nemo/acb/","page":"Fixed precision complex balls","title":"Fixed 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/acb/","page":"Fixed precision complex balls","title":"Fixed precision complex balls","text":"isequal(::AcbFieldElem, ::AcbFieldElem)","category":"page"},{"location":"Nemo/acb/#isequal-Tuple{AcbFieldElem, AcbFieldElem}","page":"Fixed precision complex balls","title":"isequal","text":"isequal(x::AcbFieldElem, y::AcbFieldElem)\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 precision complex balls","title":"Fixed 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/acb/","page":"Fixed precision complex balls","title":"Fixed precision complex balls","text":"Function\n==(x::AcbFieldElem, y::Integer)\n==(x::Integer, y::AcbFieldElem)\n==(x::AcbFieldElem, y::ZZRingElem)\n==(x::ZZRingElem, y::AcbFieldElem)\n==(x::ArbFieldElem, y::ZZRingElem)\n==(x::ZZRingElem, y::ArbFieldElem)\n==(x::AcbFieldElem, y::Float64)\n==(x::Float64, y::AcbFieldElem)","category":"page"},{"location":"Nemo/acb/","page":"Fixed precision complex balls","title":"Fixed precision complex balls","text":"Examples","category":"page"},{"location":"Nemo/acb/","page":"Fixed precision complex balls","title":"Fixed precision complex 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 precision complex balls","title":"Absolute value","text":"","category":"section"},{"location":"Nemo/acb/","page":"Fixed precision complex balls","title":"Fixed precision complex balls","text":"Examples","category":"page"},{"location":"Nemo/acb/","page":"Fixed precision complex balls","title":"Fixed precision complex 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 precision complex balls","title":"Shifting","text":"","category":"section"},{"location":"Nemo/acb/","page":"Fixed precision complex balls","title":"Fixed precision complex balls","text":"Examples","category":"page"},{"location":"Nemo/acb/","page":"Fixed precision complex balls","title":"Fixed precision complex 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 precision complex balls","title":"Miscellaneous operations","text":"","category":"section"},{"location":"Nemo/acb/","page":"Fixed precision complex balls","title":"Fixed precision complex balls","text":"trim(::AcbFieldElem)","category":"page"},{"location":"Nemo/acb/#trim-Tuple{AcbFieldElem}","page":"Fixed precision complex balls","title":"trim","text":"trim(x::AcbFieldElem)\n\nReturn an AcbFieldElem 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 precision complex balls","title":"Fixed precision complex balls","text":"unique_integer(::AcbFieldElem)","category":"page"},{"location":"Nemo/acb/#unique_integer-Tuple{AcbFieldElem}","page":"Fixed precision complex balls","title":"unique_integer","text":"unique_integer(x::AcbFieldElem)\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 precision complex balls","title":"Fixed precision complex balls","text":"Examples","category":"page"},{"location":"Nemo/acb/","page":"Fixed precision complex balls","title":"Fixed precision complex 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 precision complex balls","title":"Constants","text":"","category":"section"},{"location":"Nemo/acb/","page":"Fixed precision complex balls","title":"Fixed precision complex balls","text":"const_pi(::AcbField)","category":"page"},{"location":"Nemo/acb/#const_pi-Tuple{AcbField}","page":"Fixed precision complex 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 precision complex balls","title":"Fixed precision complex balls","text":"Examples","category":"page"},{"location":"Nemo/acb/","page":"Fixed precision complex balls","title":"Fixed precision complex 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 precision complex balls","title":"Mathematical and special functions","text":"","category":"section"},{"location":"Nemo/acb/","page":"Fixed precision complex balls","title":"Fixed precision complex balls","text":"rsqrt(::AcbFieldElem)","category":"page"},{"location":"Nemo/acb/#rsqrt-Tuple{AcbFieldElem}","page":"Fixed precision complex balls","title":"rsqrt","text":"rsqrt(x::AcbFieldElem)\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 precision complex balls","title":"Fixed precision complex balls","text":"cispi(::AcbFieldElem)","category":"page"},{"location":"Nemo/acb/#cispi-Tuple{AcbFieldElem}","page":"Fixed precision complex balls","title":"cispi","text":"cispi(x::AcbFieldElem)\n\nReturn the exponential of pi i x.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/acb/","page":"Fixed precision complex balls","title":"Fixed precision complex balls","text":"root_of_unity(::AcbField, k::Int)","category":"page"},{"location":"Nemo/acb/#root_of_unity-Tuple{AcbField, Int64}","page":"Fixed precision complex 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 precision complex balls","title":"Fixed precision complex balls","text":"log_sinpi(::AcbFieldElem)","category":"page"},{"location":"Nemo/acb/#log_sinpi-Tuple{AcbFieldElem}","page":"Fixed precision complex balls","title":"log_sinpi","text":"log_sinpi(x::AcbFieldElem)\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 precision complex balls","title":"Fixed precision complex balls","text":"gamma(::AcbFieldElem)","category":"page"},{"location":"Nemo/acb/#gamma-Tuple{AcbFieldElem}","page":"Fixed precision complex balls","title":"gamma","text":"gamma(x::AcbFieldElem)\n\nReturn the Gamma function evaluated at x.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/acb/","page":"Fixed precision complex balls","title":"Fixed precision complex balls","text":"lgamma(::AcbFieldElem)","category":"page"},{"location":"Nemo/acb/#lgamma-Tuple{AcbFieldElem}","page":"Fixed precision complex balls","title":"lgamma","text":"lgamma(x::AcbFieldElem)\n\nReturn the logarithm of the Gamma function evaluated at x.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/acb/","page":"Fixed precision complex balls","title":"Fixed precision complex balls","text":"rgamma(::AcbFieldElem)","category":"page"},{"location":"Nemo/acb/#rgamma-Tuple{AcbFieldElem}","page":"Fixed precision complex balls","title":"rgamma","text":"rgamma(x::AcbFieldElem)\n\nReturn the reciprocal of the Gamma function evaluated at x.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/acb/","page":"Fixed precision complex balls","title":"Fixed precision complex balls","text":"digamma(::AcbFieldElem)","category":"page"},{"location":"Nemo/acb/#digamma-Tuple{AcbFieldElem}","page":"Fixed precision complex balls","title":"digamma","text":"digamma(x::AcbFieldElem)\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 precision complex balls","title":"Fixed precision complex balls","text":"zeta(::AcbFieldElem)","category":"page"},{"location":"Nemo/acb/#zeta-Tuple{AcbFieldElem}","page":"Fixed precision complex balls","title":"zeta","text":"zeta(x::AcbFieldElem)\n\nReturn the Riemann zeta function evaluated at x.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/acb/","page":"Fixed precision complex balls","title":"Fixed precision complex balls","text":"barnes_g(::AcbFieldElem)","category":"page"},{"location":"Nemo/acb/#barnes_g-Tuple{AcbFieldElem}","page":"Fixed precision complex balls","title":"barnes_g","text":"barnes_g(x::AcbFieldElem)\n\nReturn the Barnes G-function, evaluated at x.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/acb/","page":"Fixed precision complex balls","title":"Fixed precision complex balls","text":"log_barnes_g(::AcbFieldElem)","category":"page"},{"location":"Nemo/acb/#log_barnes_g-Tuple{AcbFieldElem}","page":"Fixed precision complex balls","title":"log_barnes_g","text":"log_barnes_g(x::AcbFieldElem)\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 precision complex balls","title":"Fixed precision complex balls","text":"erf(::AcbFieldElem)","category":"page"},{"location":"Nemo/acb/#erf-Tuple{AcbFieldElem}","page":"Fixed precision complex balls","title":"erf","text":"erf(x::AcbFieldElem)\n\nReturn the error function evaluated at x.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/acb/","page":"Fixed precision complex balls","title":"Fixed precision complex balls","text":"erfi(::AcbFieldElem)","category":"page"},{"location":"Nemo/acb/#erfi-Tuple{AcbFieldElem}","page":"Fixed precision complex balls","title":"erfi","text":"erfi(x::AcbFieldElem)\n\nReturn the imaginary error function evaluated at x.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/acb/","page":"Fixed precision complex balls","title":"Fixed precision complex balls","text":"exp_integral_ei(::AcbFieldElem)","category":"page"},{"location":"Nemo/acb/#exp_integral_ei-Tuple{AcbFieldElem}","page":"Fixed precision complex balls","title":"exp_integral_ei","text":"exp_integral_ei(x::AcbFieldElem)\n\nReturn the exponential integral evaluated at x.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/acb/","page":"Fixed precision complex balls","title":"Fixed precision complex balls","text":"sin_integral(::AcbFieldElem)","category":"page"},{"location":"Nemo/acb/#sin_integral-Tuple{AcbFieldElem}","page":"Fixed precision complex balls","title":"sin_integral","text":"sin_integral(x::AcbFieldElem)\n\nReturn the sine integral evaluated at x.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/acb/","page":"Fixed precision complex balls","title":"Fixed precision complex balls","text":"cos_integral(::AcbFieldElem)","category":"page"},{"location":"Nemo/acb/#cos_integral-Tuple{AcbFieldElem}","page":"Fixed precision complex balls","title":"cos_integral","text":"cos_integral(x::AcbFieldElem)\n\nReturn the exponential cosine integral evaluated at x.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/acb/","page":"Fixed precision complex balls","title":"Fixed precision complex balls","text":"sinh_integral(::AcbFieldElem)","category":"page"},{"location":"Nemo/acb/#sinh_integral-Tuple{AcbFieldElem}","page":"Fixed precision complex balls","title":"sinh_integral","text":"sinh_integral(x::AcbFieldElem)\n\nReturn the hyperbolic sine integral evaluated at x.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/acb/","page":"Fixed precision complex balls","title":"Fixed precision complex balls","text":"cosh_integral(::AcbFieldElem)","category":"page"},{"location":"Nemo/acb/#cosh_integral-Tuple{AcbFieldElem}","page":"Fixed precision complex balls","title":"cosh_integral","text":"cosh_integral(x::AcbFieldElem)\n\nReturn the hyperbolic cosine integral evaluated at x.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/acb/","page":"Fixed precision complex balls","title":"Fixed precision complex balls","text":"dedekind_eta(::AcbFieldElem)","category":"page"},{"location":"Nemo/acb/#dedekind_eta-Tuple{AcbFieldElem}","page":"Fixed precision complex balls","title":"dedekind_eta","text":"dedekind_eta(x::AcbFieldElem)\n\nReturn the Dedekind eta function eta(tau) at tau = x.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/acb/","page":"Fixed precision complex balls","title":"Fixed precision complex balls","text":"modular_weber_f(::AcbFieldElem)","category":"page"},{"location":"Nemo/acb/#modular_weber_f-Tuple{AcbFieldElem}","page":"Fixed precision complex balls","title":"modular_weber_f","text":"modular_weber_f(x::AcbFieldElem)\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 precision complex balls","title":"Fixed precision complex balls","text":"modular_weber_f1(::AcbFieldElem)","category":"page"},{"location":"Nemo/acb/#modular_weber_f1-Tuple{AcbFieldElem}","page":"Fixed precision complex balls","title":"modular_weber_f1","text":"modular_weber_f1(x::AcbFieldElem)\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 precision complex balls","title":"Fixed precision complex balls","text":"modular_weber_f2(::AcbFieldElem)","category":"page"},{"location":"Nemo/acb/#modular_weber_f2-Tuple{AcbFieldElem}","page":"Fixed precision complex balls","title":"modular_weber_f2","text":"modular_weber_f2(x::AcbFieldElem)\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 precision complex balls","title":"Fixed precision complex balls","text":"j_invariant(::AcbFieldElem)","category":"page"},{"location":"Nemo/acb/#j_invariant-Tuple{AcbFieldElem}","page":"Fixed precision complex balls","title":"j_invariant","text":"j_invariant(x::AcbFieldElem)\n\nReturn the j-invariant j(tau) at tau = x.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/acb/","page":"Fixed precision complex balls","title":"Fixed precision complex balls","text":"modular_lambda(::AcbFieldElem)","category":"page"},{"location":"Nemo/acb/#modular_lambda-Tuple{AcbFieldElem}","page":"Fixed precision complex balls","title":"modular_lambda","text":"modular_lambda(x::AcbFieldElem)\n\nReturn the modular lambda function lambda(tau) at tau = x.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/acb/","page":"Fixed precision complex balls","title":"Fixed precision complex balls","text":"modular_delta(::AcbFieldElem)","category":"page"},{"location":"Nemo/acb/#modular_delta-Tuple{AcbFieldElem}","page":"Fixed precision complex balls","title":"modular_delta","text":"modular_delta(x::AcbFieldElem)\n\nReturn the modular delta function Delta(tau) at tau = x.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/acb/","page":"Fixed precision complex balls","title":"Fixed precision complex balls","text":"eisenstein_g(::Int, ::AcbFieldElem)","category":"page"},{"location":"Nemo/acb/#eisenstein_g-Tuple{Int64, AcbFieldElem}","page":"Fixed precision complex balls","title":"eisenstein_g","text":"eisenstein_g(k::Int, x::AcbFieldElem)\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 precision complex balls","title":"Fixed precision complex balls","text":"elliptic_k(::AcbFieldElem)","category":"page"},{"location":"Nemo/acb/#elliptic_k-Tuple{AcbFieldElem}","page":"Fixed precision complex balls","title":"elliptic_k","text":"elliptic_k(x::AcbFieldElem)\n\nReturn the complete elliptic integral K(x).\n\n\n\n\n\n","category":"method"},{"location":"Nemo/acb/","page":"Fixed precision complex balls","title":"Fixed precision complex balls","text":"elliptic_e(::AcbFieldElem)","category":"page"},{"location":"Nemo/acb/#elliptic_e-Tuple{AcbFieldElem}","page":"Fixed precision complex balls","title":"elliptic_e","text":"elliptic_e(x::AcbFieldElem)\n\nReturn the complete elliptic integral E(x).\n\n\n\n\n\n","category":"method"},{"location":"Nemo/acb/","page":"Fixed precision complex balls","title":"Fixed precision complex balls","text":"agm(::AcbFieldElem)\nagm(::AcbFieldElem, ::AcbFieldElem)","category":"page"},{"location":"Nemo/acb/#agm-Tuple{AcbFieldElem}","page":"Fixed precision complex balls","title":"agm","text":"agm(x::AcbFieldElem)\n\nReturn the arithmetic-geometric mean of 1 and x.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/acb/#agm-Tuple{AcbFieldElem, AcbFieldElem}","page":"Fixed precision complex balls","title":"agm","text":"agm(x::AcbFieldElem, y::AcbFieldElem)\n\nReturn the arithmetic-geometric mean of x and y.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/acb/","page":"Fixed precision complex balls","title":"Fixed precision complex balls","text":"polygamma(::AcbFieldElem, ::AcbFieldElem)","category":"page"},{"location":"Nemo/acb/#polygamma-Tuple{AcbFieldElem, AcbFieldElem}","page":"Fixed precision complex balls","title":"polygamma","text":"polygamma(s::AcbFieldElem, a::AcbFieldElem)\n\nReturn the generalised polygamma function psi(sz).\n\n\n\n\n\n","category":"method"},{"location":"Nemo/acb/","page":"Fixed precision complex balls","title":"Fixed precision complex balls","text":"zeta(::AcbFieldElem, ::AcbFieldElem)","category":"page"},{"location":"Nemo/acb/#zeta-Tuple{AcbFieldElem, AcbFieldElem}","page":"Fixed precision complex balls","title":"zeta","text":"zeta(s::AcbFieldElem, a::AcbFieldElem)\n\nReturn the Hurwitz zeta function zeta(sa).\n\n\n\n\n\n","category":"method"},{"location":"Nemo/acb/","page":"Fixed precision complex balls","title":"Fixed precision complex balls","text":"rising_factorial(::AcbFieldElem, ::Int)","category":"page"},{"location":"Nemo/acb/#rising_factorial-Tuple{AcbFieldElem, Int64}","page":"Fixed precision complex balls","title":"rising_factorial","text":"rising_factorial(x::AcbFieldElem, 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 precision complex balls","title":"Fixed precision complex balls","text":"rising_factorial2(::AcbFieldElem, ::Int)","category":"page"},{"location":"Nemo/acb/#rising_factorial2-Tuple{AcbFieldElem, Int64}","page":"Fixed precision complex balls","title":"rising_factorial2","text":"rising_factorial2(x::AcbFieldElem, 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 precision complex balls","title":"Fixed precision complex balls","text":"polylog(::Union{AcbFieldElem,Int}, ::AcbFieldElem)","category":"page"},{"location":"Nemo/acb/#polylog-Tuple{Union{Int64, AcbFieldElem}, AcbFieldElem}","page":"Fixed precision complex balls","title":"polylog","text":"polylog(s::Union{AcbFieldElem,Int}, a::AcbFieldElem)\n\nReturn the polylogarithm Li_s(a).\n\n\n\n\n\n","category":"method"},{"location":"Nemo/acb/","page":"Fixed precision complex balls","title":"Fixed precision complex balls","text":"log_integral(::AcbFieldElem)","category":"page"},{"location":"Nemo/acb/#log_integral-Tuple{AcbFieldElem}","page":"Fixed precision complex balls","title":"log_integral","text":"log_integral(x::AcbFieldElem)\n\nReturn the logarithmic integral, evaluated at x.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/acb/","page":"Fixed precision complex balls","title":"Fixed precision complex balls","text":"log_integral_offset(::AcbFieldElem)","category":"page"},{"location":"Nemo/acb/#log_integral_offset-Tuple{AcbFieldElem}","page":"Fixed precision complex balls","title":"log_integral_offset","text":"log_integral_offset(x::AcbFieldElem)\n\nReturn the offset logarithmic integral, evaluated at x.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/acb/","page":"Fixed precision complex balls","title":"Fixed precision complex balls","text":"exp_integral_e(::AcbFieldElem, ::AcbFieldElem)","category":"page"},{"location":"Nemo/acb/#exp_integral_e-Tuple{AcbFieldElem, AcbFieldElem}","page":"Fixed precision complex balls","title":"exp_integral_e","text":"exp_integral_e(s::AcbFieldElem, x::AcbFieldElem)\n\nReturn the generalised exponential integral E_s(x).\n\n\n\n\n\n","category":"method"},{"location":"Nemo/acb/","page":"Fixed precision complex balls","title":"Fixed precision complex balls","text":"gamma(::AcbFieldElem, ::AcbFieldElem)","category":"page"},{"location":"Nemo/acb/#gamma-Tuple{AcbFieldElem, AcbFieldElem}","page":"Fixed precision complex balls","title":"gamma","text":"gamma(s::AcbFieldElem, x::AcbFieldElem)\n\nReturn the upper incomplete gamma function Gamma(sx).\n\n\n\n\n\n","category":"method"},{"location":"Nemo/acb/","page":"Fixed precision complex balls","title":"Fixed precision complex balls","text":"gamma_regularized(::AcbFieldElem, ::AcbFieldElem)","category":"page"},{"location":"Nemo/acb/#gamma_regularized-Tuple{AcbFieldElem, AcbFieldElem}","page":"Fixed precision complex balls","title":"gamma_regularized","text":"gamma_regularized(s::AcbFieldElem, x::AcbFieldElem)\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 precision complex balls","title":"Fixed precision complex balls","text":"gamma_lower(::AcbFieldElem, ::AcbFieldElem)","category":"page"},{"location":"Nemo/acb/#gamma_lower-Tuple{AcbFieldElem, AcbFieldElem}","page":"Fixed precision complex balls","title":"gamma_lower","text":"gamma_lower(s::AcbFieldElem, x::AcbFieldElem)\n\nReturn the lower incomplete gamma function gamma(sx) Gamma(s).\n\n\n\n\n\n","category":"method"},{"location":"Nemo/acb/","page":"Fixed precision complex balls","title":"Fixed precision complex balls","text":"gamma_lower_regularized(::AcbFieldElem, ::AcbFieldElem)","category":"page"},{"location":"Nemo/acb/#gamma_lower_regularized-Tuple{AcbFieldElem, AcbFieldElem}","page":"Fixed precision complex balls","title":"gamma_lower_regularized","text":"gamma_lower_regularized(s::AcbFieldElem, x::AcbFieldElem)\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 precision complex balls","title":"Fixed precision complex balls","text":"airy_ai(::AcbFieldElem)","category":"page"},{"location":"Nemo/acb/#airy_ai-Tuple{AcbFieldElem}","page":"Fixed precision complex balls","title":"airy_ai","text":"airy_ai(x::AcbFieldElem)\n\nReturn the Airy function operatornameAi(x).\n\n\n\n\n\n","category":"method"},{"location":"Nemo/acb/","page":"Fixed precision complex balls","title":"Fixed precision complex balls","text":"airy_ai_prime(::AcbFieldElem)","category":"page"},{"location":"Nemo/acb/#airy_ai_prime-Tuple{AcbFieldElem}","page":"Fixed precision complex balls","title":"airy_ai_prime","text":"airy_ai_prime(x::AcbFieldElem)\n\nReturn the derivative of the Airy function operatornameAi^prime(x).\n\n\n\n\n\n","category":"method"},{"location":"Nemo/acb/","page":"Fixed precision complex balls","title":"Fixed precision complex balls","text":"airy_bi(::AcbFieldElem)","category":"page"},{"location":"Nemo/acb/#airy_bi-Tuple{AcbFieldElem}","page":"Fixed precision complex balls","title":"airy_bi","text":"airy_bi(x::AcbFieldElem)\n\nReturn the Airy function operatornameBi(x).\n\n\n\n\n\n","category":"method"},{"location":"Nemo/acb/","page":"Fixed precision complex balls","title":"Fixed precision complex balls","text":"airy_bi_prime(::AcbFieldElem)","category":"page"},{"location":"Nemo/acb/#airy_bi_prime-Tuple{AcbFieldElem}","page":"Fixed precision complex balls","title":"airy_bi_prime","text":"airy_bi_prime(x::AcbFieldElem)\n\nReturn the derivative of the Airy function operatornameBi^prime(x).\n\n\n\n\n\n","category":"method"},{"location":"Nemo/acb/","page":"Fixed precision complex balls","title":"Fixed precision complex balls","text":"bessel_j(::AcbFieldElem, ::AcbFieldElem)","category":"page"},{"location":"Nemo/acb/#bessel_j-Tuple{AcbFieldElem, AcbFieldElem}","page":"Fixed precision complex balls","title":"bessel_j","text":"bessel_j(nu::AcbFieldElem, x::AcbFieldElem)\n\nReturn the Bessel function J_nu(x).\n\n\n\n\n\n","category":"method"},{"location":"Nemo/acb/","page":"Fixed precision complex balls","title":"Fixed precision complex balls","text":"bessel_y(::AcbFieldElem, ::AcbFieldElem)","category":"page"},{"location":"Nemo/acb/#bessel_y-Tuple{AcbFieldElem, AcbFieldElem}","page":"Fixed precision complex balls","title":"bessel_y","text":"bessel_y(nu::AcbFieldElem, x::AcbFieldElem)\n\nReturn the Bessel function Y_nu(x).\n\n\n\n\n\n","category":"method"},{"location":"Nemo/acb/","page":"Fixed precision complex balls","title":"Fixed precision complex balls","text":"bessel_i(::AcbFieldElem, ::AcbFieldElem)","category":"page"},{"location":"Nemo/acb/#bessel_i-Tuple{AcbFieldElem, AcbFieldElem}","page":"Fixed precision complex balls","title":"bessel_i","text":"bessel_i(nu::AcbFieldElem, x::AcbFieldElem)\n\nReturn the Bessel function I_nu(x).\n\n\n\n\n\n","category":"method"},{"location":"Nemo/acb/","page":"Fixed precision complex balls","title":"Fixed precision complex balls","text":"bessel_k(::AcbFieldElem, ::AcbFieldElem)","category":"page"},{"location":"Nemo/acb/#bessel_k-Tuple{AcbFieldElem, AcbFieldElem}","page":"Fixed precision complex balls","title":"bessel_k","text":"bessel_k(nu::AcbFieldElem, x::AcbFieldElem)\n\nReturn the Bessel function K_nu(x).\n\n\n\n\n\n","category":"method"},{"location":"Nemo/acb/","page":"Fixed precision complex balls","title":"Fixed precision complex balls","text":"hypergeometric_1f1(::AcbFieldElem, ::AcbFieldElem, ::AcbFieldElem)","category":"page"},{"location":"Nemo/acb/#hypergeometric_1f1-Tuple{AcbFieldElem, AcbFieldElem, AcbFieldElem}","page":"Fixed precision complex balls","title":"hypergeometric_1f1","text":"hypergeometric_1f1(a::AcbFieldElem, b::AcbFieldElem, x::AcbFieldElem)\n\nReturn the confluent hypergeometric function _1F_1(abx).\n\n\n\n\n\n","category":"method"},{"location":"Nemo/acb/","page":"Fixed precision complex balls","title":"Fixed precision complex balls","text":"hypergeometric_1f1_regularized(::AcbFieldElem, ::AcbFieldElem, ::AcbFieldElem)","category":"page"},{"location":"Nemo/acb/#hypergeometric_1f1_regularized-Tuple{AcbFieldElem, AcbFieldElem, AcbFieldElem}","page":"Fixed precision complex balls","title":"hypergeometric_1f1_regularized","text":"hypergeometric_1f1_regularized(a::AcbFieldElem, b::AcbFieldElem, x::AcbFieldElem)\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 precision complex balls","title":"Fixed precision complex balls","text":"hypergeometric_u(::AcbFieldElem, ::AcbFieldElem, ::AcbFieldElem)","category":"page"},{"location":"Nemo/acb/#hypergeometric_u-Tuple{AcbFieldElem, AcbFieldElem, AcbFieldElem}","page":"Fixed precision complex balls","title":"hypergeometric_u","text":"hypergeometric_u(a::AcbFieldElem, b::AcbFieldElem, x::AcbFieldElem)\n\nReturn the confluent hypergeometric function U(abx).\n\n\n\n\n\n","category":"method"},{"location":"Nemo/acb/","page":"Fixed precision complex balls","title":"Fixed precision complex balls","text":"hypergeometric_2f1(::AcbFieldElem, ::AcbFieldElem, ::AcbFieldElem, ::AcbFieldElem)","category":"page"},{"location":"Nemo/acb/#hypergeometric_2f1-NTuple{4, AcbFieldElem}","page":"Fixed precision complex balls","title":"hypergeometric_2f1","text":"hypergeometric_2f1(a::AcbFieldElem, b::AcbFieldElem, c::AcbFieldElem, x::AcbFieldElem; flags=0)\n\nReturn the Gauss hypergeometric function _2F_1(abcx).\n\n\n\n\n\n","category":"method"},{"location":"Nemo/acb/","page":"Fixed precision complex balls","title":"Fixed precision complex balls","text":"jacobi_theta(::AcbFieldElem, ::AcbFieldElem)","category":"page"},{"location":"Nemo/acb/#jacobi_theta-Tuple{AcbFieldElem, AcbFieldElem}","page":"Fixed precision complex balls","title":"jacobi_theta","text":"jacobi_theta(z::AcbFieldElem, tau::AcbFieldElem)\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 precision complex balls","title":"Fixed precision complex balls","text":"weierstrass_p(::AcbFieldElem, ::AcbFieldElem)","category":"page"},{"location":"Nemo/acb/#weierstrass_p-Tuple{AcbFieldElem, AcbFieldElem}","page":"Fixed precision complex balls","title":"weierstrass_p","text":"weierstrass_p(z::AcbFieldElem, tau::AcbFieldElem)\n\nReturn the Weierstrass elliptic function wp(ztau).\n\n\n\n\n\n","category":"method"},{"location":"Nemo/acb/","page":"Fixed precision complex balls","title":"Fixed precision complex balls","text":"Examples","category":"page"},{"location":"Nemo/acb/","page":"Fixed precision complex balls","title":"Fixed precision complex 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 precision complex balls","title":"Linear dependence","text":"","category":"section"},{"location":"Nemo/acb/","page":"Fixed precision complex balls","title":"Fixed precision complex balls","text":"lindep(::Vector{AcbFieldElem}, n::Int)","category":"page"},{"location":"Nemo/acb/#lindep-Tuple{Vector{AcbFieldElem}, Int64}","page":"Fixed precision complex balls","title":"lindep","text":"lindep(A::Vector{AcbFieldElem}, 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 precision complex balls","title":"Fixed precision complex balls","text":"lindep(A::Matrix{AcbFieldElem}, bits::Int)","category":"page"},{"location":"Nemo/acb/#lindep-Tuple{Matrix{AcbFieldElem}, Int64}","page":"Fixed precision complex balls","title":"lindep","text":"lindep(A::Matrix{AcbFieldElem}, 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 precision complex balls","title":"Fixed precision complex balls","text":"Examples","category":"page"},{"location":"Nemo/acb/","page":"Fixed precision complex balls","title":"Fixed precision complex balls","text":"julia> CC = AcbField(128)\nComplex Field with 128 bits of precision and error bounds\n\njulia> # These are two of the roots of x^5 + 3x + 1\n\njulia> a = CC(1.0050669478588622428791051888364775253, -0.93725915669289182697903585868761513585)\n[1.00506694785886230292248910700436681509 +/- 1.80e-40] - [0.937259156692891837181491609953809529543 +/- 7.71e-41]*im\n\njulia> b = CC(-0.33198902958450931620250069492231652319)\n-[0.331989029584509320880414406929048709571 +/- 3.62e-40]\n\njulia> V1 = [CC(1), a, a^2, a^3, a^4, a^5]; # We recover the polynomial from one root....\n\njulia> W = lindep(V1, 20)\n6-element Vector{ZZRingElem}:\n 1\n 3\n 0\n 0\n 0\n 1\n\njulia> V2 = [CC(1), b, b^2, b^3, b^4, b^5]; # ...or from two\n\njulia> Vs = [transpose(V1); transpose(V2)];\n\njulia> X = lindep(Vs, 20)\n6-element Vector{ZZRingElem}:\n 1\n 3\n 0\n 0\n 0\n 1","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::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\ndirect_sum(G::FinGenAbGroup...) -> FinGenAbGroup, Vector{FinGenAbGroupHom}\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 G_i, one should call direct_product(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\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{TorQuadModuleMap}\ndirect_sum(x::Vector{TorQuadModule}) -> TorQuadModule, Vector{TorQuadModuleMap}\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::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 [Oxl11].\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: quadratic space -> quadratic space, Map: quadratic space -> quadratic space])\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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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: quadratic space -> quadratic space, Map: quadratic space -> quadratic space])\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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\nFor a vector of maps fi : M -> Ni compute the map f : M -> prod Ni : m -> (fi(m))_i\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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\nExamples\n\njulia> L = special_linear_lie_algebra(QQ, 3);\n\njulia> V1 = exterior_power(standard_module(L), 2)[1]; # some module\n\njulia> V2 = symmetric_power(standard_module(L), 3)[1]; # some module\n\njulia> direct_sum(V1, V2)\nDirect sum module\n of dimension 13\n direct sum with direct summands\n 2nd exterior power of\n standard module\n 3rd symmetric power of\n standard module\nover special linear Lie algebra of degree 3 over QQ\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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 = free_module(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 = free_module(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 = free_module(QQ, 1);\n\njulia> M = free_module(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 = free_module(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 = Oscar.doctestsetup()","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":"[ES96]\n[OMdCS00]\n[Kah10]\n[EM16]\n[EM19]","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 generated by\n x^2 - y^3\n 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 generated by\n x[1]^3*x[5] - x[2]^3*x[5]\n x[3]*x[6] - x[4]*x[6]\n x[5]^2\n x[6]^2\n 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 generated by\n x - y\n x^3 - 1\n 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 generated by\n x + y\n\njulia> is_unital(I)\nfalse\n\njulia> J = ideal(R, [x^2-y^3, z^2])\nIdeal generated by\n x^2 - y^3\n 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 generated by\n x - y\n x^3 - 1\n 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 generated by\n x[1]^3*x[5] - x[2]^3*x[5]\n x[3]*x[6] - x[4]*x[6]\n x[5]^2\n x[6]^2\n x[5]*x[6]\n\njulia> is_cellular(I)\n(true, [1, 2, 3, 4])\n\njulia> cellular_hull(I)\nIdeal generated by\n x[6]\n 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 generated by\n x[1]^3*x[5] - x[2]^3*x[5]\n x[3]*x[6] - x[4]*x[6]\n x[5]^2\n x[6]^2\n x[5]*x[6]\n\njulia> cellular_associated_primes(I)\n5-element Vector{MPolyIdeal{AbstractAlgebra.Generic.MPoly{QQAbFieldElem{AbsSimpleNumFieldElem}}}}:\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 generated by\n x[1]^3*x[5] - x[2]^3*x[5]\n x[3]*x[6] - x[4]*x[6]\n x[5]^2\n x[6]^2\n x[5]*x[6]\n\njulia> cellular_minimal_associated_primes(I::MPolyIdeal{QQMPolyRingElem})\n1-element Vector{MPolyIdeal{AbstractAlgebra.Generic.MPoly{QQAbFieldElem{AbsSimpleNumFieldElem}}}}:\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 generated by\n x[1]^3*x[5] - x[2]^3*x[5]\n x[3]*x[6] - x[4]*x[6]\n x[5]^2\n x[6]^2\n x[5]*x[6]\n\njulia> cellular_primary_decomposition(I)\n5-element Vector{Tuple{MPolyIdeal{AbstractAlgebra.Generic.MPoly{QQAbFieldElem{AbsSimpleNumFieldElem}}}, MPolyIdeal{AbstractAlgebra.Generic.MPoly{QQAbFieldElem{AbsSimpleNumFieldElem}}}}}:\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 generated by\n x - y\n x^3 - 1\n y^2*z - z\n\njulia> binomial_primary_decomposition(I)\n3-element Vector{Tuple{MPolyIdeal{AbstractAlgebra.Generic.MPoly{QQAbFieldElem{AbsSimpleNumFieldElem}}}, MPolyIdeal{AbstractAlgebra.Generic.MPoly{QQAbFieldElem{AbsSimpleNumFieldElem}}}}}:\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":"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":"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)\nmatrix_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]))\nProjective algebraic set\n in projective 1-space over QQ with coordinates [x0, x1]\ndefined by ideal (x0, x1)\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 = proj(ideal([x0*x1^2, x2]))\nProjective scheme\n over rational field\ndefined by ideal (x0*x1^2, x2)\n\njulia> Y = algebraic_set(X)\nProjective algebraic set\n in projective 2-space over QQ with coordinates [x0, x1, x2]\ndefined by ideal (x0*x1^2, x2)\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)\nProjective algebraic 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\nProjective algebraic 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 homogeneous 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":"Experimental/BasisLieHighestWeight/user_functions/","page":"Functions for a monomial basis of highest weight modules","title":"Functions for a monomial basis of highest weight modules","text":"CurrentModule = Oscar\nDocTestSetup = Oscar.doctestsetup()","category":"page"},{"location":"Experimental/BasisLieHighestWeight/user_functions/#Functions-for-a-monomial-basis-of-highest-weight-modules","page":"Functions for a monomial basis of highest weight modules","title":"Functions for a monomial basis of highest weight modules","text":"","category":"section"},{"location":"Experimental/BasisLieHighestWeight/user_functions/","page":"Functions for a monomial basis of highest weight modules","title":"Functions for a monomial basis of highest weight modules","text":"basis_lie_highest_weight_operators\nbasis_lie_highest_weight\nbasis_lie_highest_weight_ffl\nbasis_lie_highest_weight_lusztig\nbasis_lie_highest_weight_nz\nbasis_lie_highest_weight_string","category":"page"},{"location":"Experimental/BasisLieHighestWeight/user_functions/#basis_lie_highest_weight_operators","page":"Functions for a monomial basis of highest weight modules","title":"basis_lie_highest_weight_operators","text":"basis_lie_highest_weight_operators(type::Symbol, rank::Int)\n\nLists the operators available for a given simple Lie algebra of type type_rank, together with their index. Operators f_alpha of negative roots are shown as the coefficients of the corresponding positive root. w.r.t. the simple roots alpha_i.\n\nExample\n\njulia> basis_lie_highest_weight_operators(:B, 2)\n4-element Vector{Tuple{Int64, Vector{QQFieldElem}}}:\n (1, [1, 0])\n (2, [0, 1])\n (3, [1, 1])\n (4, [1, 2])\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"function"},{"location":"Experimental/BasisLieHighestWeight/user_functions/#basis_lie_highest_weight","page":"Functions for a monomial basis of highest weight modules","title":"basis_lie_highest_weight","text":"basis_lie_highest_weight(type::Symbol, rank::Int, highest_weight::Vector{Int}; monomial_ordering::Symbol=:degrevlex)\nbasis_lie_highest_weight(type::Symbol, rank::Int, highest_weight::Vector{Int}, birational_sequence::Vector{Int}; monomial_ordering::Symbol=:degrevlex)\nbasis_lie_highest_weight(type::Symbol, rank::Int, highest_weight::Vector{Int}, birational_sequence::Vector{Vector{Int}}; monomial_ordering::Symbol=:degrevlex)\n\nComputes a monomial basis for the highest weight module with highest weight highest_weight (in terms of the fundamental weights omega_i), for a simple Lie algebra of type type_rank.\n\nIf no birational sequence is specified, all operators in the order of basis_lie_highest_weight_operators are used. A birational sequence of type Vector{Int} is a sequence of indices of operators in basis_lie_highest_weight_operators. A birational sequence of type Vector{Vector{Int}} is a sequence of weights in terms of the simple roots alpha_i.\n\nmonomial_ordering describes the monomial ordering used for the basis. If this is a weighted ordering, the height of the corresponding root is used as weight.\n\nExamples\n\njulia> base = basis_lie_highest_weight(:A, 2, [1, 1])\nMonomial basis of a highest weight module\n of highest weight [1, 1]\n of dimension 8\n with monomial ordering degrevlex([x1, x2, x3])\nover Lie algebra of type A2\n where the used birational sequence consists of the following roots (given as coefficients w.r.t. alpha_i):\n [1, 0]\n [0, 1]\n [1, 1]\n and the basis was generated by Minkowski sums of the bases of the following highest weight modules:\n [1, 0]\n [0, 1]\n\njulia> base = basis_lie_highest_weight(:A, 3, [2, 2, 3]; monomial_ordering = :lex)\nMonomial basis of a highest weight module\n of highest weight [2, 2, 3]\n of dimension 1260\n with monomial ordering lex([x1, x2, x3, x4, x5, x6])\nover Lie algebra of type A3\n where the used birational sequence consists of the following roots (given as coefficients w.r.t. alpha_i):\n [1, 0, 0]\n [0, 1, 0]\n [0, 0, 1]\n [1, 1, 0]\n [0, 1, 1]\n [1, 1, 1]\n and the basis was generated by Minkowski sums of the bases of the following highest weight modules:\n [1, 0, 0]\n [0, 1, 0]\n [0, 0, 1]\n\njulia> base = basis_lie_highest_weight(:A, 2, [1, 0], [1,2,1])\nMonomial basis of a highest weight module\n of highest weight [1, 0]\n of dimension 3\n with monomial ordering degrevlex([x1, x2, x3])\nover Lie algebra of type A2\n where the used birational sequence consists of the following roots (given as coefficients w.r.t. alpha_i):\n [1, 0]\n [0, 1]\n [1, 0]\n and the basis was generated by Minkowski sums of the bases of the following highest weight modules:\n [1, 0]\n\njulia> base = basis_lie_highest_weight(:A, 2, [1, 0], [[1,0], [0,1], [1,0]])\nMonomial basis of a highest weight module\n of highest weight [1, 0]\n of dimension 3\n with monomial ordering degrevlex([x1, x2, x3])\nover Lie algebra of type A2\n where the used birational sequence consists of the following roots (given as coefficients w.r.t. alpha_i):\n [1, 0]\n [0, 1]\n [1, 0]\n and the basis was generated by Minkowski sums of the bases of the following highest weight modules:\n [1, 0]\n\njulia> base = basis_lie_highest_weight(:C, 3, [1, 1, 1]; monomial_ordering = :lex)\nMonomial basis of a highest weight module\n of highest weight [1, 1, 1]\n of dimension 512\n with monomial ordering lex([x1, x2, x3, x4, x5, x6, x7, x8, x9])\nover Lie algebra of type C3\n where the used birational sequence consists of the following roots (given as coefficients w.r.t. alpha_i):\n [1, 0, 0]\n [0, 1, 0]\n [0, 0, 1]\n [1, 1, 0]\n [0, 1, 1]\n [1, 1, 1]\n [0, 2, 1]\n [1, 2, 1]\n [2, 2, 1]\n and the basis was generated by Minkowski sums of the bases of the following highest weight modules:\n [1, 0, 0]\n [0, 1, 0]\n [0, 0, 1]\n [0, 1, 1]\n [1, 1, 1]\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"function"},{"location":"Experimental/BasisLieHighestWeight/user_functions/#basis_lie_highest_weight_ffl","page":"Functions for a monomial basis of highest weight modules","title":"basis_lie_highest_weight_ffl","text":"basis_lie_highest_weight_ffl(type::Symbol, rank::Int, highest_weight::Vector{Int})\n\nComputes a monomial basis for the highest weight module with highest weight highest_weight (in terms of the fundamental weights omega_i), for a simple Lie algebra L of type type_rank.\n\nThen the birational sequence used consists of all operators in descening height of the corresponding root.\n\nThe monomial ordering is fixed to degrevlex. \n\nExamples\n\njulia> basis_lie_highest_weight_ffl(:A, 3, [1,1,1])\nMonomial basis of a highest weight module\n of highest weight [1, 1, 1]\n of dimension 64\n with monomial ordering degrevlex([x1, x2, x3, x4, x5, x6])\nover Lie algebra of type A3\n where the used birational sequence consists of the following roots (given as coefficients w.r.t. alpha_i):\n [1, 1, 1]\n [0, 1, 1]\n [1, 1, 0]\n [0, 0, 1]\n [0, 1, 0]\n [1, 0, 0]\n and the basis was generated by Minkowski sums of the bases of the following highest weight modules:\n [1, 0, 0]\n [0, 1, 0]\n [0, 0, 1]\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"function"},{"location":"Experimental/BasisLieHighestWeight/user_functions/#basis_lie_highest_weight_lusztig","page":"Functions for a monomial basis of highest weight modules","title":"basis_lie_highest_weight_lusztig","text":"basis_lie_highest_weight_lusztig(type::Symbol, rank::Int, highest_weight::Vector{Int}, reduced_expression::Vector{Int})\n\nComputes a monomial basis for the highest weight module with highest weight highest_weight (in terms of the fundamental weights omega_i), for a simple Lie algebra L of type type_rank.\n\nLet omega_0 = s_i_1 cdots s_i_N be a reduced expression of the longest element in the Weyl group of L given as indices i_1 dots i_N in reduced_expression. Then the birational sequence used consists of beta_1 dots beta_N where beta_1 = alpha_i_1 and \\betak := s{i1} \\cdots s{i{k-1}} \\alpha{i_k}$ for k = 2 dots N.\n\nThe monomial ordering is fixed to wdegrevlex (weighted degree reverse lexicographic order).\n\nExamples\n\njulia> base = basis_lie_highest_weight_lusztig(:D, 4, [1,1,1,1], [4,3,2,4,3,2,1,2,4,3,2,1])\nMonomial basis of a highest weight module\n of highest weight [1, 1, 1, 1]\n of dimension 4096\n with monomial ordering wdegrevlex([x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12], [1, 1, 3, 2, 2, 1, 5, 4, 3, 3, 2, 1])\nover Lie algebra of type D4\n where the used birational sequence consists of the following roots (given as coefficients w.r.t. alpha_i):\n [0, 0, 0, 1]\n [0, 0, 1, 0]\n [0, 1, 1, 1]\n [0, 1, 1, 0]\n [0, 1, 0, 1]\n [0, 1, 0, 0]\n [1, 2, 1, 1]\n [1, 1, 1, 1]\n [1, 1, 0, 1]\n [1, 1, 1, 0]\n [1, 1, 0, 0]\n [1, 0, 0, 0]\n and the basis was generated by Minkowski sums of the bases of the following highest weight modules:\n [1, 0, 0, 0]\n [0, 1, 0, 0]\n [0, 0, 1, 0]\n [0, 0, 0, 1]\n [0, 0, 1, 1]\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"function"},{"location":"Experimental/BasisLieHighestWeight/user_functions/#basis_lie_highest_weight_nz","page":"Functions for a monomial basis of highest weight modules","title":"basis_lie_highest_weight_nz","text":"basis_lie_highest_weight_nz(type::Symbol, rank::Int, highest_weight::Vector{Int}, reduced_expression::Vector{Int})\n\nComputes a monomial basis for the highest weight module with highest weight highest_weight (in terms of the fundamental weights omega_i), for a simple Lie algebra L of type type_rank.\n\nLet omega_0 = s_i_1 cdots s_i_N be a reduced expression of the longest element in the Weyl group of L given as indices i_1 dots i_N in reduced_expression. Then the birational sequence used consists of alpha_i_1 dots alpha_i_N.\n\nThe monomial ordering is fixed to degrevlex (degree reverse lexicographic order). \n\nExamples\n\njulia> basis_lie_highest_weight_nz(:C, 3, [1,1,1], [3,2,3,2,1,2,3,2,1])\nMonomial basis of a highest weight module\n of highest weight [1, 1, 1]\n of dimension 512\n with monomial ordering degrevlex([x1, x2, x3, x4, x5, x6, x7, x8, x9])\nover Lie algebra of type C3\n where the used birational sequence consists of the following roots (given as coefficients w.r.t. alpha_i):\n [0, 0, 1]\n [0, 1, 0]\n [0, 0, 1]\n [0, 1, 0]\n [1, 0, 0]\n [0, 1, 0]\n [0, 0, 1]\n [0, 1, 0]\n [1, 0, 0]\n and the basis was generated by Minkowski sums of the bases of the following highest weight modules:\n [1, 0, 0]\n [0, 1, 0]\n [0, 0, 1]\n\njulia> basis_lie_highest_weight_nz(:A, 4, [1,1,1,1], [4,3,2,1,2,3,4,3,2,3])\nMonomial basis of a highest weight module\n of highest weight [1, 1, 1, 1]\n of dimension 1024\n with monomial ordering degrevlex([x1, x2, x3, x4, x5, x6, x7, x8, x9, x10])\nover Lie algebra of type A4\n where the used birational sequence consists of the following roots (given as coefficients w.r.t. alpha_i):\n [0, 0, 0, 1]\n [0, 0, 1, 0]\n [0, 1, 0, 0]\n [1, 0, 0, 0]\n [0, 1, 0, 0]\n [0, 0, 1, 0]\n [0, 0, 0, 1]\n [0, 0, 1, 0]\n [0, 1, 0, 0]\n [0, 0, 1, 0]\n and the basis was generated by Minkowski sums of the bases of the following highest weight modules:\n [1, 0, 0, 0]\n [0, 1, 0, 0]\n [0, 0, 1, 0]\n [0, 0, 0, 1]\n [0, 1, 0, 1] \n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"function"},{"location":"Experimental/BasisLieHighestWeight/user_functions/#basis_lie_highest_weight_string","page":"Functions for a monomial basis of highest weight modules","title":"basis_lie_highest_weight_string","text":"basis_lie_highest_weight_string(type::Symbol, rank::Int, highest_weight::Vector{Int}, reduced_expression::Vector{Int})\n\nComputes a monomial basis for the highest weight module with highest weight highest_weight (in terms of the fundamental weights omega_i), for a simple Lie algebra L of type type_rank.\n\nLet omega_0 = s_i_1 cdots s_i_N be a reduced expression of the longest element in the Weyl group of L given as indices i_1 dots i_N in reduced_expression. Then the birational sequence used consists of alpha_i_1 dots alpha_i_N.\n\nThe monomial ordering is fixed to neglex (negative lexicographic order). \n\nExamples\n\njulia> basis_lie_highest_weight_string(:B, 3, [1,1,1], [3,2,3,2,1,2,3,2,1])\nMonomial basis of a highest weight module\n of highest weight [1, 1, 1]\n of dimension 512\n with monomial ordering neglex([x1, x2, x3, x4, x5, x6, x7, x8, x9])\nover Lie algebra of type B3\n where the used birational sequence consists of the following roots (given as coefficients w.r.t. alpha_i):\n [0, 0, 1]\n [0, 1, 0]\n [0, 0, 1]\n [0, 1, 0]\n [1, 0, 0]\n [0, 1, 0]\n [0, 0, 1]\n [0, 1, 0]\n [1, 0, 0]\n and the basis was generated by Minkowski sums of the bases of the following highest weight modules:\n [1, 0, 0]\n [0, 1, 0]\n [0, 0, 1]\n\njulia> basis_lie_highest_weight_string(:A, 4, [1,1,1,1], [4,3,2,1,2,3,4,3,2,3])\nMonomial basis of a highest weight module\n of highest weight [1, 1, 1, 1]\n of dimension 1024\n with monomial ordering neglex([x1, x2, x3, x4, x5, x6, x7, x8, x9, x10])\nover Lie algebra of type A4\n where the used birational sequence consists of the following roots (given as coefficients w.r.t. alpha_i):\n [0, 0, 0, 1]\n [0, 0, 1, 0]\n [0, 1, 0, 0]\n [1, 0, 0, 0]\n [0, 1, 0, 0]\n [0, 0, 1, 0]\n [0, 0, 0, 1]\n [0, 0, 1, 0]\n [0, 1, 0, 0]\n [0, 0, 1, 0]\n and the basis was generated by Minkowski sums of the bases of the following highest weight modules:\n [1, 0, 0, 0]\n [0, 1, 0, 0]\n [0, 0, 1, 0]\n [0, 0, 0, 1]\n [0, 1, 0, 1]\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"function"},{"location":"Experimental/BasisLieHighestWeight/user_functions/#Functions-for-Kodaira-embeddings","page":"Functions for a monomial basis of highest weight modules","title":"Functions for Kodaira embeddings","text":"","category":"section"},{"location":"Experimental/BasisLieHighestWeight/user_functions/","page":"Functions for a monomial basis of highest weight modules","title":"Functions for a monomial basis of highest weight modules","text":"basis_coordinate_ring_kodaira\nbasis_coordinate_ring_kodaira_ffl","category":"page"},{"location":"Experimental/BasisLieHighestWeight/user_functions/#basis_coordinate_ring_kodaira","page":"Functions for a monomial basis of highest weight modules","title":"basis_coordinate_ring_kodaira","text":"basis_coordinate_ring_kodaira(type::Symbol, rank::Int, highest_weight::Vector{Int}, degree::Int; monomial_ordering::Symbol=:degrevlex)\nbasis_coordinate_ring_kodaira(type::Symbol, rank::Int, highest_weight::Vector{Int}, degree::Int, birational_sequence::Vector{Int}; monomial_ordering::Symbol=:degrevlex)\nbasis_coordinate_ring_kodaira(type::Symbol, rank::Int, highest_weight::Vector{Int}, degree::Int, birational_sequence::Vector{Vector{Int}}; monomial_ordering::Symbol=:degrevlex)\n\nCompute monomial bases for the degree-truncated coordinate ring (for all degrees up to degree) of the Kodaira embedding of the generalized flag variety into the projective space of the highest weight module with highest weight highest_weight for a simple Lie algebra L of type type and rank rank. Furthermore, for each degree, return the monomials that are not contained in the Minkowski sum of the bases of the lower degrees.\n\nwarn: Warn\nCurrently, this function expects -w_0(lambda) instead of lambda as the highest_weight input. This might change in a minor release.\n\nIf no birational sequence is specified, all operators in the order of basis_lie_highest_weight_operators are used. A birational sequence of type Vector{Int} is a sequence of indices of operators in basis_lie_highest_weight_operators. A birational sequence of type Vector{Vector{Int}} is a sequence of weights in terms of the simple roots alpha_i.\n\nmonomial_ordering describes the monomial ordering used for the basis. If this is a weighted ordering, the height of the corresponding root is used as weight.\n\nExample\n\njulia> bases = basis_coordinate_ring_kodaira(:G, 2, [1,0], 6; monomial_ordering = :invlex)\n6-element Vector{Tuple{MonomialBasis, Vector{ZZMPolyRingElem}}}:\n (Monomial basis of a highest weight module with highest weight [1, 0] over Lie algebra of type G2, [1, x1, x3, x1*x3, x1^2*x3, x3*x4, x1*x3*x4])\n (Monomial basis of a highest weight module with highest weight [2, 0] over Lie algebra of type G2, [x4, x1*x4, x4^2, x3*x4^2, x1*x3*x4^2])\n (Monomial basis of a highest weight module with highest weight [3, 0] over Lie algebra of type G2, [x1^2*x4^2, x4^3, x1*x4^3, x4^4, x1*x4^4, x3*x4^4, x5, x2*x5, x1*x2*x5, x1^2*x2*x5, x3^2*x5, x1*x3^2*x5, x3^3*x5, x1*x3^3*x5])\n (Monomial basis of a highest weight module with highest weight [4, 0] over Lie algebra of type G2, [x4^5, x1*x4^5, x4^6, x3^2*x4*x5, x1*x3^2*x4*x5, x3^2*x4^2*x5, x3^3*x4^2*x5])\n (Monomial basis of a highest weight module with highest weight [5, 0] over Lie algebra of type G2, [x1^2*x4^6, x4^7, x1*x4^7, x2*x4^3*x5, x1*x2*x4^3*x5, x2*x3*x4^3*x5, x1*x2*x3*x4^3*x5, x1^2*x2*x3*x4^3*x5, x2*x3^2*x4^3*x5, x1*x2*x3^2*x4^3*x5, x1^2*x2*x3^2*x4^3*x5, x2*x4^4*x5])\n (Monomial basis of a highest weight module with highest weight [6, 0] over Lie algebra of type G2, [x4^9, x1*x3*x4^4*x5, x2*x4^5*x5, x3*x4^5*x5, x3^2*x4^5*x5, x2*x3^2*x4^5*x5, x1*x2*x3^2*x4^5*x5, x3^4*x4*x5^2])\n\njulia> [length(basis[2]) for basis in bases]\n6-element Vector{Int64}:\n 7\n 5\n 14\n 7\n 12\n 8\n\njulia> bases[end][1]\nMonomial basis of a highest weight module\n of highest weight [6, 0]\n of dimension 714\n with monomial ordering invlex([x1, x2, x3, x4, x5, x6])\nover Lie algebra of type G2\n where the used birational sequence consists of the following roots (given as coefficients w.r.t. alpha_i):\n [1, 0]\n [0, 1]\n [1, 1]\n [2, 1]\n [3, 1]\n [3, 2]\n and the basis was generated by Minkowski sums of the bases of the following highest weight modules:\n [1, 0]\n [2, 0]\n [3, 0]\n [4, 0]\n [5, 0]\n [6, 0]\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"function"},{"location":"Experimental/BasisLieHighestWeight/user_functions/#basis_coordinate_ring_kodaira_ffl","page":"Functions for a monomial basis of highest weight modules","title":"basis_coordinate_ring_kodaira_ffl","text":"basis_coordinate_ring_kodaira_ffl(type::Symbol, rank::Int, highest_weight::Vector{Int}, degree::Int; monomial_ordering::Symbol=:degrevlex)\n\nCompute monomial bases for the degree-truncated coordinate ring (for all degrees up to degree) of the Kodaira embedding of the generalized flag variety into the projective space of the highest weight module with highest weight highest_weight for a simple Lie algebra L of type type and rank rank. Furthermore, for each degree, return the monomials that are not contained in the Minkowski sum of the bases of the lower degrees.\n\nwarn: Warn\nCurrently, this function expects -w_0(lambda) instead of lambda as the highest_weight input. This might change in a minor release.\n\nThe the birational sequence used consists of all operators in descening height of the corresponding root, i.e. a \"good\" ordering.\n\nThe monomial ordering is fixed to degrevlex. \n\nExample\n\njulia> bases = basis_coordinate_ring_kodaira_ffl(:G, 2, [1,0], 6)\n6-element Vector{Tuple{MonomialBasis, Vector{ZZMPolyRingElem}}}:\n (Monomial basis of a highest weight module with highest weight [1, 0] over Lie algebra of type G2, [1, x6, x4, x3, x2, x1, x1*x6])\n (Monomial basis of a highest weight module with highest weight [2, 0] over Lie algebra of type G2, [])\n (Monomial basis of a highest weight module with highest weight [3, 0] over Lie algebra of type G2, [])\n (Monomial basis of a highest weight module with highest weight [4, 0] over Lie algebra of type G2, [])\n (Monomial basis of a highest weight module with highest weight [5, 0] over Lie algebra of type G2, [])\n (Monomial basis of a highest weight module with highest weight [6, 0] over Lie algebra of type G2, [])\n\njulia> [length(basis[2]) for basis in bases]\n6-element Vector{Int64}:\n 7\n 0\n 0\n 0\n 0\n 0\n\njulia> bases[end][1]\nMonomial basis of a highest weight module\n of highest weight [6, 0]\n of dimension 714\n with monomial ordering degrevlex([x1, x2, x3, x4, x5, x6])\nover Lie algebra of type G2\n where the used birational sequence consists of the following roots (given as coefficients w.r.t. alpha_i):\n [3, 2]\n [3, 1]\n [2, 1]\n [1, 1]\n [0, 1]\n [1, 0]\n and the basis was generated by Minkowski sums of the bases of the following highest weight modules:\n [1, 0]\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"function"},{"location":"Hecke/manual/orders/frac_ideals/#Fractional-ideals","page":"Fractional ideals","title":"Fractional ideals","text":"","category":"section"},{"location":"Hecke/manual/orders/frac_ideals/","page":"Fractional ideals","title":"Fractional ideals","text":"CurrentModule = Hecke","category":"page"},{"location":"Hecke/manual/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/manual/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 AbsSimpleNumFieldOrderFractionalIdeal.","category":"page"},{"location":"Hecke/manual/orders/frac_ideals/#Creation","page":"Fractional ideals","title":"Creation","text":"","category":"section"},{"location":"Hecke/manual/orders/frac_ideals/","page":"Fractional ideals","title":"Fractional ideals","text":"fractional_ideal(::AbsSimpleNumFieldOrder, ::ZZMatrix)\nfractional_ideal(::AbsSimpleNumFieldOrder, ::ZZMatrix, ::ZZRingElem)\nfractional_ideal(::AbsSimpleNumFieldOrder, ::QQMatrix)\nfractional_ideal(::AbsSimpleNumFieldOrder, ::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem})\nfractional_ideal(::AbsSimpleNumFieldOrder, ::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}, ::ZZRingElem)\nfractional_ideal(::AbsSimpleNumFieldOrder, ::AbsSimpleNumFieldElem)\nfractional_ideal(::AbsSimpleNumFieldOrder, ::AbsSimpleNumFieldOrderElem)\ninv(::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem})","category":"page"},{"location":"Hecke/manual/orders/frac_ideals/#fractional_ideal-Tuple{AbsSimpleNumFieldOrder, ZZMatrix}","page":"Fractional ideals","title":"fractional_ideal","text":"fractional_ideal(O::AbsNumFieldOrder, M::ZZMatrix, b::ZZRingElem; M_in_hnf::Bool = false) -> AbsNumFieldOrderFractionalIdeal\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/manual/orders/frac_ideals/#fractional_ideal-Tuple{AbsSimpleNumFieldOrder, ZZMatrix, ZZRingElem}","page":"Fractional ideals","title":"fractional_ideal","text":"fractional_ideal(O::AbsNumFieldOrder, M::ZZMatrix, b::ZZRingElem; M_in_hnf::Bool = false) -> AbsNumFieldOrderFractionalIdeal\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/manual/orders/frac_ideals/#fractional_ideal-Tuple{AbsSimpleNumFieldOrder, QQMatrix}","page":"Fractional ideals","title":"fractional_ideal","text":"fractional_ideal(O::AbsNumFieldOrder, M::QQMatrix) -> AbsNumFieldOrderFractionalIdeal\n\nCreates the fractional ideal of mathcal O generated by the elements corresponding to the rows of M.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/orders/frac_ideals/#fractional_ideal-Tuple{AbsSimpleNumFieldOrder, AbsSimpleNumFieldOrderIdeal}","page":"Fractional ideals","title":"fractional_ideal","text":"fractional_ideal(O::AbsSimpleNumFieldOrder, I::AbsNumFieldOrderIdeal) -> AbsSimpleNumFieldOrderFractionalIdeal\n\nThe fractional ideal of O generated by a Z-basis of I.\n\n\n\n\n\nfractional_ideal(O::AbsNumFieldOrder, I::AbsNumFieldOrderIdeal) -> AbsNumFieldOrderFractionalIdeal\n\nTurns the ideal I into a fractional ideal of mathcal O.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/orders/frac_ideals/#fractional_ideal-Tuple{AbsSimpleNumFieldOrder, AbsSimpleNumFieldOrderIdeal, ZZRingElem}","page":"Fractional ideals","title":"fractional_ideal","text":"fractional_ideal(O::AbsNumFieldOrder, I::AbsNumFieldOrderIdeal, b::ZZRingElem) -> AbsNumFieldOrderFractionalIdeal\n\nCreates the fractional ideal Ib of mathcal O.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/orders/frac_ideals/#fractional_ideal-Tuple{AbsSimpleNumFieldOrder, AbsSimpleNumFieldElem}","page":"Fractional ideals","title":"fractional_ideal","text":"fractional_ideal(O::AbsNumFieldOrder, a::AbsSimpleNumFieldElem) -> AbsNumFieldOrderFractionalIdeal\n\nCreates the principal fractional ideal (a) of mathcal O.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/orders/frac_ideals/#fractional_ideal-Tuple{AbsSimpleNumFieldOrder, AbsSimpleNumFieldOrderElem}","page":"Fractional ideals","title":"fractional_ideal","text":"fractional_ideal(O::AbsNumFieldOrder, a::AbsNumFieldOrderElem) -> AbsNumFieldOrderFractionalIdeal\n\nCreates the principal fractional ideal (a) of mathcal O.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/orders/frac_ideals/#inv-Tuple{AbsSimpleNumFieldOrderIdeal}","page":"Fractional ideals","title":"inv","text":"inv(A::AbsNumFieldOrderIdeal) -> AbsSimpleNumFieldOrderFractionalIdeal\n\nComputes the inverse of A, that is, the fractional ideal B such that AB = mathcal O_K.\n\n\n\n\n\n inv(a::LocalizedEuclideanRingElem{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\n","category":"method"},{"location":"Hecke/manual/orders/frac_ideals/#Arithmetic","page":"Fractional ideals","title":"Arithmetic","text":"","category":"section"},{"location":"Hecke/manual/orders/frac_ideals/","page":"Fractional ideals","title":"Fractional ideals","text":"All the normal operations are provided as well.","category":"page"},{"location":"Hecke/manual/orders/frac_ideals/","page":"Fractional ideals","title":"Fractional ideals","text":"inv(::AbsSimpleNumFieldOrderFractionalIdeal)\nintegral_split(::AbsSimpleNumFieldOrderFractionalIdeal)\nnumerator(::RelNumFieldOrderFractionalIdeal)\ndenominator(::RelNumFieldOrderFractionalIdeal)","category":"page"},{"location":"Hecke/manual/orders/frac_ideals/#inv-Tuple{AbsSimpleNumFieldOrderFractionalIdeal}","page":"Fractional ideals","title":"inv","text":"inv(A::AbsNumFieldOrderFractionalIdeal) -> AbsNumFieldOrderFractionalIdeal\n\nReturns the fractional ideal B such that AB = mathcal O.\n\n\n\n\n\n inv(a::LocalizedEuclideanRingElem{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\n","category":"method"},{"location":"Hecke/manual/orders/frac_ideals/#integral_split-Tuple{AbsSimpleNumFieldOrderFractionalIdeal}","page":"Fractional ideals","title":"integral_split","text":"integral_split(A::AbsNumFieldOrderFractionalIdeal) -> AbsNumFieldOrderIdeal, AbsNumFieldOrderIdeal\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/manual/orders/frac_ideals/#numerator-Tuple{Hecke.RelNumFieldOrderFractionalIdeal}","page":"Fractional ideals","title":"numerator","text":"numerator(a::RelNumFieldOrderFractionalIdeal) -> RelNumFieldOrderIdeal\n\nReturns the ideal d*a where d is the denominator of a.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/orders/frac_ideals/#denominator-Tuple{Hecke.RelNumFieldOrderFractionalIdeal}","page":"Fractional ideals","title":"denominator","text":"denominator(a::RelNumFieldOrderFractionalIdeal) -> 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/manual/orders/frac_ideals/#Miscaellenous","page":"Fractional ideals","title":"Miscaellenous","text":"","category":"section"},{"location":"Hecke/manual/orders/frac_ideals/","page":"Fractional ideals","title":"Fractional ideals","text":"order(::AbsSimpleNumFieldOrderFractionalIdeal)\nbasis_matrix(::AbsSimpleNumFieldOrderFractionalIdeal)\nbasis_mat_inv(::AbsSimpleNumFieldOrderFractionalIdeal)\nbasis(::AbsSimpleNumFieldOrderFractionalIdeal)\nnorm(::AbsSimpleNumFieldOrderFractionalIdeal)","category":"page"},{"location":"Hecke/manual/orders/frac_ideals/#order-Tuple{AbsSimpleNumFieldOrderFractionalIdeal}","page":"Fractional ideals","title":"order","text":"order(::Type{T} = BigInt, G::Group) where T\n\nReturn the order of G as an instance of T. If G is of infinite order, an InfiniteOrderError exception will be thrown. Use is_finite(G) to avoid this kind of exception. If the order does not fit into type T, an InexactError exception will be thrown.\n\n\n\n\n\norder(::Type{T} = BigInt, g::GroupElem) where T\n\nReturn the order of g as an instance of T. If g is of infinite order, an InfiniteOrderError exception will be thrown. Use is_finite_order(G) to avoid this kind of exception. If the order does not fit into type T, an InexactError exception will be thrown.\n\n\n\n\n\norder(a::AbsNumFieldOrderFractionalIdeal) -> AbsNumFieldOrder\n\nThe order that was used to define the ideal a.\n\n\n\n\n\norder(::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(::Type{T}, W::WeylGroup) where {T} -> T\n\nReturns the order of W.\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/orders/frac_ideals/#basis_matrix-Tuple{AbsSimpleNumFieldOrderFractionalIdeal}","page":"Fractional ideals","title":"basis_matrix","text":"basis_matrix(I::AbsNumFieldOrderFractionalIdeal) -> 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/manual/orders/frac_ideals/#basis_mat_inv-Tuple{AbsSimpleNumFieldOrderFractionalIdeal}","page":"Fractional ideals","title":"basis_mat_inv","text":"basis_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/manual/orders/frac_ideals/#basis-Tuple{AbsSimpleNumFieldOrderFractionalIdeal}","page":"Fractional ideals","title":"basis","text":"basis(I::AbsNumFieldOrderFractionalIdeal) -> Vector{AbsSimpleNumFieldElem}\n\nReturns the mathbf Z-basis of I.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/orders/frac_ideals/#norm-Tuple{AbsSimpleNumFieldOrderFractionalIdeal}","page":"Fractional ideals","title":"norm","text":"norm(I::AbsNumFieldOrderFractionalIdeal) -> QQFieldElem\n\nReturns the norm of I.\n\n\n\n\n\nnorm(a::RelNumFieldOrderIdeal) -> AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}\n\nReturns the norm of a.\n\n\n\n\n\nnorm(a::RelNumFieldOrderFractionalIdeal{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":"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 EuclideanRingResidueRingElem{T} EuclideanRingResidueRing{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);\n\njulia> g, s, t = gcdx(R(123), R(456))\n(1, 123456789012345678928, 41152263004115226322)","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/ToricIdealSheaves/","page":"Toric Ideal Sheaves (Experimental)","title":"Toric Ideal Sheaves (Experimental)","text":"CurrentModule = Oscar","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/ToricIdealSheaves/#Toric-Ideal-Sheaves-(Experimental)","page":"Toric Ideal Sheaves (Experimental)","title":"Toric Ideal Sheaves (Experimental)","text":"","category":"section"},{"location":"AlgebraicGeometry/ToricVarieties/ToricIdealSheaves/","page":"Toric Ideal Sheaves (Experimental)","title":"Toric Ideal Sheaves (Experimental)","text":"Ideal sheaves on toric varieties are currently in experimental state. Currently, we support the following functionality. Note that, as of October 2023, this is limited to smooth toric varieties.","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/ToricIdealSheaves/","page":"Toric Ideal Sheaves (Experimental)","title":"Toric Ideal Sheaves (Experimental)","text":"ideal_sheaf(td::ToricDivisor)\nideal_sheaf(X::NormalToricVariety, I::MPolyIdeal)","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/ToricIdealSheaves/#ideal_sheaf-Tuple{ToricDivisor}","page":"Toric Ideal Sheaves (Experimental)","title":"ideal_sheaf","text":"ideal_sheaf(td::ToricDivisor)\n\nReturn the ideal sheaf corresponding to a toric divisor.\n\nExamples\n\njulia> P3 = projective_space(NormalToricVariety, 3)\nNormal toric variety\n\njulia> td = toric_divisor(P3, [0, 1, 0, 0])\nTorus-invariant, prime divisor on a normal toric variety\n\njulia> ideal_sheaf(td)\nSheaf of ideals\n on normal, smooth toric variety\nwith restrictions\n 1: Ideal (x_2_1)\n 2: Ideal (x_2_2)\n 3: Ideal (1)\n 4: Ideal (x_2_4)\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/ToricIdealSheaves/#ideal_sheaf-Tuple{NormalToricVariety, MPolyIdeal}","page":"Toric Ideal Sheaves (Experimental)","title":"ideal_sheaf","text":"ideal_sheaf(X::NormalToricVariety, I::MPolyIdeal)\n\nCreate a sheaf of ideals on a toric variety X from a homogeneous ideal I in its cox_ring.\n\nExamples\n\njulia> P3 = projective_space(NormalToricVariety, 3)\nNormal toric variety\n\njulia> (x1,x2,x3,x4) = gens(cox_ring(P3));\n\njulia> I = ideal([x2,x3])\nIdeal generated by\n x2\n x3\n\njulia> IdealSheaf(P3, I);\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"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::AbstractUnitRange{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::AbstractUnitRange{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, <:AbstractUnitRange{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::AbstractUnitRange{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":"Experimental/FTheoryTools/generalities/","page":"Functionality for all F-theory models","title":"Functionality for all F-theory models","text":"CurrentModule = Oscar","category":"page"},{"location":"Experimental/FTheoryTools/generalities/#Functionality-for-all-F-theory-models","page":"Functionality for all F-theory models","title":"Functionality for all F-theory models","text":"","category":"section"},{"location":"Experimental/FTheoryTools/generalities/","page":"Functionality for all F-theory models","title":"Functionality for all F-theory models","text":"All F-theory models focus on elliptic (or genus-one) fibrations. Details depend on the specific way in which the fibration is constructed/described. Still, some functionality is common among all or at least the majority of all supported models. We will document such common functionality here.","category":"page"},{"location":"Experimental/FTheoryTools/generalities/#Family-of-Spaces","page":"Functionality for all F-theory models","title":"Family of Spaces","text":"","category":"section"},{"location":"Experimental/FTheoryTools/generalities/","page":"Functionality for all F-theory models","title":"Functionality for all F-theory models","text":"Many F-theory constructions (e.g. in the literature) work without fully specifying the base space of the elliptic fibrations. Put differently, those works consider an entire family of base spaces. We aim to support this data structure.","category":"page"},{"location":"Experimental/FTheoryTools/generalities/","page":"Functionality for all F-theory models","title":"Functionality for all F-theory models","text":"Note of caution: This data structure is subject to discussion. The exact implementation details may change drastically in the future. Use with care (as all experimental code, of course).","category":"page"},{"location":"Experimental/FTheoryTools/generalities/#Constructors","page":"Functionality for all F-theory models","title":"Constructors","text":"","category":"section"},{"location":"Experimental/FTheoryTools/generalities/","page":"Functionality for all F-theory models","title":"Functionality for all F-theory models","text":"We currently support the following constructor:","category":"page"},{"location":"Experimental/FTheoryTools/generalities/","page":"Functionality for all F-theory models","title":"Functionality for all F-theory models","text":"family_of_spaces(coordinate_ring::MPolyRing, grading::Matrix{Int64}, dim::Int)","category":"page"},{"location":"Experimental/FTheoryTools/generalities/#family_of_spaces-Tuple{MPolyRing, Matrix{Int64}, Int64}","page":"Functionality for all F-theory models","title":"family_of_spaces","text":"family_of_spaces(coordinate_ring::MPolyRing, grading::Matrix{Int64}, dim::Int)\n\nReturn a family of spaces that is (currently) used to build families of F-theory models, defined by using a family of base spaces for an elliptic fibration. It is specified by the following data:\n\nA polynomial ring. This may be thought of as the coordinate ring of the generic member in this family of spaces.\nA grading for this polynomial ring. This may be thought of as specifying certain line bundles on the generic member in this family of spaces. Of particular interest for F-theory is always the canonical bundle. For this reason, the first row is always thought of as grading the coordinate ring with regard to the canonical bundle. Or put differently, if a variable shares the weight 1 in the first row, then this means that we should think of this coordinate as a section of 1 times the canonical bundle.\nAn integer, which specifies the dimension of the generic member within this family of spaces.\n\nNote that the coordinate ring can have strictly more variables than the dimension. This is a desired feature for most, if not all, F-theory literature constructions.\n\njulia> coord_ring, _ = QQ[:f, :g, :Kbar, :u];\n\njulia> grading = [4 6 1 0; 0 0 0 1]\n2×4 Matrix{Int64}:\n 4 6 1 0\n 0 0 0 1\n\njulia> d = 3\n3\n\njulia> f = family_of_spaces(coord_ring, grading, d)\nA family of spaces of dimension d = 3\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/generalities/#Attributes","page":"Functionality for all F-theory models","title":"Attributes","text":"","category":"section"},{"location":"Experimental/FTheoryTools/generalities/","page":"Functionality for all F-theory models","title":"Functionality for all F-theory models","text":"We currently support the following attributes:","category":"page"},{"location":"Experimental/FTheoryTools/generalities/","page":"Functionality for all F-theory models","title":"Functionality for all F-theory models","text":"coordinate_ring(f::FamilyOfSpaces)\nweights(f::FamilyOfSpaces)\ndim(f::FamilyOfSpaces)\nirrelevant_ideal(f::FamilyOfSpaces)\nideal_of_linear_relations(f::FamilyOfSpaces)","category":"page"},{"location":"Experimental/FTheoryTools/generalities/#coordinate_ring-Tuple{FamilyOfSpaces}","page":"Functionality for all F-theory models","title":"coordinate_ring","text":"coordinate_ring(f::FamilyOfSpaces)\n\nReturn the coordinate ring of a generic member of the family of spaces.\n\njulia> ring, (f, g, Kbar, u) = QQ[:f, :g, :Kbar, :u]\n(Multivariate polynomial ring in 4 variables over QQ, QQMPolyRingElem[f, g, Kbar, u])\n\njulia> grading = [4 6 1 0; 0 0 0 1]\n2×4 Matrix{Int64}:\n 4 6 1 0\n 0 0 0 1\n\njulia> d = 3\n3\n\njulia> f = family_of_spaces(ring, grading, d)\nA family of spaces of dimension d = 3\n\njulia> coordinate_ring(f)\nMultivariate polynomial ring in 4 variables f, g, Kbar, u\n over rational field\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/generalities/#weights-Tuple{FamilyOfSpaces}","page":"Functionality for all F-theory models","title":"weights","text":"weights(f::FamilyOfSpaces)\n\nReturn the grading of the coordinate ring of a generic member of the family of spaces.\n\njulia> ring, (f, g, Kbar, u) = QQ[:f, :g, :Kbar, :u]\n(Multivariate polynomial ring in 4 variables over QQ, QQMPolyRingElem[f, g, Kbar, u])\n\njulia> grading = [4 6 1 0; 0 0 0 1]\n2×4 Matrix{Int64}:\n 4 6 1 0\n 0 0 0 1\n\njulia> d = 3\n3\n\njulia> f = family_of_spaces(ring, grading, d)\nA family of spaces of dimension d = 3\n\njulia> weights(f)\n2×4 Matrix{Int64}:\n 4 6 1 0\n 0 0 0 1\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/generalities/#dim-Tuple{FamilyOfSpaces}","page":"Functionality for all F-theory models","title":"dim","text":"dim(f::FamilyOfSpaces)\n\nReturn the dimension of the generic member of the family of spaces.\n\njulia> ring, (f, g, Kbar, u) = QQ[:f, :g, :Kbar, :u]\n(Multivariate polynomial ring in 4 variables over QQ, QQMPolyRingElem[f, g, Kbar, u])\n\njulia> grading = [4 6 1 0; 0 0 0 1]\n2×4 Matrix{Int64}:\n 4 6 1 0\n 0 0 0 1\n\njulia> d = 3\n3\n\njulia> f = family_of_spaces(ring, grading, d)\nA family of spaces of dimension d = 3\n\njulia> dim(f)\n3\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/generalities/#irrelevant_ideal-Tuple{FamilyOfSpaces}","page":"Functionality for all F-theory models","title":"irrelevant_ideal","text":"irrelevant_ideal(f::FamilyOfSpaces)\n\nReturn the equivalent of the irrelevant ideal for the generic member of the family of spaces.\n\njulia> coord_ring, (f, g, Kbar, u) = QQ[:f, :g, :Kbar, :u]\n(Multivariate polynomial ring in 4 variables over QQ, QQMPolyRingElem[f, g, Kbar, u])\n\njulia> grading = [4 6 1 0; 0 0 0 1]\n2×4 Matrix{Int64}:\n 4 6 1 0\n 0 0 0 1\n\njulia> d = 3\n3\n\njulia> f = family_of_spaces(coord_ring, grading, d)\nA family of spaces of dimension d = 3\n\njulia> irrelevant_ideal(f)\nIdeal generated by\n u\n Kbar\n g\n f\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/generalities/#ideal_of_linear_relations-Tuple{FamilyOfSpaces}","page":"Functionality for all F-theory models","title":"ideal_of_linear_relations","text":"ideal_of_linear_relations(f::FamilyOfSpaces)\n\nReturn the equivalent of the ideal of linear relations for the generic member of the family of spaces.\n\njulia> coord_ring, (f, g, Kbar, u) = QQ[:f, :g, :Kbar, :u]\n(Multivariate polynomial ring in 4 variables over QQ, QQMPolyRingElem[f, g, Kbar, u])\n\njulia> grading = [4 6 1 0; 0 0 0 1]\n2×4 Matrix{Int64}:\n 4 6 1 0\n 0 0 0 1\n\njulia> f = family_of_spaces(coord_ring, grading, 3)\nA family of spaces of dimension d = 3\n\njulia> ideal_of_linear_relations(f)\nIdeal generated by\n -5*f + 3*g + 2*Kbar\n -3*f + 2*g\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/generalities/#Printouts","page":"Functionality for all F-theory models","title":"Printouts","text":"","category":"section"},{"location":"Experimental/FTheoryTools/generalities/","page":"Functionality for all F-theory models","title":"Functionality for all F-theory models","text":"The user can decide to get information whenever a family of spaces is being used. To this end, one invokes set_verbosity_level(:FTheoryModelPrinter, 1). More information is available here.","category":"page"},{"location":"Experimental/FTheoryTools/generalities/#Attributes-of-all-(or-most)-F-theory-models","page":"Functionality for all F-theory models","title":"Attributes of all (or most) F-theory models","text":"","category":"section"},{"location":"Experimental/FTheoryTools/generalities/","page":"Functionality for all F-theory models","title":"Functionality for all F-theory models","text":"ambient_space(m::AbstractFTheoryModel)\nbase_space(m::AbstractFTheoryModel)\nfiber_ambient_space(m::AbstractFTheoryModel)\nexplicit_model_sections(m::AbstractFTheoryModel)\ndefining_section_parametrization(m::AbstractFTheoryModel)\nclasses_of_model_sections(m::AbstractFTheoryModel)\ndefining_classes(m::AbstractFTheoryModel)\ngauge_algebra(m::AbstractFTheoryModel)\nglobal_gauge_quotients(m::AbstractFTheoryModel)\nchern_class(m::AbstractFTheoryModel, k::Int; check::Bool = true)\nchern_classes(m::AbstractFTheoryModel; check::Bool = true)\neuler_characteristic(m::AbstractFTheoryModel; check::Bool = true)","category":"page"},{"location":"Experimental/FTheoryTools/generalities/#ambient_space-Tuple{AbstractFTheoryModel}","page":"Functionality for all F-theory models","title":"ambient_space","text":"ambient_space(m::AbstractFTheoryModel)\n\nReturn the ambient space of the F-theory 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> ambient_space(m)\nA family of spaces of dimension d = 5\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/generalities/#base_space-Tuple{AbstractFTheoryModel}","page":"Functionality for all F-theory models","title":"base_space","text":"base_space(m::AbstractFTheoryModel)\n\nReturn the base space of the F-theory 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> base_space(m)\nA family of spaces of dimension d = 3\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/generalities/#fiber_ambient_space-Tuple{AbstractFTheoryModel}","page":"Functionality for all F-theory models","title":"fiber_ambient_space","text":"fiber_ambient_space(m::AbstractFTheoryModel)\n\nReturn the fiber ambient space of an F-theory 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)\nNormal toric variety\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/generalities/#explicit_model_sections-Tuple{AbstractFTheoryModel}","page":"Functionality for all F-theory models","title":"explicit_model_sections","text":"explicit_model_sections(m::AbstractFTheoryModel)\n\nReturn the model sections in explicit form, that is as polynomials of the base space coordinates.\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> explicit_model_sections(t)\nDict{String, QQMPolyRingElem} with 9 entries:\n \"a6\" => 0\n \"a21\" => a21\n \"a3\" => w^2*a32\n \"w\" => w\n \"a2\" => w*a21\n \"a1\" => a1\n \"a4\" => w^3*a43\n \"a43\" => a43\n \"a32\" => a32\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/generalities/#defining_section_parametrization-Tuple{AbstractFTheoryModel}","page":"Functionality for all F-theory models","title":"defining_section_parametrization","text":"defining_section_parametrization(m::AbstractFTheoryModel)\n\nReturn the model sections in explicit form, that is as polynomials of the base space coordinates.\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> defining_section_parametrization(t)\nDict{String, MPolyRingElem} with 4 entries:\n \"a6\" => 0\n \"a3\" => w^2*a32\n \"a2\" => w*a21\n \"a4\" => w^3*a43\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/generalities/#classes_of_model_sections-Tuple{AbstractFTheoryModel}","page":"Functionality for all F-theory models","title":"classes_of_model_sections","text":"classes_of_model_sections(m::AbstractFTheoryModel)\n\nReturn the divisor classes of all model sections.\n\njulia> B3 = projective_space(NormalToricVariety, 3)\nNormal toric variety\n\njulia> w = torusinvariant_prime_divisors(B3)[1]\nTorus-invariant, prime divisor on a normal toric variety\n\njulia> t = literature_model(arxiv_id = \"1109.3454\", equation = \"3.1\", base_space = B3, defining_classes = Dict(\"w\" => w), completeness_check = false)\nConstruction over concrete base may lead to singularity enhancement. Consider computing singular_loci. However, this may take time!\n\nGlobal Tate model over a concrete base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)\n\njulia> classes_of_model_sections(t)\nDict{String, ToricDivisorClass} with 9 entries:\n \"a21\" => Divisor class on a normal toric variety\n \"a6\" => Divisor class on a normal toric variety\n \"a3\" => Divisor class on a normal toric variety\n \"w\" => Divisor class on a normal toric variety\n \"a2\" => Divisor class on a normal toric variety\n \"a1\" => Divisor class on a normal toric variety\n \"a43\" => Divisor class on a normal toric variety\n \"a4\" => Divisor class on a normal toric variety\n \"a32\" => Divisor class on a normal toric variety\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/generalities/#defining_classes-Tuple{AbstractFTheoryModel}","page":"Functionality for all F-theory models","title":"defining_classes","text":"defining_classes(m::AbstractFTheoryModel)\n\nReturn the defining divisor classes of the model in question.\n\njulia> B3 = projective_space(NormalToricVariety, 3)\nNormal toric variety\n\njulia> w = torusinvariant_prime_divisors(B3)[1]\nTorus-invariant, prime divisor on a normal toric variety\n\njulia> t = literature_model(arxiv_id = \"1109.3454\", equation = \"3.1\", base_space = B3, defining_classes = Dict(\"w\" => w), completeness_check = false)\nConstruction over concrete base may lead to singularity enhancement. Consider computing singular_loci. However, this may take time!\n\nGlobal Tate model over a concrete base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)\n\njulia> defining_classes(t)\nDict{String, ToricDivisorClass} with 2 entries:\n \"w\" => Divisor class on a normal toric variety\n \"Kbar\" => Divisor class on a normal toric variety\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/generalities/#gauge_algebra-Tuple{AbstractFTheoryModel}","page":"Functionality for all F-theory models","title":"gauge_algebra","text":"gauge_algebra(m::AbstractFTheoryModel)\n\nReturn the gauge algebra of the given model. If no gauge algebra is known, an error is raised. This information is typically available for all models, however.\n\njulia> t = literature_model(arxiv_id = \"1408.4808\", equation = \"3.190\", type = \"hypersurface\")\nAssuming that the first row of the given grading is the grading under Kbar\n\nHypersurface model over a not fully specified base\n\njulia> gauge_algebra(t)\nDirect sum Lie algebra\n of dimension 13\nwith summands\n sl_2\n sl_2\n sl_2\n sl_2\n linear Lie algebra\nover field of algebraic numbers\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/generalities/#global_gauge_quotients-Tuple{AbstractFTheoryModel}","page":"Functionality for all F-theory models","title":"global_gauge_quotients","text":"global_gauge_quotients(m::AbstractFTheoryModel)\n\nReturn list of lists of matrices, where each list of matrices corresponds to a gauge factor of the same index given by gauge_algebra(m). These matrices are elements of the center of the corresponding gauge factor and quotienting by them replicates the action of some discrete group on the center of the lie algebra. This list combined with gauge_algebra(m) completely determines the gauge group of the model. If no gauge quotients are known, an error is raised.\n\njulia> t = literature_model(arxiv_id = \"1408.4808\", equation = \"3.190\", type = \"hypersurface\")\nAssuming that the first row of the given grading is the grading under Kbar\n\nHypersurface model over a not fully specified base\n\njulia> global_gauge_quotients(t)\n5-element Vector{Vector{String}}:\n [\"-identity_matrix(C,2)\", \"-identity_matrix(C,2)\"]\n [\"-identity_matrix(C,2)\"]\n [\"-identity_matrix(C,2)\"]\n [\"-identity_matrix(C,2)\", \"-identity_matrix(C,2)\"]\n [\"-identity_matrix(C,1)\"]\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/generalities/#chern_class-Tuple{AbstractFTheoryModel, Int64}","page":"Functionality for all F-theory models","title":"chern_class","text":"chern_class(m::AbstractFTheoryModel, k::Int; check::Bool = true)\n\nIf the elliptically fibered n-fold Y_n underlying the F-theory model in question is given as a hypersurface in a toric ambient space, we can compute a cohomology class h on the toric ambient space X_Sigma, such that its restriction to Y_n is the k-th Chern class c_k of the tangent bundle of Y_n. If those assumptions are satisfied, this method returns this very cohomology class h, otherwise it raises an error.\n\nThe theory guarantees that the implemented algorithm works for toric ambient spaces which are smooth and complete. The check for completeness can be very time consuming. This check can be switched off by setting the optional argument check to the value false, as demonstrated below.\n\njulia> qsm_model = literature_model(arxiv_id = \"1903.00009\", model_parameters = Dict(\"k\" => 4))\nHypersurface model over a concrete base\n\njulia> h = chern_class(qsm_model, 4; check = false);\n\njulia> is_trivial(h)\nfalse\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/generalities/#chern_classes-Tuple{AbstractFTheoryModel}","page":"Functionality for all F-theory models","title":"chern_classes","text":"chern_classes(m::AbstractFTheoryModel; check::Bool = true)\n\nIf the elliptically fibered n-fold Y_n underlying the F-theory model in question is given as a hypersurface in a toric ambient space, we can compute a cohomology class h on the toric ambient space X_Sigma, such that its restriction to Y_n is the k-th Chern class c_k of the tangent bundle of Y_n. If those assumptions are satisfied, this method returns a vector with the cohomology classes corresponding to all non-trivial Chern classes c_k of Y_n. Otherwise, this methods raises an error.\n\nAs of right now, this method is computationally expensive for involved toric ambient spaces, such as in the example below.\n\nThe theory guarantees that the implemented algorithm works for toric ambient spaces which are simplicial and complete. The check for completeness can be very time consuming. This check can be switched off by setting the optional argument check to the value false, as demonstrated below.\n\njulia> qsm_model = literature_model(arxiv_id = \"1903.00009\", model_parameters = Dict(\"k\" => 4))\nHypersurface model over a concrete base\n\njulia> h = chern_classes(qsm_model; check = false);\n\njulia> is_one(polynomial(h[1]))\ntrue\n\njulia> is_trivial(h[2])\ntrue\n\njulia> is_trivial(h[3])\nfalse\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/generalities/#euler_characteristic-Tuple{AbstractFTheoryModel}","page":"Functionality for all F-theory models","title":"euler_characteristic","text":"euler_characteristic(m::AbstractFTheoryModel; check::Bool = true)\n\nIf the elliptically fibered n-fold Y_n underlying the F-theory model in question is given as a hypersurface in a toric ambient space, we can compute the Euler characteristic. If this assumptions is satisfied, this method returns the Euler characteristic, otherwise it raises an error.\n\njulia> qsm_model = literature_model(arxiv_id = \"1903.00009\", model_parameters = Dict(\"k\" => 4))\nHypersurface model over a concrete base\n\njulia> h = euler_characteristic(qsm_model; check = false)\n378\n\njulia> h = euler_characteristic(qsm_model; check = false)\n378\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/generalities/#Properties-of-all-(or-most)-F-theory-models","page":"Functionality for all F-theory models","title":"Properties of all (or most) F-theory models","text":"","category":"section"},{"location":"Experimental/FTheoryTools/generalities/","page":"Functionality for all F-theory models","title":"Functionality for all F-theory models","text":"is_base_space_fully_specified(m::AbstractFTheoryModel)\nis_calabi_yau(m::AbstractFTheoryModel; check::Bool = true)\nis_partially_resolved(m::AbstractFTheoryModel)\nverify_euler_characteristic_from_hodge_numbers(m::AbstractFTheoryModel; check::Bool = true)","category":"page"},{"location":"Experimental/FTheoryTools/generalities/#is_base_space_fully_specified-Tuple{AbstractFTheoryModel}","page":"Functionality for all F-theory models","title":"is_base_space_fully_specified","text":"is_base_space_fully_specified(m::AbstractFTheoryModel)\n\nReturn true if the F-theory 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> is_base_space_fully_specified(t)\nfalse\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/generalities/#is_calabi_yau-Tuple{AbstractFTheoryModel}","page":"Functionality for all F-theory models","title":"is_calabi_yau","text":"is_calabi_yau(m::AbstractFTheoryModel; check::Bool = true)\n\nVerify if the first Chern class of the tangent bundle of the F-theory geometry Y_n vanishes. If so, this confirms that this geometry is indeed Calabi-Yau, as required by the reasoning of F-theory.\n\nThe implemented algorithm works for hypersurface, Weierstrass and global Tate models, which are defined in a toric ambient space. It expresses c_1(Y_n) as the restriction of a cohomology class h on the toric ambient space. This in turn requires that the toric ambient space is simplicial and complete. We provide a switch to turn off these computationally very demanding checks. This is demonstrated in the example below.\n\njulia> qsm_model = literature_model(arxiv_id = \"1903.00009\", model_parameters = Dict(\"k\" => 4))\nHypersurface model over a concrete base\n\njulia> is_calabi_yau(qsm_model, check = false)\ntrue\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/generalities/#is_partially_resolved-Tuple{AbstractFTheoryModel}","page":"Functionality for all F-theory models","title":"is_partially_resolved","text":"is_partially_resolved(m::AbstractFTheoryModel)\n\nReturn true if resolution techniques were applied to the F-theory model, thereby potentially resolving its singularities. Otherwise, return false.\n\njulia> B3 = projective_space(NormalToricVariety, 3)\nNormal toric variety\n\njulia> w = torusinvariant_prime_divisors(B3)[1]\nTorus-invariant, prime divisor on a normal toric variety\n\njulia> t = literature_model(arxiv_id = \"1109.3454\", equation = \"3.1\", base_space = B3, defining_classes = Dict(\"w\" => w), completeness_check = false)\nConstruction over concrete base may lead to singularity enhancement. Consider computing singular_loci. However, this may take time!\n\nGlobal Tate model over a concrete base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)\n\njulia> is_partially_resolved(t)\nfalse\n\njulia> t2 = blow_up(t, [\"x\", \"y\", \"x1\"]; coordinate_name = \"e1\")\nPartially resolved global Tate model over a concrete base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)\n\njulia> is_partially_resolved(t2)\ntrue\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/generalities/#verify_euler_characteristic_from_hodge_numbers-Tuple{AbstractFTheoryModel}","page":"Functionality for all F-theory models","title":"verify_euler_characteristic_from_hodge_numbers","text":"verify_euler_characteristic_from_hodge_numbers(m::AbstractFTheoryModel; check::Bool = true)\n\nVerify if the Euler characteristic, as computed from integrating the 4-th Chern class, agrees with the results obtained from using the alternating sum of the Hodge numbers. If so, this method returns true. However, should information be missing, (e.g. some Hodge numbers), or the dimension of the F-theory model differ form 4, then this method raises an error.\n\njulia> qsm_model = literature_model(arxiv_id = \"1903.00009\", model_parameters = Dict(\"k\" => 4))\nHypersurface model over a concrete base\n\njulia> verify_euler_characteristic_from_hodge_numbers(qsm_model, check = false)\ntrue\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/generalities/#Methods-for-all-(or-most)-F-theory-models","page":"Functionality for all F-theory models","title":"Methods for all (or most) F-theory models","text":"","category":"section"},{"location":"Experimental/FTheoryTools/generalities/","page":"Functionality for all F-theory models","title":"Functionality for all F-theory models","text":"blow_up(m::AbstractFTheoryModel, ideal_gens::Vector{String}; coordinate_name::String = \"e\")\nblow_up(m::AbstractFTheoryModel, I::MPolyIdeal; coordinate_name::String = \"e\")\nblow_up(m::AbstractFTheoryModel, I::AbsIdealSheaf; coordinate_name::String = \"e\")\ntune(m::AbstractFTheoryModel, p::MPolyRingElem; completeness_check::Bool = true)\nput_over_concrete_base(m::AbstractFTheoryModel, concrete_data::Dict{String, <:Any}; completeness_check::Bool = true)","category":"page"},{"location":"Experimental/FTheoryTools/generalities/#blow_up-Tuple{AbstractFTheoryModel, Vector{String}}","page":"Functionality for all F-theory models","title":"blow_up","text":"blow_up(m::AbstractFTheoryModel, ideal_gens::Vector{String}; coordinate_name::String = \"e\")\n\nResolve an F-theory model by blowing up a locus in the ambient space.\n\nExamples\n\njulia> B3 = projective_space(NormalToricVariety, 3)\nNormal toric variety\n\njulia> w = torusinvariant_prime_divisors(B3)[1]\nTorus-invariant, prime divisor on a normal toric variety\n\njulia> t = literature_model(arxiv_id = \"1109.3454\", equation = \"3.1\", base_space = B3, defining_classes = Dict(\"w\" => w), completeness_check = false)\nConstruction over concrete base may lead to singularity enhancement. Consider computing singular_loci. However, this may take time!\n\nGlobal Tate model over a concrete base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)\n\njulia> blow_up(t, [\"x\", \"y\", \"x1\"]; coordinate_name = \"e1\")\nPartially resolved global Tate model over a concrete base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)\n\nHere is an example for a Weierstrass model.\n\nExamples\n\njulia> B2 = projective_space(NormalToricVariety, 2)\nNormal toric variety\n\njulia> b = torusinvariant_prime_divisors(B2)[1]\nTorus-invariant, prime divisor on a normal toric variety\n\njulia> w = literature_model(arxiv_id = \"1208.2695\", equation = \"B.19\", base_space = B2, defining_classes = Dict(\"b\" => b), completeness_check = false)\nConstruction over concrete base may lead to singularity enhancement. Consider computing singular_loci. However, this may take time!\n\nWeierstrass model over a concrete base -- U(1) Weierstrass model based on arXiv paper 1208.2695 Eq. (B.19)\n\njulia> blow_up(w, [\"x\", \"y\", \"x1\"]; coordinate_name = \"e1\")\nPartially resolved Weierstrass model over a concrete base -- U(1) Weierstrass model based on arXiv paper 1208.2695 Eq. (B.19)\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/generalities/#blow_up-Tuple{AbstractFTheoryModel, MPolyIdeal}","page":"Functionality for all F-theory models","title":"blow_up","text":"blow_up(m::AbstractFTheoryModel, I::MPolyIdeal; coordinate_name::String = \"e\")\n\nResolve an F-theory model by blowing up a locus in the ambient space.\n\nExamples\n\njulia> B3 = projective_space(NormalToricVariety, 3)\nNormal toric variety\n\njulia> w = torusinvariant_prime_divisors(B3)[1]\nTorus-invariant, prime divisor on a normal toric variety\n\njulia> t = literature_model(arxiv_id = \"1109.3454\", equation = \"3.1\", base_space = B3, defining_classes = Dict(\"w\" => w), completeness_check = false)\nConstruction over concrete base may lead to singularity enhancement. Consider computing singular_loci. However, this may take time!\n\nGlobal Tate model over a concrete base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)\n\njulia> x1, x2, x3, x4, x, y, z = gens(cox_ring(ambient_space(t)))\n7-element Vector{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}:\n x1\n x2\n x3\n x4\n x\n y\n z\n\njulia> blow_up(t, ideal([x, y, x1]); coordinate_name = \"e1\")\nPartially resolved global Tate model over a concrete base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/generalities/#blow_up-Tuple{AbstractFTheoryModel, Oscar.AbsIdealSheaf}","page":"Functionality for all F-theory models","title":"blow_up","text":"blow_up(m::AbstractFTheoryModel, I::AbsIdealSheaf; coordinate_name::String = \"e\")\n\nResolve an F-theory model by blowing up a locus in the ambient space. For this method, the blowup center is encoded by an ideal sheaf.\n\nExamples\n\njulia> B3 = projective_space(NormalToricVariety, 3)\nNormal toric variety\n\njulia> w = torusinvariant_prime_divisors(B3)[1]\nTorus-invariant, prime divisor on a normal toric variety\n\njulia> t = literature_model(arxiv_id = \"1109.3454\", equation = \"3.1\", base_space = B3, defining_classes = Dict(\"w\" => w), completeness_check = false)\nConstruction over concrete base may lead to singularity enhancement. Consider computing singular_loci. However, this may take time!\n\nGlobal Tate model over a concrete base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)\n\njulia> x1, x2, x3, x4, x, y, z = gens(cox_ring(ambient_space(t)))\n7-element Vector{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}:\n x1\n x2\n x3\n x4\n x\n y\n z\n\njulia> blowup_center = ideal_sheaf(ambient_space(t), ideal([x, y, x1]))\nSheaf of ideals\n on normal, simplicial toric variety\nwith restrictions\n 1: Ideal (x_5_1, x_4_1, x_1_1)\n 2: Ideal (1)\n 3: Ideal (x_5_3, x_4_3, x_1_3)\n 4: Ideal (x_5_4, x_4_4, x_1_4)\n 5: Ideal (1)\n 6: Ideal (1)\n 7: Ideal (1)\n 8: Ideal (1)\n 9: Ideal (1)\n 10: Ideal (1)\n 11: Ideal (1)\n 12: Ideal (1)\n\njulia> blow_up(t, blowup_center; coordinate_name = \"e1\")\nPartially resolved global Tate model over a concrete base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/generalities/#tune-Tuple{AbstractFTheoryModel, MPolyRingElem}","page":"Functionality for all F-theory models","title":"tune","text":"tune(m::AbstractFTheoryModel, p::MPolyRingElem; completeness_check::Bool = true)\n\nTune an F-theory model by replacing the hypersurface equation by a custom (polynomial) equation. The latter can be any type of polynomial: a Tate polynomial, a Weierstrass polynomial or a general polynomial. We do not conduct checks to tell which type the provided polynomial is. Consequently, this tuning will always return a hypersurface model.\n\nNote that there is less functionality for hypersurface models than for Weierstrass or Tate models. For instance, singular_loci can (currently) not be computed for hypersurface models.\n\nExamples\n\njulia> B3 = projective_space(NormalToricVariety, 3)\nNormal toric variety\n\njulia> w = torusinvariant_prime_divisors(B3)[1]\nTorus-invariant, prime divisor on a normal toric variety\n\njulia> t = literature_model(arxiv_id = \"1109.3454\", equation = \"3.1\", base_space = B3, defining_classes = Dict(\"w\" => w), completeness_check = false)\nConstruction over concrete base may lead to singularity enhancement. Consider computing singular_loci. However, this may take time!\n\nGlobal Tate model over a concrete base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)\n\njulia> x1, x2, x3, x4, x, y, z = gens(parent(tate_polynomial(t)))\n7-element Vector{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}:\n x1\n x2\n x3\n x4\n x\n y\n z\n\njulia> new_tate_polynomial = x^3 - y^2 - x * y * z * x4^4\n-x4^4*x*y*z + x^3 - y^2\n\njulia> tuned_t = tune(t, new_tate_polynomial)\nHypersurface model over a concrete base\n\njulia> hypersurface_equation(tuned_t) == new_tate_polynomial\ntrue\n\njulia> base_space(tuned_t) == base_space(t)\ntrue\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/generalities/#put_over_concrete_base-Tuple{AbstractFTheoryModel, Dict{String}}","page":"Functionality for all F-theory models","title":"put_over_concrete_base","text":"put_over_concrete_base(m::AbstractFTheoryModel, concrete_data::Dict{String, <:Any}; completeness_check::Bool = true)\n\nPut an F-theory model defined over a family of spaces over a concrete base.\n\nCurrently, this functionality is limited to Tate and Weierstrass models.\n\nExamples\n\njulia> t = literature_model(arxiv_id = \"1109.3454\", equation = \"3.1\", completeness_check = false)\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> B3 = projective_space(NormalToricVariety, 3)\nNormal toric variety\n\njulia> w_bundle = toric_line_bundle(torusinvariant_prime_divisors(B3)[1])\nToric line bundle on a normal toric variety\n\njulia> kbar = anticanonical_bundle(B3)\nToric line bundle on a normal toric variety\n\njulia> w = generic_section(w_bundle);\n\njulia> a21 = generic_section(kbar^2 * w_bundle^(-1));\n\njulia> a32 = generic_section(kbar^3 * w_bundle^(-2));\n\njulia> a43 = generic_section(kbar^4 * w_bundle^(-3));\n\njulia> t2 = put_over_concrete_base(t, Dict(\"base\" => B3, \"w\" => w, \"a21\" => a21, \"a32\" => a32, \"a43\" => a43), completeness_check = false)\nGlobal Tate model over a concrete base\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"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":"AlgebraicGeometry/Surfaces/duValSing/","page":"Classifier/identifier specifically for du Val singularities","title":"Classifier/identifier specifically for du Val singularities","text":"CurrentModule = Oscar","category":"page"},{"location":"AlgebraicGeometry/Surfaces/duValSing/#Classifier/identifier-specifically-for-du-Val-singularities","page":"Classifier/identifier specifically for du Val singularities","title":"Classifier/identifier specifically for du Val singularities","text":"","category":"section"},{"location":"AlgebraicGeometry/Surfaces/duValSing/","page":"Classifier/identifier specifically for du Val singularities","title":"Classifier/identifier specifically for du Val singularities","text":"has_du_val_singularities\nis_du_val_singularity\ndecide_du_val_singularity","category":"page"},{"location":"AlgebraicGeometry/Surfaces/duValSing/#has_du_val_singularities","page":"Classifier/identifier specifically for du Val singularities","title":"has_du_val_singularities","text":"has_du_val_singularities(X::Scheme)\n\nReturn whether the given X has at most du Val (surface) singularities.\n\nExample:\n\njulia> R,(x,y,z,w) = QQ[:x, :y, :z, :w]\n(Multivariate polynomial ring in 4 variables over QQ, QQMPolyRingElem[x, y, z, w])\n\njulia> I = ideal(R,[w,x^2+y^3+z^4])\nIdeal generated by\n w\n x^2 + y^3 + z^4\n\njulia> Rq, _ = quo(R,I)\n(Quotient of multivariate polynomial ring by ideal (w, x^2 + y^3 + z^4), Map: R -> Rq)\n\njulia> X = spec(Rq)\nSpectrum\n of quotient\n of multivariate polynomial ring in 4 variables x, y, z, w\n over rational field\n by ideal (w, x^2 + y^3 + z^4)\n\njulia> has_du_val_singularities(X)\ntrue\n\n\n\n\n\n\n","category":"function"},{"location":"AlgebraicGeometry/Surfaces/duValSing/#is_du_val_singularity","page":"Classifier/identifier specifically for du Val singularities","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\nis_du_val_singularity(X::AbsAffineScheme, I::Ideal)\n\nReturn whether the given X has at most du Val (surface) singularities at the geometric points specified by the ideal I.\n\nNote: For the ideal I in a ring R, dim(R/I) = 0 is asserted\n\nExample:\n\njulia> R,(x,y,z,w) = QQ[:x, :y, :z, :w]\n(Multivariate polynomial ring in 4 variables over QQ, QQMPolyRingElem[x, y, z, w])\n\njulia> I = ideal(R,[w,x^2+y^3+z^4])\nIdeal generated by\n w\n x^2 + y^3 + z^4\n\njulia> Rq, _ = quo(R,I)\n(Quotient of multivariate polynomial ring by ideal (w, x^2 + y^3 + z^4), Map: R -> Rq)\n\njulia> J = ideal(R,[x,y,z,w])\nIdeal generated by\n x\n y\n z\n w\n\njulia> X = spec(Rq)\nSpectrum\n of quotient\n of multivariate polynomial ring in 4 variables x, y, z, w\n over rational field\n by ideal (w, x^2 + y^3 + z^4)\n\njulia> is_du_val_singularity(X,J)\ntrue\n\n\n\n\n\n\n","category":"function"},{"location":"AlgebraicGeometry/Surfaces/duValSing/#decide_du_val_singularity","page":"Classifier/identifier specifically for du Val singularities","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\ndecide_du_val_singularity(X::AbsAffineScheme, I::Ideal)\n\nReturn a vector of tuples T with the following data:\n\nT[1]::Bool answers whether X has at most du Val (surface) singularities at the geometric points specified by the ideal I.\nT[2]::Ideal is I_P the associated prime of I (possibly over a suitable field extension) describing some geometrically irreducible point\nT[3]::Tuple contains the type of the singularity at P e.g. (:A, 3)\nT[4]::Int number of conjugate points\n\nIf X has a least one singularity which is not du Val, the returned vector contains a single tuple T, with the following values:\n\nT[1] is false\nT[2] represents a point at which some non-du-Val singularity is present\nT[3] is the empty tuple\nT[4] = 1\n\nNote: For the ideal I in a ring R, dim(R/I) = 0 is asserted\n\nExample:\n\njulia> R,(x,y,z,w) = QQ[:x, :y, :z, :w]\n(Multivariate polynomial ring in 4 variables over QQ, QQMPolyRingElem[x, y, z, w])\n\njulia> I = ideal(R,[w,x^2+y^3+z^4])\nIdeal generated by\n w\n x^2 + y^3 + z^4\n\njulia> Rq, _ = quo(R,I)\n(Quotient of multivariate polynomial ring by ideal (w, x^2 + y^3 + z^4), Map: R -> Rq)\n\njulia> J = ideal(R,[x,y,z,w])\nIdeal generated by\n x\n y\n z\n w\n\njulia> X = spec(Rq)\nSpectrum\n of quotient\n of multivariate polynomial ring in 4 variables x, y, z, w\n over rational field\n by ideal (w, x^2 + y^3 + z^4)\n\njulia> decide_du_val_singularity(X,J)\n1-element Vector{Any}:\n (true, Ideal (w, z, y, x), (:E, 6), 1)\n\n\n\n\n\n","category":"function"},{"location":"Hecke/manual/orders/orders/#Orders","page":"Orders","title":"Orders","text":"","category":"section"},{"location":"Hecke/manual/orders/orders/","page":"Orders","title":"Orders","text":"CurrentModule = Hecke","category":"page"},{"location":"Hecke/manual/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/manual/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/manual/orders/orders/#Creation-and-basic-properties","page":"Orders","title":"Creation and basic properties","text":"","category":"section"},{"location":"Hecke/manual/orders/orders/","page":"Orders","title":"Orders","text":"Order(::AbsSimpleNumField, ::Vector{AbsSimpleNumFieldElem})\nOrder(::AbsSimpleNumField, ::QQMatrix)\nOrder(::AbsSimpleNumFieldOrderFractionalIdeal)\nEquationOrder(::AbsSimpleNumField)\nMaximalOrder(::AbsSimpleNumField)\nMaximalOrder(::AbsSimpleNumFieldOrder)\nlll(::AbsSimpleNumFieldOrder)\nany_order(K::AbsSimpleNumField)","category":"page"},{"location":"Hecke/manual/orders/orders/#Order-Tuple{AbsSimpleNumField, Vector{AbsSimpleNumFieldElem}}","page":"Orders","title":"Order","text":"Order(a::Vector{AbsSimpleNumFieldElem}; check::Bool = true, cached::Bool = true, isbasis::Bool = false) -> AbsSimpleNumFieldOrder\nOrder(K::AbsSimpleNumField, a::Vector{AbsSimpleNumFieldElem}; check::Bool = true, cached::Bool = true, isbasis::Bool = false) -> AbsSimpleNumFieldOrder\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/manual/orders/orders/#Order-Tuple{AbsSimpleNumField, QQMatrix}","page":"Orders","title":"Order","text":"Order(K::AbsSimpleNumField, A::QQMatrix; check::Bool = true) -> AbsSimpleNumFieldOrder\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(K::AbsSimpleNumField, A::QQMatrix; check::Bool = true) -> AbsSimpleNumFieldOrder\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/manual/orders/orders/#Order-Tuple{AbsSimpleNumFieldOrderFractionalIdeal}","page":"Orders","title":"Order","text":"Order(K::AbsSimpleNumField, A::ZZMatrix, check::Bool = true) -> AbsSimpleNumFieldOrder\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::AbstractAssociativeAlgebra{<: 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/manual/orders/orders/#EquationOrder-Tuple{AbsSimpleNumField}","page":"Orders","title":"EquationOrder","text":"EquationOrder(K::number_field) -> NumFieldOrder\nequation_order(K::number_field) -> NumFieldOrder\n\nReturns the equation order of the number field K.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/orders/orders/#MaximalOrder-Tuple{AbsSimpleNumField}","page":"Orders","title":"MaximalOrder","text":"MaximalOrder(K::NumField{QQFieldElem}; discriminant::ZZRingElem, ramified_primes::Vector{ZZRingElem}) -> AbsNumFieldOrder\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/manual/orders/orders/#MaximalOrder-Tuple{AbsSimpleNumFieldOrder}","page":"Orders","title":"MaximalOrder","text":"MaximalOrder(O::AbsNumFieldOrder; index_divisors::Vector{ZZRingElem}, discriminant::ZZRingElem, ramified_primes::Vector{ZZRingElem}) -> AbsNumFieldOrder\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::AbstractAssociativeAlgebra{QQFieldElem}) -> AlgAssAbsOrd\n\nReturns a maximal order of A.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/orders/orders/#lll-Tuple{AbsSimpleNumFieldOrder}","page":"Orders","title":"lll","text":"lll(M::AbsNumFieldOrder) -> AbsNumFieldOrder\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/manual/orders/orders/#any_order-Tuple{AbsSimpleNumField}","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/manual/orders/orders/#Example","page":"Orders","title":"Example","text":"","category":"section"},{"location":"Hecke/manual/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/manual/orders/orders/","page":"Orders","title":"Orders","text":"parent(::AbsSimpleNumFieldOrder)\nsignature(::AbsSimpleNumFieldOrder)\nnf(::AbsSimpleNumFieldOrder)\nbasis(::AbsSimpleNumFieldOrder)\nlll_basis(::AbsSimpleNumFieldOrder)\nbasis(::AbsSimpleNumFieldOrder, ::AbsSimpleNumField)\npseudo_basis(::RelNumFieldOrder)\nbasis_pmatrix(::RelNumFieldOrder)\nbasis_nf(::RelNumFieldOrder)\ninv_coeff_ideals(::RelNumFieldOrder)\nbasis_matrix(::AbsNumFieldOrder)\nbasis_mat_inv(::AbsSimpleNumFieldOrder)\ngen_index(::AbsSimpleNumFieldOrder)\nis_index_divisor(::AbsSimpleNumFieldOrder, ::ZZRingElem)\nminkowski_matrix(::AbsSimpleNumFieldOrder, ::Int)\nin(::AbsSimpleNumFieldElem, ::AbsSimpleNumFieldOrder)\nnorm_change_const(::AbsSimpleNumFieldOrder)\ntrace_matrix(::AbsSimpleNumFieldOrder)\n+(::AbsNumFieldOrder, ::AbsNumFieldOrder)\npoverorder(::AbsSimpleNumFieldOrder, ::ZZRingElem)\npoverorders(::AbsSimpleNumFieldOrder, ::ZZRingElem)\npmaximal_overorder(::AbsSimpleNumFieldOrder, ::ZZRingElem)\npradical(::AbsNumFieldOrder, ::Union{Integer, ZZRingElem})\npradical(::RelNumFieldOrder, ::Union{Hecke.RelNumFieldOrderIdeal, AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}})\nring_of_multipliers(::AbsNumFieldOrderIdeal)\n","category":"page"},{"location":"Hecke/manual/orders/orders/#parent-Tuple{AbsSimpleNumFieldOrder}","page":"Orders","title":"parent","text":"parent(O::AbsNumFieldOrder) -> AbsNumFieldOrderSet\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/manual/orders/orders/#signature-Tuple{AbsSimpleNumFieldOrder}","page":"Orders","title":"signature","text":"signature(O::NumFieldOrder) -> 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/manual/orders/orders/#nf-Tuple{AbsSimpleNumFieldOrder}","page":"Orders","title":"nf","text":"nf(O::NumFieldOrder) -> NumField\n\nReturns the ambient number field of mathcal O.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/orders/orders/#basis-Tuple{AbsSimpleNumFieldOrder}","page":"Orders","title":"basis","text":"basis(O::AbsNumFieldOrder) -> Vector{AbsNumFieldOrderElem}\n\nReturns the mathbf Z-basis of mathcal O.\n\n\n\n\n\nbasis(I::AbsNumFieldOrderFractionalIdeal) -> Vector{AbsSimpleNumFieldElem}\n\nReturns the mathbf Z-basis of I.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/orders/orders/#lll_basis-Tuple{AbsSimpleNumFieldOrder}","page":"Orders","title":"lll_basis","text":"lll_basis(M::NumFieldOrder) -> 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/manual/orders/orders/#basis-Tuple{AbsSimpleNumFieldOrder, AbsSimpleNumField}","page":"Orders","title":"basis","text":"basis(O::AbsSimpleNumFieldOrder, K::AbsSimpleNumField) -> Vector{AbsSimpleNumFieldElem}\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/manual/orders/orders/#pseudo_basis-Tuple{Hecke.RelNumFieldOrder}","page":"Orders","title":"pseudo_basis","text":" pseudo_basis(O::RelNumFieldOrder{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/manual/orders/orders/#basis_pmatrix-Tuple{Hecke.RelNumFieldOrder}","page":"Orders","title":"basis_pmatrix","text":" basis_pmatrix(O::RelNumFieldOrder) -> 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/manual/orders/orders/#basis_nf-Tuple{Hecke.RelNumFieldOrder}","page":"Orders","title":"basis_nf","text":" basis_nf(O::RelNumFieldOrder) -> 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/manual/orders/orders/#inv_coeff_ideals-Tuple{Hecke.RelNumFieldOrder}","page":"Orders","title":"inv_coeff_ideals","text":" inv_coeff_ideals(O::RelNumFieldOrder{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/manual/orders/orders/#basis_matrix-Tuple{AbsNumFieldOrder}","page":"Orders","title":"basis_matrix","text":"basis_matrix(O::AbsNumFieldOrder) -> QQMatrix\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/manual/orders/orders/#basis_mat_inv-Tuple{AbsSimpleNumFieldOrder}","page":"Orders","title":"basis_mat_inv","text":"basis_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/manual/orders/orders/#gen_index-Tuple{AbsSimpleNumFieldOrder}","page":"Orders","title":"gen_index","text":"gen_index(O::AbsSimpleNumFieldOrder) -> 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/manual/orders/orders/#is_index_divisor-Tuple{AbsSimpleNumFieldOrder, ZZRingElem}","page":"Orders","title":"is_index_divisor","text":"is_index_divisor(O::AbsSimpleNumFieldOrder, d::ZZRingElem) -> Bool\nis_index_divisor(O::AbsSimpleNumFieldOrder, 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/manual/orders/orders/#minkowski_matrix-Tuple{AbsSimpleNumFieldOrder, Int64}","page":"Orders","title":"minkowski_matrix","text":"minkowski_matrix(O::AbsNumFieldOrder, abs_tol::Int = 64) -> ArbMatrix\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 ArbFieldElem with radius less then 2^-abs_tol.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/orders/orders/#in-Tuple{AbsSimpleNumFieldElem, AbsSimpleNumFieldOrder}","page":"Orders","title":"in","text":"in(a::NumFieldElem, O::NumFieldOrder) -> Bool\n\nChecks whether a lies in mathcal O.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/orders/orders/#norm_change_const-Tuple{AbsSimpleNumFieldOrder}","page":"Orders","title":"norm_change_const","text":"norm_change_const(O::AbsSimpleNumFieldOrder) -> (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/manual/orders/orders/#trace_matrix-Tuple{AbsSimpleNumFieldOrder}","page":"Orders","title":"trace_matrix","text":"trace_matrix(O::AbsNumFieldOrder) -> 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/manual/orders/orders/#+-Tuple{AbsNumFieldOrder, AbsNumFieldOrder}","page":"Orders","title":"+","text":"+(R::AbsSimpleNumFieldOrder, S::AbsSimpleNumFieldOrder) -> AbsSimpleNumFieldOrder\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/manual/orders/orders/#poverorder-Tuple{AbsSimpleNumFieldOrder, ZZRingElem}","page":"Orders","title":"poverorder","text":"poverorder(O::AbsSimpleNumFieldOrder, p::ZZRingElem) -> AbsSimpleNumFieldOrder\npoverorder(O::AbsSimpleNumFieldOrder, p::Integer) -> AbsSimpleNumFieldOrder\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/manual/orders/orders/#poverorders-Tuple{AbsSimpleNumFieldOrder, 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/manual/orders/orders/#pmaximal_overorder-Tuple{AbsSimpleNumFieldOrder, ZZRingElem}","page":"Orders","title":"pmaximal_overorder","text":"pmaximal_overorder(O::AbsSimpleNumFieldOrder, p::ZZRingElem) -> AbsSimpleNumFieldOrder\npmaximal_overorder(O::AbsSimpleNumFieldOrder, p::Integer) -> AbsSimpleNumFieldOrder\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/manual/orders/orders/#pradical-Tuple{AbsNumFieldOrder, Union{Integer, ZZRingElem}}","page":"Orders","title":"pradical","text":"pradical(O::AbsSimpleNumFieldOrder, p::{ZZRingElem|Integer}) -> AbsNumFieldOrderIdeal\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/manual/orders/orders/#pradical-Tuple{Hecke.RelNumFieldOrder, Union{Hecke.RelNumFieldOrderIdeal, AbsSimpleNumFieldOrderIdeal}}","page":"Orders","title":"pradical","text":" pradical(O::RelNumFieldOrder, P::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}) -> RelNumFieldOrderIdeal\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/manual/orders/orders/#ring_of_multipliers-Tuple{AbsNumFieldOrderIdeal}","page":"Orders","title":"ring_of_multipliers","text":"ring_of_multipliers(I::AbsNumFieldOrderIdeal) -> AbsNumFieldOrder\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/manual/orders/orders/#Invariants","page":"Orders","title":"Invariants","text":"","category":"section"},{"location":"Hecke/manual/orders/orders/","page":"Orders","title":"Orders","text":"discriminant(::AbsNumFieldOrder)\nreduced_discriminant(::AbsSimpleNumFieldOrder)\ndegree(::AbsSimpleNumFieldOrder)\nindex(::AbsSimpleNumFieldOrder)\ndifferent(::AbsSimpleNumFieldOrder)\ncodifferent(::AbsSimpleNumFieldOrder)\nis_gorenstein(::AbsSimpleNumFieldOrder)\nis_bass(::AbsSimpleNumFieldOrder)\nis_equation_order(::AbsSimpleNumFieldOrder)\nzeta_log_residue(::AbsSimpleNumFieldOrder, ::Float64)\nramified_primes(::AbsSimpleNumFieldOrder)","category":"page"},{"location":"Hecke/manual/orders/orders/#discriminant-Tuple{AbsNumFieldOrder}","page":"Orders","title":"discriminant","text":"discriminant(O::AbsSimpleNumFieldOrder) -> ZZRingElem\n\nReturns the discriminant of mathcal O.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/orders/orders/#reduced_discriminant-Tuple{AbsSimpleNumFieldOrder}","page":"Orders","title":"reduced_discriminant","text":"reduced_discriminant(O::AbsSimpleNumFieldOrder) -> 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/manual/orders/orders/#degree-Tuple{AbsSimpleNumFieldOrder}","page":"Orders","title":"degree","text":"degree(O::NumFieldOrder) -> Int\n\nReturns the degree of mathcal O.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/orders/orders/#index-Tuple{AbsSimpleNumFieldOrder}","page":"Orders","title":"index","text":"index(O::AbsSimpleNumFieldOrder) -> 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/manual/orders/orders/#different-Tuple{AbsSimpleNumFieldOrder}","page":"Orders","title":"different","text":"different(R::AbsNumFieldOrder) -> AbsNumFieldOrderIdeal\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/manual/orders/orders/#codifferent-Tuple{AbsSimpleNumFieldOrder}","page":"Orders","title":"codifferent","text":"codifferent(R::AbsNumFieldOrder) -> AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}\n\nThe codifferent ideal of R, i.e. the trace-dual of R.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/orders/orders/#is_gorenstein-Tuple{AbsSimpleNumFieldOrder}","page":"Orders","title":"is_gorenstein","text":"is_gorenstein(O::AbsSimpleNumFieldOrder) -> Bool\n\nReturn whether the order \\mathcal{O} is Gorenstein.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/orders/orders/#is_bass-Tuple{AbsSimpleNumFieldOrder}","page":"Orders","title":"is_bass","text":"is_bass(O::AbsSimpleNumFieldOrder) -> Bool\n\nReturn whether the order \\mathcal{O} is Bass.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/orders/orders/#is_equation_order-Tuple{AbsSimpleNumFieldOrder}","page":"Orders","title":"is_equation_order","text":"is_equation_order(O::NumFieldOrder) -> 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/manual/orders/orders/#zeta_log_residue-Tuple{AbsSimpleNumFieldOrder, Float64}","page":"Orders","title":"zeta_log_residue","text":"zeta_log_residue(O::AbsSimpleNumFieldOrder, error::Float64) -> ArbFieldElem\n\nComputes the residue of the zeta function of mathcal O at 1. The output will be an element of type ArbFieldElem with radius less then error.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/orders/orders/#ramified_primes-Tuple{AbsSimpleNumFieldOrder}","page":"Orders","title":"ramified_primes","text":"ramified_primes(O::AbsNumFieldOrder) -> Vector{ZZRingElem}\n\nReturns the list of prime numbers that divide operatornamedisc(mathcal O).\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/orders/orders/#Arithmetic","page":"Orders","title":"Arithmetic","text":"","category":"section"},{"location":"Hecke/manual/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/manual/orders/orders/","page":"Orders","title":"Orders","text":"ClassGroup\nUnitGroup","category":"page"},{"location":"Hecke/manual/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 groups, see here, for ideals, here.","category":"page"},{"location":"Hecke/manual/orders/orders/","page":"Orders","title":"Orders","text":"torsion_unit_group(::AbsSimpleNumFieldOrder)\nunit_group(::AbsSimpleNumFieldOrder)\nunit_group_fac_elem(::AbsSimpleNumFieldOrder)\nsunit_group(::Vector{AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}})\nsunit_group_fac_elem(::Vector{AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}})\nsunit_mod_units_group_fac_elem(::Vector{AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}})\nclass_group(::AbsSimpleNumFieldOrder)\npicard_group(::AbsSimpleNumFieldOrder)\nnarrow_class_group(::AbsSimpleNumFieldOrder)","category":"page"},{"location":"Hecke/manual/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/manual/orders/orders/","page":"Orders","title":"Orders","text":"is_independent","category":"page"},{"location":"Hecke/manual/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/manual/orders/orders/#Predicates","page":"Orders","title":"Predicates","text":"","category":"section"},{"location":"Hecke/manual/orders/orders/","page":"Orders","title":"Orders","text":"Hecke.is_contained(::AbsNumFieldOrder, ::AbsNumFieldOrder)\nis_maximal(::AbsNumFieldOrder)","category":"page"},{"location":"Hecke/manual/orders/orders/#is_contained-Tuple{AbsNumFieldOrder, AbsNumFieldOrder}","page":"Orders","title":"is_contained","text":"is_contained(R::AbsNumFieldOrder, S::AbsNumFieldOrder) -> Bool\n\nChecks if R is contained in S.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/orders/orders/#is_maximal-Tuple{AbsNumFieldOrder}","page":"Orders","title":"is_maximal","text":"is_maximal(R::AbsNumFieldOrder) -> 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":"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) ArbFieldElem 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":"julia> RR = ArbField(64)\nReal Field with 64 bits of precision and error bounds\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/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(::ArbFieldElem, ::ArbFieldElem)","category":"page"},{"location":"Nemo/arb/#ball-Tuple{ArbFieldElem, ArbFieldElem}","page":"Fixed precision real balls","title":"ball","text":"ball(x::ArbFieldElem, y::ArbFieldElem)\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":"julia> RR = ArbField(64)\nReal Field with 64 bits of precision and error bounds\n\njulia> c = ball(RR(3), RR(\"0.0001\"))\n[3.000 +/- 1.01e-4]","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":"julia> RR = ArbField(64)\nReal Field with 64 bits of precision and error bounds\n\njulia> convert(Float64, RR(1//3))\n0.3333333333333333","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(::ArbFieldElem)","category":"page"},{"location":"Nemo/arb/#is_nonzero-Tuple{ArbFieldElem}","page":"Fixed precision real balls","title":"is_nonzero","text":"is_nonzero(x::ArbFieldElem)\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(::ArbFieldElem)","category":"page"},{"location":"Nemo/arb/#isfinite-Tuple{ArbFieldElem}","page":"Fixed precision real balls","title":"isfinite","text":"isfinite(x::ArbFieldElem)\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(::ArbFieldElem)","category":"page"},{"location":"Nemo/arb/#is_exact-Tuple{ArbFieldElem}","page":"Fixed precision real balls","title":"is_exact","text":"is_exact(x::ArbFieldElem)\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(::ArbFieldElem)","category":"page"},{"location":"Nemo/arb/#isinteger-Tuple{ArbFieldElem}","page":"Fixed precision real balls","title":"isinteger","text":"isinteger(x::ArbFieldElem)\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(::ArbFieldElem)","category":"page"},{"location":"Nemo/arb/#is_positive-Tuple{ArbFieldElem}","page":"Fixed precision real balls","title":"is_positive","text":"is_positive(x::ArbFieldElem)\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(::ArbFieldElem)","category":"page"},{"location":"Nemo/arb/#is_nonnegative-Tuple{ArbFieldElem}","page":"Fixed precision real balls","title":"is_nonnegative","text":"is_nonnegative(x::ArbFieldElem)\n\nReturn true if x is certainly non-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_negative(::ArbFieldElem)","category":"page"},{"location":"Nemo/arb/#is_negative-Tuple{ArbFieldElem}","page":"Fixed precision real balls","title":"is_negative","text":"is_negative(x::ArbFieldElem)\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(::ArbFieldElem)","category":"page"},{"location":"Nemo/arb/#is_nonpositive-Tuple{ArbFieldElem}","page":"Fixed precision real balls","title":"is_nonpositive","text":"is_nonpositive(x::ArbFieldElem)\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(::ArbFieldElem)","category":"page"},{"location":"Nemo/arb/#midpoint-Tuple{ArbFieldElem}","page":"Fixed precision real balls","title":"midpoint","text":"midpoint(x::ArbFieldElem)\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(::ArbFieldElem)","category":"page"},{"location":"Nemo/arb/#radius-Tuple{ArbFieldElem}","page":"Fixed precision real balls","title":"radius","text":"radius(x::ArbFieldElem)\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(::ArbFieldElem)","category":"page"},{"location":"Nemo/arb/#accuracy_bits-Tuple{ArbFieldElem}","page":"Fixed precision real balls","title":"accuracy_bits","text":"accuracy_bits(x::ArbFieldElem)\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":"julia> RR = ArbField(64)\nReal Field with 64 bits of precision and error bounds\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/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":"julia> RR = ArbField(64)\nReal Field with 64 bits of precision and error bounds\n\njulia> a = RR(1)\n1.0000000000000000000\n\njulia> b = RR(2)\n2.0000000000000000000\n\njulia> c = RR(12)\n12.000000000000000000\n\njulia> x = ball(a, b)\n[+/- 3.01]\n\njulia> y = ball(c, b)\n[1e+1 +/- 4.01]\n\njulia> mid = midpoint(x)\n1.0000000000000000000\n\njulia> rad = radius(x)\n[2.0000000037252902985 +/- 3.81e-20]\n\njulia> print(x, \"\\n\", y, \"\\n\", mid, \"\\n\", rad)\n[+/- 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(::ArbFieldElem, ::ArbFieldElem)","category":"page"},{"location":"Nemo/arb/#overlaps-Tuple{ArbFieldElem, ArbFieldElem}","page":"Fixed precision real balls","title":"overlaps","text":"overlaps(x::ArbFieldElem, y::ArbFieldElem)\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(::ArbFieldElem, ::ArbFieldElem)","category":"page"},{"location":"Nemo/arb/#contains-Tuple{ArbFieldElem, ArbFieldElem}","page":"Fixed precision real balls","title":"contains","text":"contains(x::ArbFieldElem, y::ArbFieldElem)\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(::ArbFieldElem, ::Integer)\ncontains(::ArbFieldElem, ::ZZRingElem)\ncontains(::ArbFieldElem, ::QQFieldElem)\ncontains{T <: Integer}(::ArbFieldElem, ::Rational{T})\ncontains(::ArbFieldElem, ::BigFloat)","category":"page"},{"location":"Nemo/arb/#contains-Tuple{ArbFieldElem, Integer}","page":"Fixed precision real balls","title":"contains","text":"contains(x::ArbFieldElem, 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{ArbFieldElem, ZZRingElem}","page":"Fixed precision real balls","title":"contains","text":"contains(x::ArbFieldElem, 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{ArbFieldElem, QQFieldElem}","page":"Fixed precision real balls","title":"contains","text":"contains(x::ArbFieldElem, 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{ArbFieldElem, Rational{T}}} where T<:Integer","page":"Fixed precision real balls","title":"contains","text":"contains(x::ArbFieldElem, 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{ArbFieldElem, BigFloat}","page":"Fixed precision real balls","title":"contains","text":"contains(x::ArbFieldElem, 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(::ArbFieldElem)","category":"page"},{"location":"Nemo/arb/#contains_zero-Tuple{ArbFieldElem}","page":"Fixed precision real balls","title":"contains_zero","text":"contains_zero(x::ArbFieldElem)\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(::ArbFieldElem)","category":"page"},{"location":"Nemo/arb/#contains_negative-Tuple{ArbFieldElem}","page":"Fixed precision real balls","title":"contains_negative","text":"contains_negative(x::ArbFieldElem)\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(::ArbFieldElem)","category":"page"},{"location":"Nemo/arb/#contains_positive-Tuple{ArbFieldElem}","page":"Fixed precision real balls","title":"contains_positive","text":"contains_positive(x::ArbFieldElem)\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(::ArbFieldElem)","category":"page"},{"location":"Nemo/arb/#contains_nonnegative-Tuple{ArbFieldElem}","page":"Fixed precision real balls","title":"contains_nonnegative","text":"contains_nonnegative(x::ArbFieldElem)\n\nReturns true if the ball x contains any non-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_nonpositive(::ArbFieldElem)","category":"page"},{"location":"Nemo/arb/#contains_nonpositive-Tuple{ArbFieldElem}","page":"Fixed precision real balls","title":"contains_nonpositive","text":"contains_nonpositive(x::ArbFieldElem)\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":"julia> RR = ArbField(64)\nReal Field with 64 bits of precision and error bounds\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/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(::ArbFieldElem, ::ArbFieldElem)","category":"page"},{"location":"Nemo/arb/#isequal-Tuple{ArbFieldElem, ArbFieldElem}","page":"Fixed precision real balls","title":"isequal","text":"isequal(x::ArbFieldElem, y::ArbFieldElem)\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::ArbFieldElem, y::Integer)\n==(x::Integer, y::ArbFieldElem)\n==(x::ArbFieldElem, y::ZZRingElem)\n==(x::ZZRingElem, y::ArbFieldElem)\n==(x::ArbFieldElem, y::Float64)\n==(x::Float64, y::ArbFieldElem)\nisless(x::ArbFieldElem, y::Integer)\nisless(x::Integer, y::ArbFieldElem)\nisless(x::ArbFieldElem, y::ZZRingElem)\nisless(x::ZZRingElem, y::ArbFieldElem)\nisless(x::ArbFieldElem, y::Float64)\nisless(x::Float64, y::ArbFieldElem)\nisless(x::ArbFieldElem, y::BigFloat)\nisless(x::BigFloat, y::ArbFieldElem)\nisless(x::ArbFieldElem, y::QQFieldElem)\nisless(x::QQFieldElem, y::ArbFieldElem)","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":"julia> RR = ArbField(64)\nReal Field with 64 bits of precision and error bounds\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\n\njulia> 3 == y\ntrue","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":"julia> RR = ArbField(64)\nReal Field with 64 bits of precision and error bounds\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/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":"julia> RR = ArbField(64)\nReal Field with 64 bits of precision and error bounds\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/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!(::ArbFieldElem, ::ArbFieldElem)","category":"page"},{"location":"Nemo/arb/#add_error!-Tuple{ArbFieldElem, ArbFieldElem}","page":"Fixed precision real balls","title":"add_error!","text":"add_error!(x::ArbFieldElem, y::ArbFieldElem)\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(::ArbFieldElem)","category":"page"},{"location":"Nemo/arb/#trim-Tuple{ArbFieldElem}","page":"Fixed precision real balls","title":"trim","text":"trim(x::ArbFieldElem)\n\nReturn an ArbFieldElem 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(::ArbFieldElem)","category":"page"},{"location":"Nemo/arb/#unique_integer-Tuple{ArbFieldElem}","page":"Fixed precision real balls","title":"unique_integer","text":"unique_integer(x::ArbFieldElem)\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(::ArbFieldElem, ::ArbFieldElem)","category":"page"},{"location":"Nemo/arb/#setunion-Tuple{ArbFieldElem, ArbFieldElem}","page":"Fixed precision real balls","title":"setunion","text":"setunion(x::ArbFieldElem, y::ArbFieldElem)\n\nReturn an ArbFieldElem 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":"julia> RR = ArbField(64)\nReal Field with 64 bits of precision and error bounds\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/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":"julia> RR = ArbField(200)\nReal Field with 200 bits of precision and error bounds\n\njulia> a = const_pi(RR)\n[3.14159265358979323846264338327950288419716939937510582097494 +/- 5.73e-60]\n\njulia> b = const_e(RR)\n[2.71828182845904523536028747135266249775724709369995957496697 +/- 7.06e-60]\n\njulia> c = const_euler(RR)\n[0.577215664901532860606512090082402431042159335939923598805767 +/- 5.37e-61]\n\njulia> d = const_glaisher(RR)\n[1.28242712910062263687534256886979172776768892732500119206374 +/- 2.18e-60]","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(::ArbFieldElem)","category":"page"},{"location":"Nemo/arb/#rsqrt-Tuple{ArbFieldElem}","page":"Fixed precision real balls","title":"rsqrt","text":"rsqrt(x::ArbFieldElem)\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(::ArbFieldElem)","category":"page"},{"location":"Nemo/arb/#sqrt1pm1-Tuple{ArbFieldElem}","page":"Fixed precision real balls","title":"sqrt1pm1","text":"sqrt1pm1(x::ArbFieldElem)\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(::ArbFieldElem)","category":"page"},{"location":"Nemo/arb/#sqrtpos-Tuple{ArbFieldElem}","page":"Fixed precision real balls","title":"sqrtpos","text":"sqrtpos(x::ArbFieldElem)\n\nReturn the sqrt root of x, assuming that x represents a non-negative 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(::ArbFieldElem)","category":"page"},{"location":"Nemo/arb/#gamma-Tuple{ArbFieldElem}","page":"Fixed precision real balls","title":"gamma","text":"gamma(x::ArbFieldElem)\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(::ArbFieldElem)","category":"page"},{"location":"Nemo/arb/#lgamma-Tuple{ArbFieldElem}","page":"Fixed precision real balls","title":"lgamma","text":"lgamma(x::ArbFieldElem)\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(::ArbFieldElem)","category":"page"},{"location":"Nemo/arb/#rgamma-Tuple{ArbFieldElem}","page":"Fixed precision real balls","title":"rgamma","text":"rgamma(x::ArbFieldElem)\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(::ArbFieldElem)","category":"page"},{"location":"Nemo/arb/#digamma-Tuple{ArbFieldElem}","page":"Fixed precision real balls","title":"digamma","text":"digamma(x::ArbFieldElem)\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(::ArbFieldElem, ::ArbFieldElem)","category":"page"},{"location":"Nemo/arb/#gamma-Tuple{ArbFieldElem, ArbFieldElem}","page":"Fixed precision real balls","title":"gamma","text":"gamma(s::ArbFieldElem, x::ArbFieldElem)\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(::ArbFieldElem, ::ArbFieldElem)","category":"page"},{"location":"Nemo/arb/#gamma_regularized-Tuple{ArbFieldElem, ArbFieldElem}","page":"Fixed precision real balls","title":"gamma_regularized","text":"gamma_regularized(s::ArbFieldElem, x::ArbFieldElem)\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(::ArbFieldElem, ::ArbFieldElem)","category":"page"},{"location":"Nemo/arb/#gamma_lower-Tuple{ArbFieldElem, ArbFieldElem}","page":"Fixed precision real balls","title":"gamma_lower","text":"gamma_lower(s::ArbFieldElem, x::ArbFieldElem)\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(::ArbFieldElem, ::ArbFieldElem)","category":"page"},{"location":"Nemo/arb/#gamma_lower_regularized-Tuple{ArbFieldElem, ArbFieldElem}","page":"Fixed precision real balls","title":"gamma_lower_regularized","text":"gamma_lower_regularized(s::ArbFieldElem, x::ArbFieldElem)\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(::ArbFieldElem)","category":"page"},{"location":"Nemo/arb/#zeta-Tuple{ArbFieldElem}","page":"Fixed precision real balls","title":"zeta","text":"zeta(x::ArbFieldElem)\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(::ArbFieldElem, ::ArbFieldElem)","category":"page"},{"location":"Nemo/arb/#atan2-Tuple{ArbFieldElem, ArbFieldElem}","page":"Fixed precision real balls","title":"atan2","text":"atan2(y::ArbFieldElem, x::ArbFieldElem)\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(::ArbFieldElem, ::ArbFieldElem)","category":"page"},{"location":"Nemo/arb/#agm-Tuple{ArbFieldElem, ArbFieldElem}","page":"Fixed precision real balls","title":"agm","text":"agm(x::ArbFieldElem, y::ArbFieldElem)\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(::ArbFieldElem, ::ArbFieldElem)","category":"page"},{"location":"Nemo/arb/#zeta-Tuple{ArbFieldElem, ArbFieldElem}","page":"Fixed precision real balls","title":"zeta","text":"zeta(s::ArbFieldElem, a::ArbFieldElem)\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(::ArbFieldElem, ::Int)","category":"page"},{"location":"Nemo/arb/#root-Tuple{ArbFieldElem, Int64}","page":"Fixed precision real balls","title":"root","text":"root(x::ArbFieldElem, 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(::ArbFieldElem)","category":"page"},{"location":"Nemo/arb/#factorial-Tuple{ArbFieldElem}","page":"Fixed precision real balls","title":"factorial","text":"factorial(x::ArbFieldElem)\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(::ArbFieldElem, ::UInt)","category":"page"},{"location":"Nemo/arb/#binomial-Tuple{ArbFieldElem, UInt64}","page":"Fixed precision real balls","title":"binomial","text":"binomial(x::ArbFieldElem, 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(::ArbFieldElem, ::Int)","category":"page"},{"location":"Nemo/arb/#rising_factorial-Tuple{ArbFieldElem, Int64}","page":"Fixed precision real balls","title":"rising_factorial","text":"rising_factorial(x::ArbFieldElem, 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(::ArbFieldElem, ::Int)","category":"page"},{"location":"Nemo/arb/#rising_factorial2-Tuple{ArbFieldElem, Int64}","page":"Fixed precision real balls","title":"rising_factorial2","text":"rising_factorial2(x::ArbFieldElem, 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{ArbFieldElem,Int}, ::ArbFieldElem)","category":"page"},{"location":"Nemo/arb/#polylog-Tuple{Union{Int64, ArbFieldElem}, ArbFieldElem}","page":"Fixed precision real balls","title":"polylog","text":"polylog(s::Union{ArbFieldElem,Int}, a::ArbFieldElem)\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, ::ArbFieldElem)","category":"page"},{"location":"Nemo/arb/#chebyshev_t-Tuple{Int64, ArbFieldElem}","page":"Fixed precision real balls","title":"chebyshev_t","text":"chebyshev_t(n::Int, x::ArbFieldElem)\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, ::ArbFieldElem)","category":"page"},{"location":"Nemo/arb/#chebyshev_u-Tuple{Int64, ArbFieldElem}","page":"Fixed precision real balls","title":"chebyshev_u","text":"chebyshev_u(n::Int, x::ArbFieldElem)\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, ::ArbFieldElem)","category":"page"},{"location":"Nemo/arb/#chebyshev_t2-Tuple{Int64, ArbFieldElem}","page":"Fixed precision real balls","title":"chebyshev_t2","text":"chebyshev_t2(n::Int, x::ArbFieldElem)\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, ::ArbFieldElem)","category":"page"},{"location":"Nemo/arb/#chebyshev_u2-Tuple{Int64, ArbFieldElem}","page":"Fixed precision real balls","title":"chebyshev_u2","text":"chebyshev_u2(n::Int, x::ArbFieldElem)\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(::ArbFieldElem)","category":"page"},{"location":"Nemo/arb/#airy_ai-Tuple{ArbFieldElem}","page":"Fixed precision real balls","title":"airy_ai","text":"airy_ai(x::ArbFieldElem)\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(::ArbFieldElem)","category":"page"},{"location":"Nemo/arb/#airy_ai_prime-Tuple{ArbFieldElem}","page":"Fixed precision real balls","title":"airy_ai_prime","text":"airy_ai_prime(x::ArbFieldElem)\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(::ArbFieldElem)","category":"page"},{"location":"Nemo/arb/#airy_bi-Tuple{ArbFieldElem}","page":"Fixed precision real balls","title":"airy_bi","text":"airy_bi(x::ArbFieldElem)\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(::ArbFieldElem)","category":"page"},{"location":"Nemo/arb/#airy_bi_prime-Tuple{ArbFieldElem}","page":"Fixed precision real balls","title":"airy_bi_prime","text":"airy_bi_prime(x::ArbFieldElem)\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":"julia> RR = ArbField(64)\nReal Field with 64 bits of precision and error bounds\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), ArbField(256))\n[2.6789385347077476336556929409746776441286893779573011009504283275904176101677 +/- 6.71e-77]\n\njulia> d = bernoulli(1000, ArbField(53))\n[-5.318704469415522e+1769 +/- 8.20e+1753]\n\njulia> f = polylog(3, RR(-10))\n[-5.92106480375697 +/- 6.68e-15]","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{ArbFieldElem}, n::Int)","category":"page"},{"location":"Nemo/arb/#lindep-Tuple{Vector{ArbFieldElem}, Int64}","page":"Fixed precision real balls","title":"lindep","text":"lindep(A::Vector{ArbFieldElem}, 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{ArbFieldElem}:\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":"julia> RR = ArbField(128)\nReal Field with 128 bits of precision and error bounds\n\njulia> a = RR(-0.33198902958450931620250069492231652319) # real root of x^5 + 3x + 1\n[-0.331989029584509320880414406929048709571 +/- 3.62e-40]\n\njulia> V = [RR(1), a, a^2, a^3, a^4, a^5]\n6-element Vector{ArbFieldElem}:\n 1.00000000000000000000000000000000000000\n [-0.331989029584509320880414406929048709571 +/- 3.62e-40]\n [0.110216715764464205102727554344054759368 +/- 3.32e-40]\n [-0.0365907405106361618384680031506015710184 +/- 8.30e-41]\n [0.0121477244339046924274232580429164920524 +/- 2.83e-41]\n [-0.00403291124647205167662794872826031818905 +/- 7.87e-42]\n\njulia> W = lindep(V, 20)\n6-element Vector{ZZRingElem}:\n 1\n 3\n 0\n 0\n 0\n 1","category":"page"},{"location":"Nemo/arb/","page":"Fixed precision real balls","title":"Fixed precision real balls","text":"simplest_rational_inside(::ArbFieldElem)","category":"page"},{"location":"Nemo/arb/#simplest_rational_inside-Tuple{ArbFieldElem}","page":"Fixed precision real balls","title":"simplest_rational_inside","text":" simplest_rational_inside(x::ArbFieldElem)\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/#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 ArbFieldElem 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 ArbFieldElem 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":"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 PadicFieldElem 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, AbsSimpleNumFieldElem 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 ArbFieldElem directory the ArbFieldElem prefix is for arbitrary precision ball arithmetic over the reals. The AcbFieldElem 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 CalciumFieldElem prefix is for Calcium's type. There is also a QQBarFieldElem 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":"Combinatorics/EnumerativeCombinatorics/compositions/#Compositions","page":"Compositions","title":"Compositions","text":"","category":"section"},{"location":"Combinatorics/EnumerativeCombinatorics/compositions/","page":"Compositions","title":"Compositions","text":"A weak composition of a non-negative integer n is a sequence lambda_1dotslambda_k of non-negative integers lambda_i such that n = lambda_1 + dots + lambda_k. A composition of n is a weak composition consisting of positive integers. The lambda_i are called the parts of the (weak) composition.","category":"page"},{"location":"Combinatorics/EnumerativeCombinatorics/compositions/","page":"Compositions","title":"Compositions","text":"weak_composition\ncomposition","category":"page"},{"location":"Combinatorics/EnumerativeCombinatorics/compositions/#weak_composition","page":"Compositions","title":"weak_composition","text":"weak_composition(parts::Vector{T}; check::Bool = true) where T <: IntegerUnion\n\nReturn the weak composition given by the integer sequence parts as an object of type WeakComposition{T}.\n\nIf check is true (default), it is checked whether the given sequence defines a weak composition, that is, whether all elements of parts are non-negative.\n\nExamples\n\njulia> W = weak_composition([6, 0, 2, 3]) # the weak composition 6, 0, 2, 3 of 11\n[6, 0, 2, 3]\n\njulia> W = weak_composition(Int8[6, 0, 2, 3]) # save the elements in 8-bit integers\nInt8[6, 0, 2, 3]\n\n\n\n\n\n","category":"function"},{"location":"Combinatorics/EnumerativeCombinatorics/compositions/#composition","page":"Compositions","title":"composition","text":"composition(parts::Vector{T}; check::Bool = true) where T <: IntegerUnion\n\nReturn the composition given by the integer sequence parts as an object of type Composition{T}.\n\nIf check is true (default), it is checked whether the given sequence defines a composition, that is, whether all elements of parts are positive.\n\nExamples\n\njulia> C = composition([6, 1, 2, 3]) # the composition 6, 1, 2, 3 of 12\n[6, 1, 2, 3]\n\njulia> C = composition(Int8[6, 1, 2, 3]) # save the elements in 8-bit integers\nInt8[6, 1, 2, 3]\n\n\n\n\n\n","category":"function"},{"location":"Combinatorics/EnumerativeCombinatorics/compositions/#Generating-and-counting","page":"Compositions","title":"Generating and counting","text":"","category":"section"},{"location":"Combinatorics/EnumerativeCombinatorics/compositions/#Unrestricted-compositions","page":"Compositions","title":"Unrestricted compositions","text":"","category":"section"},{"location":"Combinatorics/EnumerativeCombinatorics/compositions/","page":"Compositions","title":"Compositions","text":"compositions(::Oscar.IntegerUnion)\nnumber_of_compositions(::Oscar.IntegerUnion)","category":"page"},{"location":"Combinatorics/EnumerativeCombinatorics/compositions/#compositions-Tuple{Union{Integer, ZZRingElem}}","page":"Compositions","title":"compositions","text":"compositions(n::IntegerUnion)\n\nReturn an iterator over all compositions of a non-negative integer n.\n\nBy a composition of n we mean a sequence of positive integers whose sum is n.\n\nExamples\n\njulia> C = compositions(4)\nIterator over the compositions of 4\n\njulia> collect(C)\n8-element Vector{Composition{Int64}}:\n [4]\n [3, 1]\n [2, 2]\n [1, 3]\n [2, 1, 1]\n [1, 2, 1]\n [1, 1, 2]\n [1, 1, 1, 1]\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/EnumerativeCombinatorics/compositions/#number_of_compositions-Tuple{Union{Integer, ZZRingElem}}","page":"Compositions","title":"number_of_compositions","text":"number_of_compositions(n::IntegerUnion)\n\nReturn the number of compositions of the non-negative integer n. For n < 0, return 0.\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/EnumerativeCombinatorics/compositions/","page":"Compositions","title":"Compositions","text":"Note that an integer n has infinitely many weak compositions as one may always append zeros to the end of a given weak composition. Without restrictions on the number of parts, we can hence only generate compositions, but not weak compositions.","category":"page"},{"location":"Combinatorics/EnumerativeCombinatorics/compositions/#Restricted-compositions","page":"Compositions","title":"Restricted compositions","text":"","category":"section"},{"location":"Combinatorics/EnumerativeCombinatorics/compositions/","page":"Compositions","title":"Compositions","text":"compositions(::Oscar.IntegerUnion, ::Oscar.IntegerUnion)\nnumber_of_compositions(::Oscar.IntegerUnion, ::Oscar.IntegerUnion)","category":"page"},{"location":"Combinatorics/EnumerativeCombinatorics/compositions/#compositions-Tuple{Union{Integer, ZZRingElem}, Union{Integer, ZZRingElem}}","page":"Compositions","title":"compositions","text":"compositions(n::IntegerUnion, k::IntegerUnion)\n\nReturn an iterator over all compositions of a non-negative integer n into k parts, produced in lexicographically descending order.\n\nBy a composition of n into k parts we mean a sequence of k positive integers whose sum is n.\n\nExamples\n\njulia> C = compositions(4, 2)\nIterator over the compositions of 4 into 2 parts\n\njulia> collect(C)\n3-element Vector{Composition{Int64}}:\n [3, 1]\n [2, 2]\n [1, 3]\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/EnumerativeCombinatorics/compositions/#number_of_compositions-Tuple{Union{Integer, ZZRingElem}, Union{Integer, ZZRingElem}}","page":"Compositions","title":"number_of_compositions","text":"number_of_compositions(n::IntegerUnion, k::IntegerUnion)\n\nReturn the number of compositions of the non-negative integer n into k >= 0 parts. If n < 0 or k < 0, return 0.\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/EnumerativeCombinatorics/compositions/#Restricted-weak-compositions","page":"Compositions","title":"Restricted weak compositions","text":"","category":"section"},{"location":"Combinatorics/EnumerativeCombinatorics/compositions/","page":"Compositions","title":"Compositions","text":"weak_compositions\nnumber_of_weak_compositions(::Oscar.IntegerUnion, ::Oscar.IntegerUnion)","category":"page"},{"location":"Combinatorics/EnumerativeCombinatorics/compositions/#weak_compositions","page":"Compositions","title":"weak_compositions","text":"weak_compositions(n::IntegerUnion, k::IntegerUnion)\n\nReturn an iterator over all weak compositions of a non-negative integer n into k parts, produced in lexicographically descending order. Using a smaller integer type for n (e.g. Int8) may increase performance.\n\nBy a weak composition of n into k parts we mean a sequence of k non-negative integers whose sum is n.\n\nExamples\n\njulia> W = weak_compositions(3, 2)\nIterator over the weak compositions of 3 into 2 parts\n\njulia> length(W)\n4\n\njulia> collect(W)\n4-element Vector{WeakComposition{Int64}}:\n [3, 0]\n [2, 1]\n [1, 2]\n [0, 3]\n\n\n\n\n\n","category":"function"},{"location":"Combinatorics/EnumerativeCombinatorics/compositions/#number_of_weak_compositions-Tuple{Union{Integer, ZZRingElem}, Union{Integer, ZZRingElem}}","page":"Compositions","title":"number_of_weak_compositions","text":"number_of_weak_compositions(n::IntegerUnion, k::IntegerUnion)\n\nReturn the number of weak compositions of the non-negative integer n into k >= 0 parts. If n < 0 or k < 0, return 0.\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/EnumerativeCombinatorics/compositions/#Ascending-compositions","page":"Compositions","title":"Ascending compositions","text":"","category":"section"},{"location":"Combinatorics/EnumerativeCombinatorics/compositions/","page":"Compositions","title":"Compositions","text":"ascending_compositions","category":"page"},{"location":"Combinatorics/EnumerativeCombinatorics/compositions/#ascending_compositions","page":"Compositions","title":"ascending_compositions","text":"ascending_compositions(n::IntegerUnion)\n\nReturn an iterator over all ascending compositions of a non-negative integer n.\n\nBy a ascending composition of n we mean a non-decreasing sequence of positive integers whose sum is n.\n\nThe implemented algorithm is \"AccelAsc\" (Algorithm 4.1) in [KO14].\n\nExamples\n\njulia> C = ascending_compositions(4)\nIterator over the ascending compositions of 4\n\njulia> collect(C)\n5-element Vector{Composition{Int64}}:\n [1, 1, 1, 1]\n [1, 1, 2]\n [1, 3]\n [2, 2]\n [4]\n\n\n\n\n\n","category":"function"},{"location":"Combinatorics/EnumerativeCombinatorics/compositions/","page":"Compositions","title":"Compositions","text":"The number of ascending compositions of n coincides with the number of partitions of n.","category":"page"},{"location":"Experimental/IntersectionTheory/examples/","page":"Illustrating Examples From Enumerative Geometry","title":"Illustrating Examples From Enumerative Geometry","text":"CurrentModule = Oscar\nDocTestSetup = Oscar.doctestsetup()","category":"page"},{"location":"Experimental/IntersectionTheory/examples/#Illustrating-Examples-From-Enumerative-Geometry","page":"Illustrating Examples From Enumerative Geometry","title":"Illustrating Examples From Enumerative Geometry","text":"","category":"section"},{"location":"Experimental/IntersectionTheory/examples/#How-Many-Lines-in-\\mathbb-P3-Meet-Four-General-Lines-in-\\mathbb-P3?","page":"Illustrating Examples From Enumerative Geometry","title":"How Many Lines in mathbb P^3 Meet Four General Lines in mathbb P^3?","text":"","category":"section"},{"location":"Experimental/IntersectionTheory/examples/","page":"Illustrating Examples From Enumerative Geometry","title":"Illustrating Examples From Enumerative Geometry","text":"julia> G = abstract_grassmannian(2,4)\nAbstractVariety of dim 4\n\njulia> s1 = schubert_class(G, 1)\n-c[1]\n\njulia> integral(s1^4)\n2\n","category":"page"},{"location":"Experimental/IntersectionTheory/examples/#How-Many-Conics-in-\\mathbb-P3-Meet-Eight-General-Lines-in-\\mathbb-P3?","page":"Illustrating Examples From Enumerative Geometry","title":"How Many Conics in mathbb P^3 Meet Eight General Lines in mathbb P^3?","text":"","category":"section"},{"location":"Experimental/IntersectionTheory/examples/","page":"Illustrating Examples From Enumerative Geometry","title":"Illustrating Examples From Enumerative Geometry","text":"julia> G = abstract_grassmannian(3, 4)\nAbstractVariety of dim 3\n\njulia> USBd = dual(tautological_bundles(G)[1])\nAbstractBundle of rank 3 on AbstractVariety of dim 3\n\njulia> F = symmetric_power(USBd, 2)\nAbstractBundle of rank 6 on AbstractVariety of dim 3\n\njulia> PF = abstract_projective_bundle(F) # the parameter space of conics in P3\nAbstractVariety of dim 8\n\njulia> UQB = tautological_bundles(G)[2]\nAbstractBundle of rank 1 on AbstractVariety of dim 3\n\njulia> p = pullback(structure_map(PF), chern_class(UQB, 1))\n-c[1]\n\njulia> Z = dual(tautological_bundles(PF)[1])\nAbstractBundle of rank 1 on AbstractVariety of dim 8\n\njulia> z = chern_class(Z, 1)\nz\n\njulia> integral((2*p + z)^8)\n92\n","category":"page"},{"location":"Experimental/IntersectionTheory/examples/#Steiner's-Problem:-How-Many-Conics-are-Tangent-to-5-General-Conics-in-\\mathbb-P2?","page":"Illustrating Examples From Enumerative Geometry","title":"Steiner's Problem: How Many Conics are Tangent to 5 General Conics in mathbb P^2?","text":"","category":"section"},{"location":"Experimental/IntersectionTheory/examples/","page":"Illustrating Examples From Enumerative Geometry","title":"Illustrating Examples From Enumerative Geometry","text":"julia> P2 = abstract_projective_space(2)\nAbstractVariety of dim 2\n\njulia> P5 = abstract_projective_space(5, symbol = \"H\")\nAbstractVariety of dim 5\n\njulia> h = gens(P2)[1]\nh\n\njulia> H = gens(P5)[1]\nH\n\njulia> i = hom(P2, P5, [2*h])\nAbstractVarietyMap from AbstractVariety of dim 2 to AbstractVariety of dim 5\n\njulia> Bl, E, j = blowup(i)\n(AbstractVariety of dim 5, AbstractVariety of dim 4, AbstractVarietyMap from AbstractVariety of dim 4 to AbstractVariety of dim 5)\n\njulia> e, HBl = gens(chow_ring(Bl))\n2-element Vector{MPolyQuoRingElem{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}}:\n e\n H\n\njulia> integral((6*HBl-2*e)^5)\n3264\n","category":"page"},{"location":"Experimental/IntersectionTheory/examples/#How-Many-Conics-lie-on-the-General-Quintic-Hypersurface-in-\\mathbb-P4?","page":"Illustrating Examples From Enumerative Geometry","title":"How Many Conics lie on the General Quintic Hypersurface in mathbb P^4?","text":"","category":"section"},{"location":"Experimental/IntersectionTheory/examples/","page":"Illustrating Examples From Enumerative Geometry","title":"Illustrating Examples From Enumerative Geometry","text":"julia> G = abstract_grassmannian(3, 5)\nAbstractVariety of dim 6\n\njulia> USBd = dual(tautological_bundles(G)[1])\nAbstractBundle of rank 3 on AbstractVariety of dim 6\n\njulia> F = symmetric_power(USBd, 2)\nAbstractBundle of rank 6 on AbstractVariety of dim 6\n\njulia> PF = abstract_projective_bundle(F) # the parameter space of conics in P3\nAbstractVariety of dim 11\n\njulia> A = symmetric_power(USBd, 5) - symmetric_power(USBd, 3)*OO(PF, -1)\nAbstractBundle of rank 11 on AbstractVariety of dim 11\n\njulia> integral(top_chern_class(A))\n609250\n","category":"page"},{"location":"Hecke/manual/number_fields/class_fields/#Class-Field-Theory","page":"Class Field Theory","title":"Class Field Theory","text":"","category":"section"},{"location":"Hecke/manual/number_fields/class_fields/","page":"Class Field Theory","title":"Class Field Theory","text":"CurrentModule = Hecke","category":"page"},{"location":"Hecke/manual/number_fields/class_fields/#Introduction","page":"Class Field Theory","title":"Introduction","text":"","category":"section"},{"location":"Hecke/manual/number_fields/class_fields/","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/manual/number_fields/class_fields/","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/manual/number_fields/class_fields/","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/manual/number_fields/class_fields/#Ray-Class-Groups","page":"Class Field Theory","title":"Ray Class Groups","text":"","category":"section"},{"location":"Hecke/manual/number_fields/class_fields/","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/manual/number_fields/class_fields/","page":"Class Field Theory","title":"Class Field Theory","text":"ray_class_group(m::Hecke.AbsNumFieldOrderIdeal{Nemo.AbsSimpleNumField,Nemo.AbsSimpleNumFieldElem}, inf_plc::Vector{Hecke.InfPlc}; p_part, n_quo)\nclass_group(K::Nemo.AbsSimpleNumField)\nnorm_group(f::Nemo.PolyRingElem, mR::Hecke.MapRayClassGrp, is_abelian::Bool)\nnorm_group(K::RelSimpleNumField{AbsSimpleNumFieldElem}, mR::Hecke.MapRayClassGrp, is_abelian::Bool)","category":"page"},{"location":"Hecke/manual/number_fields/class_fields/#ray_class_group-Tuple{AbsSimpleNumFieldOrderIdeal, Vector{InfPlc}}","page":"Class Field Theory","title":"ray_class_group","text":"ray_class_group(m::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}, inf_plc::Vector{InfPlc}; n_quo::Int, lp::Dict{AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}, Int}) -> FinGenAbGroup, 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/manual/number_fields/class_fields/#class_group-Tuple{AbsSimpleNumField}","page":"Class Field Theory","title":"class_group","text":"class_group(K::AbsSimpleNumField) -> FinGenAbGroup, 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/manual/number_fields/class_fields/#norm_group-Tuple{PolyRingElem, MapRayClassGrp, Bool}","page":"Class Field Theory","title":"norm_group","text":"norm_group(f::Nemo.PolyRingElem, mR::Hecke.MapRayClassGrp, is_abelian::Bool = true; of_closure::Bool = false) -> Hecke.FinGenGrpAb, Hecke.FinGenGrpAbMap\n\nnorm_group(f::Array{PolyRingElem{AbsSimpleNumFieldElem}}, 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/manual/number_fields/class_fields/#norm_group-Tuple{Hecke.RelSimpleNumField{AbsSimpleNumFieldElem}, MapRayClassGrp, Bool}","page":"Class Field Theory","title":"norm_group","text":"norm_group(K::RelSimpleNumField{AbsSimpleNumFieldElem}, mR::Hecke.MapRayClassGrp) -> Hecke.FinGenGrpAb, Hecke.FinGenGrpAbMap\n\nnorm_group(K::RelNonSimpleNumField{AbsSimpleNumFieldElem}, 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/manual/number_fields/class_fields/#Ray-Class-Fields","page":"Class Field Theory","title":"Ray Class Fields","text":"","category":"section"},{"location":"Hecke/manual/number_fields/class_fields/","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/manual/number_fields/class_fields/","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/manual/number_fields/class_fields/","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.FinGenAbGroupHom)\nray_class_field(I::Hecke.AbsNumFieldOrderIdeal; n_quo, p_part)\nray_class_field(I::Hecke.AbsNumFieldOrderIdeal, ::Vector{InfPlc}; n_quo, p_part)\nhilbert_class_field(k::AbsSimpleNumField)\nring_class_field(::AbsNumFieldOrder)","category":"page"},{"location":"Hecke/manual/number_fields/class_fields/#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/manual/number_fields/class_fields/#ray_class_field-Tuple{Union{Hecke.MapClassGrp, MapRayClassGrp}, FinGenAbGroupHom}","page":"Class Field Theory","title":"ray_class_field","text":"ray_class_field(m::Union{MapClassGrp, MapRayClassGrp}, quomap::FinGenAbGroupHom) -> 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/manual/number_fields/class_fields/#ray_class_field-Tuple{AbsNumFieldOrderIdeal}","page":"Class Field Theory","title":"ray_class_field","text":"ray_class_field(I::AbsNumFieldOrderIdeal; 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/manual/number_fields/class_fields/#ray_class_field-Tuple{AbsNumFieldOrderIdeal, Vector{InfPlc}}","page":"Class Field Theory","title":"ray_class_field","text":"ray_class_field(I::AbsNumFieldOrderIdeal, 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/manual/number_fields/class_fields/#hilbert_class_field-Tuple{AbsSimpleNumField}","page":"Class Field Theory","title":"hilbert_class_field","text":"hilbert_class_field(k::AbsSimpleNumField) -> ClassField\n\nThe Hilbert class field of k as a formal (ray-) class field.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/number_fields/class_fields/#ring_class_field-Tuple{AbsNumFieldOrder}","page":"Class Field Theory","title":"ring_class_field","text":"ring_class_field(O::AbsNumFieldOrder) -> 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/manual/number_fields/class_fields/#Example","page":"Class Field Theory","title":"Example","text":"","category":"section"},{"location":"Hecke/manual/number_fields/class_fields/","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/manual/number_fields/class_fields/#Conversions","page":"Class Field Theory","title":"Conversions","text":"","category":"section"},{"location":"Hecke/manual/number_fields/class_fields/","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/manual/number_fields/class_fields/","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/manual/number_fields/class_fields/","page":"Class Field Theory","title":"Class Field Theory","text":"number_field(C::ClassField)","category":"page"},{"location":"Hecke/manual/number_fields/class_fields/#number_field-Tuple{ClassField}","page":"Class Field Theory","title":"number_field","text":"number_field(CF::ClassField) -> RelNonSimpleNumField{AbsSimpleNumFieldElem}\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/manual/number_fields/class_fields/","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/manual/number_fields/class_fields/","page":"Class Field Theory","title":"Class Field Theory","text":"ray_class_field(K::RelSimpleNumField{AbsSimpleNumFieldElem})\ngenus_field(A::ClassField, k::AbsSimpleNumField)\nmaximal_abelian_subfield(A::ClassField, k::AbsSimpleNumField)\nmaximal_abelian_subfield(K::RelSimpleNumField{AbsSimpleNumFieldElem})","category":"page"},{"location":"Hecke/manual/number_fields/class_fields/#ray_class_field-Tuple{Hecke.RelSimpleNumField{AbsSimpleNumFieldElem}}","page":"Class Field Theory","title":"ray_class_field","text":"ray_class_field(K::RelSimpleNumField{AbsSimpleNumFieldElem}) -> ClassField\nray_class_field(K::AbsSimpleNumField) -> 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/manual/number_fields/class_fields/#genus_field-Tuple{ClassField, AbsSimpleNumField}","page":"Class Field Theory","title":"genus_field","text":"genus_field(A::ClassField, k::AbsSimpleNumField) -> 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/manual/number_fields/class_fields/#maximal_abelian_subfield-Tuple{ClassField, AbsSimpleNumField}","page":"Class Field Theory","title":"maximal_abelian_subfield","text":"maximal_abelian_subfield(A::ClassField, k::AbsSimpleNumField) -> 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/manual/number_fields/class_fields/#maximal_abelian_subfield-Tuple{Hecke.RelSimpleNumField{AbsSimpleNumFieldElem}}","page":"Class Field Theory","title":"maximal_abelian_subfield","text":"maximal_abelian_subfield(K::RelSimpleNumField{AbsSimpleNumFieldElem}; 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/manual/number_fields/class_fields/#Invariants","page":"Class Field Theory","title":"Invariants","text":"","category":"section"},{"location":"Hecke/manual/number_fields/class_fields/","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::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}, inf_plc::Vector{InfPlc})\nis_normal(C::ClassField)\nis_central(C::ClassField)","category":"page"},{"location":"Hecke/manual/number_fields/class_fields/#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/manual/number_fields/class_fields/#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/manual/number_fields/class_fields/#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/manual/number_fields/class_fields/#discriminant-Tuple{ClassField}","page":"Class Field Theory","title":"discriminant","text":"discriminant(C::ClassField) -> AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}\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/manual/number_fields/class_fields/#conductor-Tuple{ClassField}","page":"Class Field Theory","title":"conductor","text":"conductor(C::ClassField) -> AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}, Vector{InfPlc}\n\nReturn the conductor of the abelian extension corresponding to C.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/number_fields/class_fields/#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/manual/number_fields/class_fields/#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/manual/number_fields/class_fields/#is_conductor-Tuple{ClassField, AbsSimpleNumFieldOrderIdeal, Vector{InfPlc}}","page":"Class Field Theory","title":"is_conductor","text":"is_conductor(C::Hecke.ClassField, m::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}, inf_plc::Vector{InfPlc}=InfPlc[]; check) -> AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}, 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/manual/number_fields/class_fields/#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/manual/number_fields/class_fields/#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/manual/number_fields/class_fields/#Operations","page":"Class Field Theory","title":"Operations","text":"","category":"section"},{"location":"Hecke/manual/number_fields/class_fields/","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.AbsNumFieldOrderIdeal)\nHecke.is_subfield(a::ClassField, b::ClassField)\nHecke.is_local_norm(r::Hecke.ClassField, a::Hecke.AbsNumFieldOrderElem)\nHecke.is_local_norm(r::Hecke.ClassField, a::Hecke.AbsNumFieldOrderElem, p::Hecke.AbsNumFieldOrderIdeal)\nHecke.normal_closure(r::Hecke.ClassField)\nsubfields(r::ClassField)","category":"page"},{"location":"Hecke/manual/number_fields/class_fields/#*-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/manual/number_fields/class_fields/#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/manual/number_fields/class_fields/#==-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/manual/number_fields/class_fields/#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/manual/number_fields/class_fields/#prime_decomposition_type-Tuple{ClassField, AbsNumFieldOrderIdeal}","page":"Class Field Theory","title":"prime_decomposition_type","text":"prime_decomposition_type(C::ClassField, p::AbsNumFieldOrderIdeal) -> (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/manual/number_fields/class_fields/#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/manual/number_fields/class_fields/#is_local_norm-Tuple{ClassField, AbsNumFieldOrderElem}","page":"Class Field Theory","title":"is_local_norm","text":"is_local_norm(r::ClassField, a::AbsNumFieldOrderElem) -> 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/manual/number_fields/class_fields/#is_local_norm-Tuple{ClassField, AbsNumFieldOrderElem, AbsNumFieldOrderIdeal}","page":"Class Field Theory","title":"is_local_norm","text":"is_local_norm(r::ClassField, a::AbsNumFieldOrderElem, p::AbsNumFieldOrderIdeal) -> 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/manual/number_fields/class_fields/#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/manual/number_fields/class_fields/#subfields-Tuple{ClassField}","page":"Class Field Theory","title":"subfields","text":"subfields(C::ClassField; degree::Int, is_normal, type) -> 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\nIf the optional keyword is_normal is given, then only those that are normal over the field fixed by the automorphisms is returned. For normal base fields, this amounts to extensions that are normal over Q.\n\nIf the optional keyword is_normal is set to a list of automorphisms, then only those wil be considered.\n\ntype can be set to the desired relative Galois group, given as a vector of integers descibing the structure.\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":"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> 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":"julia> c = RR(1//3, precision=100)\n[0.33333333333333333333 +/- 3.34e-21]\n\njulia> d = RR(1//3, precision=4)\n[0.3 +/- 0.0438]","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> 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 non-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_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":"julia> a = RR(1)\n1.0000000000000000000\n\njulia> b = RR(2)\n2.0000000000000000000\n\njulia> c = RR(12)\n12.000000000000000000\n\njulia> x = ball(a, b)\n[+/- 3.01]\n\njulia> y = ball(c, b)\n[1e+1 +/- 4.01]\n\njulia> mid = midpoint(x)\n1.0000000000000000000\n\njulia> rad = radius(x)\n[2.0000000037252902985 +/- 3.81e-20]\n\njulia> print(x, \"\\n\", y, \"\\n\", mid, \"\\n\", rad)\n[+/- 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 non-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_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> 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> 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> 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> 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 RealFieldElem 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 ArbFieldElem 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> 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> 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 non-negative 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\nrising_factorial(x::RingElement, n::Integer)\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\nExamples\n\njulia> R, x = ZZ[:x];\n\njulia> rising_factorial(x, 1)\nx\n\njulia> rising_factorial(x, 2)\nx^2 + x\n\njulia> rising_factorial(4, 2)\n20\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\nrising_factorial2(x::RingElement, n::Integer)\n\nReturn a tuple containing the rising factorial x(x + 1)cdots (x + n - 1) and its derivative. If n 0 we throw a DomainError().\n\nExamples\n\njulia> R, x = ZZ[:x];\n\njulia> rising_factorial2(x, 1)\n(x, 1)\n\njulia> rising_factorial2(x, 2)\n(x^2 + x, 2*x + 1)\n\njulia> rising_factorial2(4, 2)\n(20, 9)\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> 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 ArbFieldElem 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 ArbFieldElem 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":"a = rand(RR)\nb = rand(RR; randtype = :null_exact)\nc = rand(RR; randtype = :exact)\nd = rand(RR; randtype = :special)","category":"page"},{"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 and is_power.","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":"Hecke/manual/orders/introduction/#Introduction","page":"Introduction","title":"Introduction","text":"","category":"section"},{"location":"Hecke/manual/orders/introduction/","page":"Introduction","title":"Introduction","text":"CurrentModule = Hecke","category":"page"},{"location":"Hecke/manual/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 [Coh93], [Coh00], [PZ97] or [Mar18].","category":"page"},{"location":"Hecke/manual/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/manual/orders/introduction/#Orders-of-absolute-number-fields","page":"Introduction","title":"Orders of absolute number fields","text":"","category":"section"},{"location":"Hecke/manual/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/manual/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/manual/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/manual/orders/introduction/#Orders-of-relative-number-fields","page":"Introduction","title":"Orders of relative number fields","text":"","category":"section"},{"location":"Hecke/manual/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 [Coh00], Chapter 1 for an introduction.","category":"page"},{"location":"Hecke/manual/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/manual/orders/introduction/#Examples","page":"Introduction","title":"Examples","text":"","category":"section"},{"location":"Hecke/manual/orders/introduction/","page":"Introduction","title":"Introduction","text":"Usually, to create an order, one starts with a field (or a polynomial):","category":"page"},{"location":"Hecke/manual/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 = equation_order(K)\nZ_K = maximal_order(K)\nconductor(E)\nE == Z_K","category":"page"},{"location":"Hecke/manual/orders/introduction/","page":"Introduction","title":"Introduction","text":"Once orders are created, we can play with elements and ideals:","category":"page"},{"location":"Hecke/manual/orders/introduction/","page":"Introduction","title":"Introduction","text":"lp = prime_decomposition(Z_K, 2)\np = lp[1][1]\nis_principal(p)\nfl, alpha = is_principal_with_data(p^2)\nnorm(alpha)","category":"page"},{"location":"Hecke/manual/orders/introduction/","page":"Introduction","title":"Introduction","text":"It is possible to work with residue fields as well:","category":"page"},{"location":"Hecke/manual/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":"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::Symbol=: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(f::RelPowerSeriesRingElem, g::RelPowerSeriesRingElem; inner)\n\nCompose the series a with the series b and return the result.\n\nIf inner = :second, then f(g) is returned and g must have positive valuation.\nIf inner = :first, then g(f) is returned and f must have positive valuation.\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(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::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::MPolyRingElem{T}, x::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\nderivative(a::Generic.PuiseuxSeriesElem{T}) where T <: RingElement\n\nReturn the derivative of the given Puiseux series a.\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(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\nintegral(f::RelPowerSeriesRingElem{T}) -> RelPowerSeriesRingElem\n\nReturn the integral of the power series f.\n\n\n\n\n\nintegral(a::Generic.PuiseuxSeriesElem{T}) where T <: RingElement\n\nReturn the integral of the given Puiseux series a.\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::SeriesElem{T}) where T <: FieldElement\n\nReturn the logarithm of the power series a.\n\n\n\n\n\nlog(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/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::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\nexp(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\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::AbstractUnitRange{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 = finite_field(19, 2, \"x2\")\n(Finite field of degree 2 and characteristic 19, x2)\n\njulia> k4, x4 = finite_field(19, 4, \"x4\")\n(Finite field of degree 4 and characteristic 19, x4)\n\njulia> f = embed(k2, k4)\nMorphism of finite fields\n from finite field of degree 2 and characteristic 19\n to finite field of degree 4 and characteristic 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\npreimage_map(f::FinFieldPreimage)\n\nCompute the preimage map corresponding to the preimage of the embedding f, i.e. return 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 = finite_field(13, 7, \"x7\")\n(Finite field of degree 7 and characteristic 13, x7)\n\njulia> k21, x21 = finite_field(13, 21, \"x21\")\n(Finite field of degree 21 and characteristic 13, x21)\n\njulia> s = preimage_map(k7, k21)\nPreimage of a morphism\n from finite field of degree 7 and characteristic 13\n to finite field of degree 21 and characteristic 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 = Oscar.doctestsetup()","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 modeled 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 R\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 R at complement of prime ideal (x, y, z)\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 RQ 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> Rg, (x, y, z) = graded_polynomial_ring(QQ, [:x, :y, :z]);\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 = SubquoModule(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, \nnumber_of_generators(M) / ngens(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 R\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> number_of_generators(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> Rg, (x, y, z) = graded_polynomial_ring(QQ, [:x, :y, :z]);\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)\nZ\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; check::Bool=true)\n\nReturn the degrees of the generators of M.\n\nExamples\n\njulia> Rg, (x, y, z) = graded_polynomial_ring(QQ, [:x, :y, :z]);\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{FinGenAbGroupElem}:\n [2]\n [2]\n [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 R\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 R\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 R\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 R\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> Rg, (x, y, z) = graded_polynomial_ring(QQ, [:x, :y, :z]);\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> Rg, (x, y, z) = graded_polynomial_ring(QQ, [:x, :y, :z]);\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; check::Bool=true)\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> Rg, (x, y, z) = graded_polynomial_ring(QQ, [:x, :y, :z]);\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)\n[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)\n[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 R\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> Rg, (x, y, z) = graded_polynomial_ring(QQ, [:x, :y, :z]);\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 R\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> Rg, (x, y, z) = graded_polynomial_ring(QQ, [:x, :y, :z]);\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 R\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 R\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> Rg, (x, y, z) = graded_polynomial_ring(QQ, [:x, :y, :z]);\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 R\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> Rg, (x, y, z) = graded_polynomial_ring(QQ, [:x, :y, :z]);\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 R\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], 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\njulia> Rg, (x, y, z) = graded_polynomial_ring(QQ, [:x, :y, :z]);\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/","page":"Subquotients","title":"Subquotients","text":"annihilator(N::SubquoModule{T}) where T","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/subquotients/#annihilator-Union{Tuple{SubquoModule{T}}, Tuple{T}} where T","page":"Subquotients","title":"annihilator","text":" annihilator(N::SubquoModule{T}) where T\n\nReturn the annihilator of N.\n\nnote: Note\nBy definition, the annihilator of N is the ideal 0N = a in R mid aN = 0. Here, R = base_ring(N).\n\nExamples\n\njulia> R, (x, y, z) = polynomial_ring(QQ, [:x, :y, :z]);\n\njulia> F = free_module(R, 1);\n\njulia> AN = R[y;];\n\njulia> BN = R[x^2; y^3; 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> J = annihilator(N)\nIdeal generated by\n y^2\n x^2\n z^4\n\n\njulia> S, (x, y, z) = polynomial_ring(QQ, [:x, :y, :z]);\n\njulia> I = ideal(S, [x*y*z])\nIdeal generated by\n x*y*z\n\njulia> R, _ = quo(S, I)\n(Quotient of multivariate polynomial ring by ideal (x*y*z), Map: S -> R)\n\njulia> F = free_module(R, 1);\n\njulia> AN = R[y;];\n\njulia> BN = R[x^2; y^3; 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> J = annihilator(N)\nIdeal generated by\n x*z\n y^2\n x^2\n z^4\n\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/subquotients/","page":"Subquotients","title":"Subquotients","text":"quotient(M::SubquoModule{T}, N::SubquoModule{T}) where T","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/subquotients/#quotient-Union{Tuple{T}, Tuple{SubquoModule{T}, SubquoModule{T}}} where T","page":"Subquotients","title":"quotient","text":"quotient(M::SubquoModule{T}, N::SubquoModule{T}) where T\n\nGiven subquotients M and N such that ambient_module(M) == ambient_module(N), return the module quotient of M by N regarded as submodules of the common ambient module.\n\nAlternatively, use M:N.\n\nnote: Note\nBy definition, MN = a in R mid aN subset M. Here, R = base_ring(M) = base_ring(N).\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> B = R[x^2; y^3; z^4];\n\njulia> AM = R[x;];\n\njulia> M = SubquoModule(F, AM, B)\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 = R[y;];\n\njulia> N = SubquoModule(F, AN, B)\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> L = quotient(M, N)\nIdeal generated by\n x\n y^2\n z^4\n\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/subquotients/","page":"Subquotients","title":"Subquotients","text":"quotient(M::SubquoModule{T}, J::MPolyIdeal{T}) where T","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/subquotients/#quotient-Union{Tuple{T}, Tuple{SubquoModule{T}, MPolyIdeal{T}}} where T","page":"Subquotients","title":"quotient","text":" quotient(M::SubquoModule{T}, J::MPolyIdeal{T}) where T\n\nReturn the quotient of M by J.\n\nAlternatively, use M:J.\n\nnote: Note\nBy definition, MJ = a in A mid Ja subset M. Here, A is the ambient module of M.\n\nExamples\n\njulia> R, (x, y, z) = polynomial_ring(QQ, [:x, :y, :z]);\n\njulia> F = free_module(R, 1);\n\njulia> AM = R[x;];\n\njulia> BM = R[x^2; y^3; 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> J = ideal(R, [x, y, z])^2\nIdeal generated by\n x^2\n x*y\n x*z\n y^2\n y*z\n z^2\n\njulia> L = quotient(M, J)\nSubquotient of Submodule with 5 generators\n1 -> x*e[1]\n2 -> y^3*e[1]\n3 -> z^4*e[1]\n4 -> y*z^3*e[1]\n5 -> y^2*z^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> ambient_free_module(L) == ambient_free_module(M)\ntrue\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}}) where T","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/subquotients/#sub-Union{Tuple{T}, Tuple{ModuleFP{T}, Vector{<:ModuleFPElem{T}}}} where T","page":"Subquotients","title":"sub","text":"sub(M::ModuleFP{T}, V::Vector{<:ModuleFPElem{T}}; cache_morphism::Bool=false) where T\n\nGiven a vector V of (homogeneous) elements of M, return the (graded) submodule I of M generated by these elements together with its inclusion map `inc : I ↪ M.\n\nWhen cache_morphism is set to true, then inc will be cached and available for transport and friends.\n\nIf only the submodule itself is desired, use sub_object instead.\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 R\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}}; cache_morphism::Bool=false) where T","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/subquotients/#quo-Union{Tuple{T}, Tuple{ModuleFP{T}, Vector{<:ModuleFPElem{T}}}} where T","page":"Subquotients","title":"quo","text":"quo(M::ModuleFP{T}, V::Vector{<:ModuleFPElem{T}}; cache_morphism::Bool=false) where T\n\nGiven a vector V of (homogeneous) elements of M, return a pair (N, pr) consisting of the quotient N = M/⟨V⟩ and the projection map pr : M → N.\n\nIf one is only interested in the actual object M, but not the map, use quo_object instead.\n\nIf cache_morphism is set to true, the projection is cached and available to transport and friends.\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 R\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 R\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 R\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> Rg, (x, y, z) = graded_polynomial_ring(QQ, [: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> 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 R\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> Rg, (x, y, z) = graded_polynomial_ring(QQ, [: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> 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::ModuleFPHom)\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/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> Rg, (x, y, z) = graded_polynomial_ring(QQ, [: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);\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; check::Bool=true)\n\nIf a is graded, return the degree of a.\n\nExamples\n\njulia> Rg, (x, y, z) = graded_polynomial_ring(QQ, [: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);\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)\n[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> Rg, (x, y, z) = graded_polynomial_ring(QQ, [: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);\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)\nZ\n\n\n\n\n\n","category":"method"},{"location":"Experimental/IntersectionTheory/intro/","page":"Introduction","title":"Introduction","text":"CurrentModule = Oscar","category":"page"},{"location":"Experimental/IntersectionTheory/intro/#Introduction","page":"Introduction","title":"Introduction","text":"","category":"section"},{"location":"Experimental/IntersectionTheory/intro/","page":"Introduction","title":"Introduction","text":"In this chapter, we","category":"page"},{"location":"Experimental/IntersectionTheory/intro/","page":"Introduction","title":"Introduction","text":"introduce OSCAR tools which support computations in intersection theory, and\ngive examples which illustrate how intersection theory is used to solve problems from enumerative geometry.","category":"page"},{"location":"Experimental/IntersectionTheory/intro/","page":"Introduction","title":"Introduction","text":"note: Note\nMaking use of OSCAR, a first version of what we present here was written by Jeiao Song as a julia package. This package was \"heavily inspired by the Macaulay2 package Schubert2 and the Sage library Chow. Some functionalities from [the Sage library] Schubert3 are also implemented.\"","category":"page"},{"location":"Experimental/IntersectionTheory/intro/","page":"Introduction","title":"Introduction","text":"note: Note\nSchubert2 was written by Daniel R. Grayson, Michael E. Stillman, Stein A. Strømme, David Eisenbud, and Charley Crissman while Chow is due to Manfred Lehn and Christoph Sorger. Schubert3 as well as the Singular library schubert.lib were written by Dang Tuan Hiep. The basis for all this work, including ours, is the Maple package Schubert written by Sheldon Katz and Stein A. Strømme.","category":"page"},{"location":"Experimental/IntersectionTheory/intro/","page":"Introduction","title":"Introduction","text":"Throughout the chapter, the varieties we consider are smooth projective varieties over the complex numbers.","category":"page"},{"location":"Experimental/IntersectionTheory/intro/","page":"Introduction","title":"Introduction","text":"note: Note\nThe Chow ring of a variety X is the group of cycles of X modulo an equivalence relation, together with the intersection pairing which defines the multiplication of the ring. Here, in contrast to most textbooks, we consider numerical equivalence classes of cycles rather than rational equivalence classes.","category":"page"},{"location":"Experimental/IntersectionTheory/intro/","page":"Introduction","title":"Introduction","text":"Our approach is abstract in the sense that we do not work with concrete varieties; that is, our varieties are not given by equations. Instead, we represent a variety by specifying its dimension together with its Chow ring and, possibly, further data. We refer to such such a collection of data as an abstract variety, and to results obtained from manipulating the data as results which apply to all (smooth projective complex) varieties sharing the data. ","category":"page"},{"location":"Experimental/IntersectionTheory/intro/","page":"Introduction","title":"Introduction","text":"Of particular interest is the tangent bundle of a variety (recall that the Todd class of the tangent bundle enters the Hirzebruch-Riemann-Roch formula). As with any other vector bundle, the tangent bundle is represented as a collection of data referred to as an abstract vector bundle. The main data here is the Chern character polynomial of the vector bundle.","category":"page"},{"location":"Experimental/IntersectionTheory/intro/","page":"Introduction","title":"Introduction","text":"In the same spirit, we introduce abstract variety maps. Their key ingredient is the pullback morphism between the Chow rings.","category":"page"},{"location":"Experimental/IntersectionTheory/intro/","page":"Introduction","title":"Introduction","text":"General textbooks offering details on theory and algorithms include: ","category":"page"},{"location":"Experimental/IntersectionTheory/intro/","page":"Introduction","title":"Introduction","text":"[EH16]\n[Ful98]","category":"page"},{"location":"Experimental/IntersectionTheory/intro/","page":"Introduction","title":"Introduction","text":"For computations in the Chow rings of abstract flag bundles see ","category":"page"},{"location":"Experimental/IntersectionTheory/intro/","page":"Introduction","title":"Introduction","text":"[GSS22].","category":"page"},{"location":"Experimental/IntersectionTheory/intro/#Contact","page":"Introduction","title":"Contact","text":"","category":"section"},{"location":"Experimental/IntersectionTheory/intro/","page":"Introduction","title":"Introduction","text":"Please direct questions about this part of OSCAR to the following people:","category":"page"},{"location":"Experimental/IntersectionTheory/intro/","page":"Introduction","title":"Introduction","text":"Wolfram Decker,\nTommy Hofmann.","category":"page"},{"location":"Experimental/IntersectionTheory/intro/","page":"Introduction","title":"Introduction","text":"You can ask questions in the OSCAR Slack.","category":"page"},{"location":"Experimental/IntersectionTheory/intro/","page":"Introduction","title":"Introduction","text":"Alternatively, you can raise an issue on github.","category":"page"},{"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 RealMatrix RealMatrixSpace\nmathbbC (arbitrary precision) Arb ComplexMatrix ComplexMatrixSpace\nmathbbR (fixed precision) Arb ArbMatrix ArbMatrixSpace\nmathbbC (fixed precision) Arb AcbMatrix AcbMatrixSpace","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(::RealMatrix, ::RealMatrix)","category":"page"},{"location":"Nemo/matrix/#overlaps-Tuple{RealMatrix, RealMatrix}","page":"Matrices","title":"overlaps","text":"overlaps(x::RealMatrix, y::RealMatrix)\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(::ComplexMatrix, ::ComplexMatrix)","category":"page"},{"location":"Nemo/matrix/#overlaps-Tuple{ComplexMatrix, ComplexMatrix}","page":"Matrices","title":"overlaps","text":"overlaps(x::ComplexMatrix, y::ComplexMatrix)\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(::RealMatrix, ::RealMatrix)","category":"page"},{"location":"Nemo/matrix/#contains-Tuple{RealMatrix, RealMatrix}","page":"Matrices","title":"contains","text":"contains(x::RealMatrix, y::RealMatrix)\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(::ComplexMatrix, ::ComplexMatrix)","category":"page"},{"location":"Nemo/matrix/#contains-Tuple{ComplexMatrix, ComplexMatrix}","page":"Matrices","title":"contains","text":"contains(x::ComplexMatrix, y::ComplexMatrix)\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":"julia> C = RR[1 2; 3 4]\n[1.0000000000000000000 2.0000000000000000000]\n[3.0000000000000000000 4.0000000000000000000]\n\njulia> D = RR[\"1 +/- 0.1\" \"2 +/- 0.1\"; \"3 +/- 0.1\" \"4 +/- 0.1\"]\n[[1e+0 +/- 0.101] [2e+0 +/- 0.101]]\n[[3e+0 +/- 0.101] [4e+0 +/- 0.101]]\n\njulia> overlaps(C, D)\ntrue\n\njulia> contains(D, C)\ntrue","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":"julia> A = ZZ[2 3 5; 1 4 7; 9 6 3]\n[2 3 5]\n[1 4 7]\n[9 6 3]\n\njulia> B = A<<5\n[ 64 96 160]\n[ 32 128 224]\n[288 192 96]\n\njulia> C = B>>2\n[16 24 40]\n[ 8 32 56]\n[72 48 24]","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":"julia> A = ZZ[2 3 5; 1 4 7; 9 6 3]\n[2 3 5]\n[1 4 7]\n[9 6 3]\n\njulia> c = det_divisor(A)\n3\n\njulia> d = det_given_divisor(A, c)\n-30","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\nExamples\n\njulia> A = ZZ[1 0 1; 2 3 1; 5 6 7]\n[1 0 1]\n[2 3 1]\n[5 6 7]\n\njulia> B, d = pseudo_inv(A)\n([15 6 -3; -9 2 1; -3 -6 3], 12)\n\n\n\n\n\n","category":"method"},{"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":"julia> A = ZZ[2 3 5; 1 4 7; 9 2 2]\n[2 3 5]\n[1 4 7]\n[9 2 2]\n\njulia> reduce_mod(A, ZZ(5))\n[2 3 0]\n[1 4 2]\n[4 2 2]\n\njulia> reduce_mod(A, 2)\n[0 1 1]\n[1 0 1]\n[1 0 0]","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::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/","page":"Matrices","title":"Matrices","text":"Examples","category":"page"},{"location":"Nemo/matrix/","page":"Matrices","title":"Matrices","text":"julia> R, = residue_ring(ZZ, 7)\n(Integers modulo 7, Map: ZZ -> ZZ/(7))\n\njulia> a = R[4 5 6; 7 3 2; 1 4 5]\n[4 5 6]\n[0 3 2]\n[1 4 5]\n\njulia> b = lift(a)\n[-3 -2 -1]\n[ 0 3 2]\n[ 1 -3 -2]","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{MatSpace{ZZRingElem}}","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{MatSpace{QQFieldElem}}","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":"julia> hadamard(matrix_space(ZZ, 3, 3))\nERROR: Unable to create Hadamard matrix\n[...]\n\njulia> A = hadamard(matrix_space(ZZ, 4, 4))\n[1 1 1 1]\n[1 -1 1 -1]\n[1 1 -1 -1]\n[1 -1 -1 1]\n\njulia> is_hadamard(A)\ntrue\n\njulia> B = hilbert(matrix_space(QQ, 3, 3))\n[ 1 1//2 1//3]\n[1//2 1//3 1//4]\n[1//3 1//4 1//5]","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":"julia> A = ZZ[2 3 5; 1 4 7; 19 3 7]\n[ 2 3 5]\n[ 1 4 7]\n[19 3 7]\n\njulia> B = hnf(A)\n[1 0 16]\n[0 1 18]\n[0 0 27]\n\njulia> H, T = hnf_with_transform(A)\n([1 0 16; 0 1 18; 0 0 27], [-43 30 3; -44 31 3; -73 51 5])\n\njulia> M = hnf_modular(A, ZZ(27))\n[1 0 16]\n[0 1 18]\n[0 0 27]\n\njulia> N = hnf_modular_eldiv(A, ZZ(27))\n[1 0 16]\n[0 1 18]\n[0 0 27]\n\njulia> is_hnf(M)\ntrue","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":"LLLContext(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, ::LLLContext)","category":"page"},{"location":"Nemo/matrix/#lll-Tuple{ZZMatrix, LLLContext}","page":"Matrices","title":"lll","text":"lll(x::ZZMatrix, ctx::LLLContext = LLLContext(0.99, 0.51))\n\nReturn a matrix L whose rows form an LLL-reduced basis of the mathbbZ-lattice generated by the rows of x. L may contain additional zero rows.\n\nBy default, the LLL is performed with reduction parameters delta = 099 and eta = 051. These defaults can be overridden by specifying an optional context object.\n\nSee lll_gram for a function taking the Gram matrix as input.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/matrix/","page":"Matrices","title":"Matrices","text":"lll_with_transform(::ZZMatrix, ::LLLContext)","category":"page"},{"location":"Nemo/matrix/#lll_with_transform-Tuple{ZZMatrix, LLLContext}","page":"Matrices","title":"lll_with_transform","text":"lll_with_transform(x::ZZMatrix, ctx::LLLContext = LLLContext(0.99, 0.51))\n\nReturn a tuple (L T) where the rows of L form an LLL-reduced basis of the mathbbZ-lattice generated by the rows of x and T is a transformation matrix so that L = Tx. L may contain additional zero rows. See lll for the used default parameters which can be overridden by supplying an optional context object.\n\nSee lll_gram_with_transform for a function taking the Gram matrix as input.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/matrix/","page":"Matrices","title":"Matrices","text":"lll_gram(::ZZMatrix, ::LLLContext)","category":"page"},{"location":"Nemo/matrix/#lll_gram-Tuple{ZZMatrix, LLLContext}","page":"Matrices","title":"lll_gram","text":"lll_gram(x::ZZMatrix, ctx::LLLContext = LLLContext(0.99, 0.51, :gram))\n\nReturn the Gram matrix L of an LLL-reduced basis of the lattice given by the Gram matrix x. The matrix x must be symmetric and non-singular.\n\nBy default, the LLL is performed with reduction parameters delta = 099 and eta = 051. 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_with_transform(::ZZMatrix, ::LLLContext)","category":"page"},{"location":"Nemo/matrix/#lll_gram_with_transform-Tuple{ZZMatrix, LLLContext}","page":"Matrices","title":"lll_gram_with_transform","text":"lll_gram_with_transform(x::ZZMatrix, ctx::LLLContext = LLLContext(0.99, 0.51, :gram))\n\nReturn a tuple (L T) where L is the Gram matrix of an LLL-reduced basis of the lattice given by the Gram matrix x and T is a transformation matrix with L = T^top x T. The matrix x must be symmetric and non-singular.\n\nSee lll_gram for the used default parameters which 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_with_removal(::ZZMatrix, ::ZZRingElem, ::LLLContext)","category":"page"},{"location":"Nemo/matrix/#lll_with_removal-Tuple{ZZMatrix, ZZRingElem, LLLContext}","page":"Matrices","title":"lll_with_removal","text":"lll_with_removal(x::ZZMatrix, b::ZZRingElem, ctx::LLLContext = LLLContext(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, ::LLLContext)","category":"page"},{"location":"Nemo/matrix/#lll_with_removal_transform-Tuple{ZZMatrix, ZZRingElem, LLLContext}","page":"Matrices","title":"lll_with_removal_transform","text":"lll_with_removal_transform(x::ZZMatrix, b::ZZRingElem, ctx::LLLContext = LLLContext(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, ::LLLContext)","category":"page"},{"location":"Nemo/matrix/#lll!-Tuple{ZZMatrix, LLLContext}","page":"Matrices","title":"lll!","text":"lll!(x::ZZMatrix, ctx::LLLContext = LLLContext(0.99, 0.51))\n\nCompute an LLL-reduced basis of the mathbbZ-lattice generated by the rows of x inplace.\n\nBy default, the LLL is performed with reduction parameters delta = 099 and eta = 051. These defaults can be overridden by specifying an optional context object.\n\nSee lll_gram! for a function taking the Gram matrix as input.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/matrix/","page":"Matrices","title":"Matrices","text":"lll_gram!(::ZZMatrix, ::LLLContext)","category":"page"},{"location":"Nemo/matrix/#lll_gram!-Tuple{ZZMatrix, LLLContext}","page":"Matrices","title":"lll_gram!","text":"lll_gram!(x::ZZMatrix, ctx::LLLContext = LLLContext(0.99, 0.51, :gram))\n\nCompute the Gram matrix of an LLL-reduced basis of the lattice given by the Gram matrix x inplace. The matrix x must be symmetric and non-singular.\n\nBy default, the LLL is performed with reduction parameters delta = 099 and eta = 051. 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":"Examples","category":"page"},{"location":"Nemo/matrix/","page":"Matrices","title":"Matrices","text":"julia> A = ZZ[2 3 5; 1 4 7; 19 3 7]\n[ 2 3 5]\n[ 1 4 7]\n[19 3 7]\n\njulia> L = lll(A, LLLContext(0.95, 0.55, :zbasis, :approx))\n[-1 1 2]\n[-1 -2 2]\n[ 4 1 1]\n\njulia> L, T = lll_with_transform(A)\n([-1 1 2; -1 -2 2; 4 1 1], [-1 1 0; -15 10 1; 3 -2 0])\n\njulia> G = lll_gram(gram(A))\n[ 6 3 -1]\n[ 3 9 -4]\n[-1 -4 18]\n\njulia> G, T = lll_gram_with_transform(gram(A))\n([6 3 -1; 3 9 -4; -1 -4 18], [-1 1 0; -15 10 1; 3 -2 0])\n\njulia> r, L = lll_with_removal(A, ZZ(100))\n(3, [-1 1 2; -1 -2 2; 4 1 1])\n\njulia> r, L, T = lll_with_removal_transform(A, ZZ(100))\n(3, [-1 1 2; -1 -2 2; 4 1 1], [-1 1 0; -15 10 1; 3 -2 0])","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":"julia> A = ZZ[2 3 5; 1 4 7; 19 3 7]\n[ 2 3 5]\n[ 1 4 7]\n[19 3 7]\n\njulia> B = snf(A)\n[1 0 0]\n[0 1 0]\n[0 0 27]\n\njulia> is_snf(B) == true\ntrue\n\njulia> B = ZZ[2 0 0; 0 4 0; 0 0 7]\n[2 0 0]\n[0 4 0]\n[0 0 7]\n\njulia> C = snf_diagonal(B)\n[1 0 0]\n[0 2 0]\n[0 0 28]","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":"julia> R, = residue_ring(ZZ, 12);\n\njulia> A = R[4 1 0; 0 0 5; 0 0 0 ]\n[4 1 0]\n[0 0 5]\n[0 0 0]\n\njulia> B = strong_echelon_form(A)\n[4 1 0]\n[0 3 0]\n[0 0 1]","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":"julia> R, = residue_ring(ZZ, 12);\n\njulia> A = R[4 1 0; 0 0 5; 0 0 0 ]\n[4 1 0]\n[0 0 5]\n[0 0 0]\n\njulia> B = howell_form(A)\n[4 1 0]\n[0 3 0]\n[0 0 1]","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":"julia> A = RR[2 0 0; 0 3 0; 0 0 1]\n[2.0000000000000000000 0 0]\n[ 0 3.0000000000000000000 0]\n[ 0 0 1.0000000000000000000]\n\njulia> B = exp(A)\n[[7.389056098930650227 +/- 4.72e-19] 0 0]\n[ 0 [20.08553692318766774 +/- 1.94e-18] 0]\n[ 0 0 [2.718281828459045235 +/- 4.30e-19]]","category":"page"},{"location":"Nemo/matrix/#Norm","page":"Matrices","title":"Norm","text":"","category":"section"},{"location":"Nemo/matrix/","page":"Matrices","title":"Matrices","text":"bound_inf_norm(::RealMatrix)","category":"page"},{"location":"Nemo/matrix/#bound_inf_norm-Tuple{RealMatrix}","page":"Matrices","title":"bound_inf_norm","text":"bound_inf_norm(x::RealMatrix)\n\nReturns a non-negative element z of type ArbFieldElem, 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(::ComplexMatrix)","category":"page"},{"location":"Nemo/matrix/#bound_inf_norm-Tuple{ComplexMatrix}","page":"Matrices","title":"bound_inf_norm","text":"bound_inf_norm(x::ComplexMatrix)\n\nReturns a non-negative element z of type AcbFieldElem, 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":"julia> A = RR[1 2 3; 4 5 6; 7 8 9]\n[1.0000000000000000000 2.0000000000000000000 3.0000000000000000000]\n[4.0000000000000000000 5.0000000000000000000 6.0000000000000000000]\n[7.0000000000000000000 8.0000000000000000000 9.0000000000000000000]\n\njulia> d = bound_inf_norm(A)\n[24.000000059604644775 +/- 3.91e-19]","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":"julia> A = RR[1 2 3; 4 5 6; 7 8 9]\n[1.0000000000000000000 2.0000000000000000000 3.0000000000000000000]\n[4.0000000000000000000 5.0000000000000000000 6.0000000000000000000]\n[7.0000000000000000000 8.0000000000000000000 9.0000000000000000000]\n\njulia> B = ldexp(A, 4)\n[16.000000000000000000 32.000000000000000000 48.000000000000000000]\n[64.000000000000000000 80.000000000000000000 96.000000000000000000]\n[112.00000000000000000 128.00000000000000000 144.00000000000000000]\n\njulia> overlaps(16*A, B)\ntrue","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":"julia> A = CC[1 2 3; 4 5 6; 7 8 9]\n[1.0000000000000000000 2.0000000000000000000 3.0000000000000000000]\n[4.0000000000000000000 5.0000000000000000000 6.0000000000000000000]\n[7.0000000000000000000 8.0000000000000000000 9.0000000000000000000]\n\njulia> isreal(A)\ntrue\n\njulia> isreal(onei(CC)*A)\nfalse","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":"eigenvalues(::ComplexMatrix)\neigenvalues_with_multiplicities(::ComplexMatrix)\neigenvalues_simple(a::ComplexMatrix)","category":"page"},{"location":"Nemo/matrix/#eigenvalues-Tuple{ComplexMatrix}","page":"Matrices","title":"eigenvalues","text":"eigenvalues(A::ComplexMatrix)\n\nReturn the eigenvalues of A.\n\nThis function is experimental.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/matrix/#eigenvalues_with_multiplicities-Tuple{ComplexMatrix}","page":"Matrices","title":"eigenvalues_with_multiplicities","text":"eigenvalues_with_multiplicities(A::ComplexMatrix)\n\nReturn the eigenvalues of A with their algebraic multiplicities 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/#eigenvalues_simple-Tuple{ComplexMatrix}","page":"Matrices","title":"eigenvalues_simple","text":"eigenvalues_simple(A::ComplexMatrix, algorithm::Symbol = :default)\n\nReturns the eigenvalues of A as a vector of AcbFieldElem. 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":"julia> A = CC[1 2 3; 0 4 5; 0 0 6]\n[1.0000000000000000000 2.0000000000000000000 3.0000000000000000000]\n[ 0 4.0000000000000000000 5.0000000000000000000]\n[ 0 0 6.0000000000000000000]\n\njulia> eigenvalues_simple(A)\n3-element Vector{ComplexFieldElem}:\n 1.0000000000000000000\n 4.0000000000000000000\n 6.0000000000000000000\n\njulia> A = CC[2 2 3; 0 2 5; 0 0 2]\n[2.0000000000000000000 2.0000000000000000000 3.0000000000000000000]\n[ 0 2.0000000000000000000 5.0000000000000000000]\n[ 0 0 2.0000000000000000000]\n\njulia> eigenvalues(A)\n1-element Vector{ComplexFieldElem}:\n 2.0000000000000000000\n\njulia> eigenvalues_with_multiplicities(A)\n1-element Vector{Tuple{ComplexFieldElem, Int64}}:\n (2.0000000000000000000, 3)","category":"page"},{"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 the following constructors.","category":"page"},{"location":"AbstractAlgebra/mpolynomial/","page":"Sparse distributed multivariate polynomials","title":"Sparse distributed multivariate polynomials","text":"polynomial_ring(::Ring, ::Vector{Symbol})\npolynomial_ring(::Ring, ::Vararg)\npolynomial_ring(::Ring, ::Int)\n@polynomial_ring","category":"page"},{"location":"AbstractAlgebra/mpolynomial/#polynomial_ring-Tuple{Ring, Vector{Symbol}}","page":"Sparse distributed multivariate polynomials","title":"polynomial_ring","text":"polynomial_ring(R::Ring, varnames::Vector{Symbol}; cached=true, internal_ordering=:lex)\n\nGiven a coefficient ring R and variable names, say varnames = [:x1, :x2, ...], return a tuple S, [x1, x2, ...] of the polynomial ring S = Rx1 x2 dots and its generators x1 x2 dots.\n\nBy default (cached=true), the output S will be cached, i.e. if polynomial_ring is invoked again with the same arguments, the same (identical) ring is returned. Setting cached to false ensures a distinct new ring is returned, and will also prevent it from being cached.\n\nThe monomial ordering used for the internal storage of polynomials in S can be set with internal_ordering and must be one of :lex, :deglex or :degrevlex.\n\nSee also: polynomial_ring(::Ring, ::Vararg), @polynomial_ring.\n\nExample\n\njulia> S, generators = polynomial_ring(ZZ, [:x, :y, :z])\n(Multivariate polynomial ring in 3 variables over integers, AbstractAlgebra.Generic.MPoly{BigInt}[x, y, z])\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/mpolynomial/#polynomial_ring-Tuple{Ring, Vararg}","page":"Sparse distributed multivariate polynomials","title":"polynomial_ring","text":"polynomial_ring(R::Ring, varnames...; cached=true, internal_ordering=:lex)\npolynomial_ring(R::Ring, varnames::Tuple; cached=true, internal_ordering=:lex)\n\nLike polynomial_ring(::Ring, ::Vector{Symbol}) with more ways to give varnames as specified in variable_names.\n\nReturn a tuple S, generators... with generators[i] corresponding to varnames[i].\n\nnote: Note\nIn the first method, varnames must not be empty, and if it consists of only one name, the univariate polynomial_ring(R::NCRing, s::VarName) method is called instead.\n\nExamples\n\njulia> S, (a, b, c) = polynomial_ring(ZZ, [:a, :b, :c])\n(Multivariate polynomial ring in 3 variables over integers, AbstractAlgebra.Generic.MPoly{BigInt}[a, b, c])\n\njulia> S, x, y = polynomial_ring(ZZ, :x => (1:2, 1:2), :y => 1:3);\n\njulia> S\nMultivariate polynomial ring in 7 variables x[1, 1], x[2, 1], x[1, 2], x[2, 2], ..., y[3]\n over integers\n\njulia> x\n2×2 Matrix{AbstractAlgebra.Generic.MPoly{BigInt}}:\n x[1, 1] x[1, 2]\n x[2, 1] x[2, 2]\n\njulia> y\n3-element Vector{AbstractAlgebra.Generic.MPoly{BigInt}}:\n y[1]\n y[2]\n y[3]\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/mpolynomial/#polynomial_ring-Tuple{Ring, Int64}","page":"Sparse distributed multivariate polynomials","title":"polynomial_ring","text":"polynomial_ring(R::Ring, varnames...; cached=true, internal_ordering=:lex)\npolynomial_ring(R::Ring, varnames::Tuple; cached=true, internal_ordering=:lex)\n\nLike polynomial_ring(::Ring, ::Vector{Symbol}) with more ways to give varnames as specified in variable_names.\n\nReturn a tuple S, generators... with generators[i] corresponding to varnames[i].\n\nnote: Note\nIn the first method, varnames must not be empty, and if it consists of only one name, the univariate polynomial_ring(R::NCRing, s::VarName) method is called instead.\n\nExamples\n\njulia> S, (a, b, c) = polynomial_ring(ZZ, [:a, :b, :c])\n(Multivariate polynomial ring in 3 variables over integers, AbstractAlgebra.Generic.MPoly{BigInt}[a, b, c])\n\njulia> S, x, y = polynomial_ring(ZZ, :x => (1:2, 1:2), :y => 1:3);\n\njulia> S\nMultivariate polynomial ring in 7 variables x[1, 1], x[2, 1], x[1, 2], x[2, 2], ..., y[3]\n over integers\n\njulia> x\n2×2 Matrix{AbstractAlgebra.Generic.MPoly{BigInt}}:\n x[1, 1] x[1, 2]\n x[2, 1] x[2, 2]\n\njulia> y\n3-element Vector{AbstractAlgebra.Generic.MPoly{BigInt}}:\n y[1]\n y[2]\n y[3]\n\n\n\n\n\npolynomial_ring(R::Ring, n::Int, s::Symbol=:x; cached=true, internal_ordering=:lex)\n\nSame as polynomial_ring(::Ring, [\"s$i\" for i in 1:n]).\n\nExample\n\njulia> S, x = polynomial_ring(ZZ, 3)\n(Multivariate polynomial ring in 3 variables over integers, AbstractAlgebra.Generic.MPoly{BigInt}[x1, x2, x3])\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/mpolynomial/#@polynomial_ring","page":"Sparse distributed multivariate polynomials","title":"@polynomial_ring","text":"@polynomial_ring(R::Ring, varnames...; cached=true, internal_ordering=:lex)\n\nReturn polynomial ring from polynomial_ring(::Ring, ::Vararg) and introduce the generators into the current scope.\n\nExamples\n\njulia> S = @polynomial_ring(ZZ, \"x#\" => (1:2, 1:2), \"y#\" => 1:3)\nMultivariate polynomial ring in 7 variables x11, x21, x12, x22, ..., y3\n over integers\n\njulia> x11, x21, x12, x22\n(x11, x21, x12, x22)\n\njulia> y1, y2, y3\n(y1, y2, y3)\n\njulia> (S, [x11 x12; x21 x22], [y1, y2, y3]) == polynomial_ring(ZZ, \"x#\" => (1:2, 1:2), \"y#\" => 1:3)\ntrue\n\n\n\n\n\n","category":"macro"},{"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]; internal_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\njulia> R, x = polynomial_ring(ZZ, 10); R\nMultivariate polynomial ring in 10 variables x1, x2, x3, x4, ..., x10\n over integers\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\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)\nnumber_of_variables(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":"internal_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::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::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::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::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::MPolyRingElem{T}, x::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::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::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::MPolyRingElem)\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::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::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::MPolyRingElem{T}, m::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]; internal_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 = internal_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> number_of_variables(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::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 <: 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::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::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::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::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::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 <: 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::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::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::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 <: 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::PolyRing{T}, p::MPolyRingElem{T}) where T <: 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::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::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 <: 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::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 = matrix_ring(ZZ, 2)\nMatrix ring 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], internal_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::MPolyRingElem{T}, x::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::AbstractUnitRange{Int}, term_range::AbstractUnitRange{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 = Oscar.doctestsetup()","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::GAPGroup, N::GAPGroup)","category":"page"},{"location":"Groups/quotients/#quo-Tuple{Oscar.GAPGroup, Oscar.GAPGroup}","page":"Quotients","title":"quo","text":"quo([::Type{Q}, ]G::GAPGroup, N::GAPGroup) where Q <: 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 or SubPcGroup (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(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::GAPGroup, N::GAPGroup) for information about the type of G/N.\n\nFor groups G of type SubFPGroup, this syntax is not supported. In this case, you can switch to group of different type, using isomorphism, or try to create the normal subgroup N in question, and call quo(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> 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, FinGenAbGroup}\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\nA scheme X over some base_ring 𝕜 of type BaseRingType, given by means of affine charts and their gluings.\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: affine 2-space\n 2: affine 2-space\n in the coordinate(s)\n 1: [x, y]\n 2: [u, v]\n\njulia> V1 = PrincipalOpenSubset(U1, x); # Preparations for gluing\n\njulia> V2 = PrincipalOpenSubset(U2, u);\n\njulia> f = morphism(V1, V2, [1//x, y//x]); # The gluing isomorphism\n\njulia> g = morphism(V2, V1, [1//u, v//u]); # and its inverse\n\njulia> G = Gluing(U1, U2, f, g); # Construct the gluing\n\njulia> add_gluing!(C, G) # Make the gluing part of the Covering\nCovering\n described by patches\n 1: affine 2-space\n 2: affine 2-space\n in the coordinate(s)\n 1: [x, y]\n 2: [u, v]\n\njulia> X = CoveredScheme(C) # Create a CoveredScheme from the Gluing\nScheme\n over rational field\nwith default covering\n described by patches\n 1: affine 2-space\n 2: affine 2-space\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: affine 2-space\n 2: affine 2-space\n 3: affine 2-space\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/","page":"Covered schemes","title":"Covered schemes","text":"Other constructors:","category":"page"},{"location":"AlgebraicGeometry/Schemes/CoveredSchemes/","page":"Covered schemes","title":"Covered schemes","text":"disjoint_union(Xs::Vector{<:AbsCoveredScheme})","category":"page"},{"location":"AlgebraicGeometry/Schemes/CoveredSchemes/#disjoint_union-Tuple{Vector{<:AbsCoveredScheme}}","page":"Covered schemes","title":"disjoint_union","text":"disjoint_union(Xs::Vector{<:AbsCoveredScheme}) -> (AbsCoveredScheme, Vector{<:AbsCoveredSchemeMor})\n\nReturn the disjoint union of the non-empty vector of covered schemes as a covered scheme.\n\nInput:\n\na vector Xs of covered schemes.\n\nOutput:\n\nA pair (X mathrminjections) where X is a covered scheme and mathrminjections is a vector of inclusion morphisms ı_icolon X_i to X, where X is the disjoint union of the covered schemes X_i in Xs.\n\nExamples\n\njulia> R_1, (x, y, z) = graded_polynomial_ring(QQ, [:x, :y, :z]);\n\njulia> I_1 = ideal(R_1, z*x^2 + y^3);\n\njulia> X_1 = covered_scheme(proj(R_1, I_1))\nScheme\n over rational field\nwith default covering\n described by patches\n 1: scheme((y//x)^3 + (z//x))\n 2: scheme((x//y)^2*(z//y) + 1)\n 3: scheme((x//z)^2 + (y//z)^3)\n in the coordinate(s)\n 1: [(y//x), (z//x)]\n 2: [(x//y), (z//y)]\n 3: [(x//z), (y//z)]\n\njulia> R_2, (u, v) = polynomial_ring(rational_field(), [:u, :v]);\n\njulia> I_2 = ideal(R_2, u + v^2);\n\njulia> X_2 = covered_scheme(spec(R_2, I_2))\nScheme\n over rational field\nwith default covering\n described by patches\n 1: scheme(u + v^2)\n in the coordinate(s)\n 1: [u, v]\n\njulia> X, injections = disjoint_union([X_1, X_2]);\n\njulia> X\nScheme\n over rational field\nwith default covering\n described by patches\n 1: scheme((y//x)^3 + (z//x))\n 2: scheme((x//y)^2*(z//y) + 1)\n 3: scheme((x//z)^2 + (y//z)^3)\n 4: scheme(u + v^2)\n in the coordinate(s)\n 1: [(y//x), (z//x)]\n 2: [(x//y), (z//y)]\n 3: [(x//z), (y//z)]\n 4: [u, v]\n\njulia> injections\n2-element Vector{CoveredSchemeMorphism{CoveredScheme{QQField}, CoveredScheme{QQField}, AbsAffineSchemeMor}}:\n Hom: scheme over QQ covered with 3 patches -> scheme over QQ covered with 4 patches\n Hom: scheme over QQ covered with 1 patch -> scheme over QQ covered with 4 patches\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: scheme((s1//s0) - (s2//s0)^2)\n 2: scheme((s0//s1) - (s2//s1)^2)\n 3: scheme((s0//s2)*(s1//s2) - 1)\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{AffineScheme{QQField, MPolyQuoRing{QQMPolyRingElem}}}:\n scheme((s1//s0) - (s2//s0)^2)\n scheme((s0//s1) - (s2//s1)^2)\n scheme((s0//s2)*(s1//s2) - 1)\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: scheme((s1//s0) - (s2//s0)^2)\n 2: scheme((s0//s1) - (s2//s1)^2)\n 3: scheme((s0//s2)*(s1//s2) - 1)\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: scheme((s1//s0) - (s2//s0)^2)\n 2: scheme((s0//s1) - (s2//s1)^2)\n 3: scheme((s0//s2)*(s1//s2) - 1)\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)\nis_smooth(X::AbsCoveredScheme)","category":"page"},{"location":"AlgebraicGeometry/Schemes/CoveredSchemes/#Methods","page":"Covered schemes","title":"Methods","text":"","category":"section"},{"location":"AlgebraicGeometry/Schemes/CoveredSchemes/","page":"Covered schemes","title":"Covered schemes","text":"fiber_product(f::AbsCoveredSchemeMorphism, g::AbsCoveredSchemeMorphism)\nis_normal(X::AbsCoveredScheme; check::Bool=true)\nnormalization(X::AbsCoveredScheme; check::Bool=true)","category":"page"},{"location":"AlgebraicGeometry/Schemes/CoveredSchemes/#fiber_product-Tuple{AbsCoveredSchemeMorphism, AbsCoveredSchemeMorphism}","page":"Covered schemes","title":"fiber_product","text":"fiber_product(f::AbsCoveredSchemeMorphism, g::AbsCoveredSchemeMorphism)\n\nFor a diagram XxY ––> Y | | g V V X–––> Z f this computes the fiber product XxY together with the canonical maps to X and Y and returns the resulting triple.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/CoveredSchemes/#is_normal-Tuple{AbsCoveredScheme}","page":"Covered schemes","title":"is_normal","text":"is_normal(X::AbsCoveredScheme; check::Bool=true) -> Bool\n\nInput:\n\na reduced scheme X,\nif check is true, then confirm that X is reduced; this is expensive.\n\nOutput:\n\nReturns whether the scheme X is normal.\n\nExamples\n\njulia> R, (x, y, z) = QQ[:x, :y, :z];\n\njulia> X = covered_scheme(spec(R));\n\njulia> is_normal(X)\ntrue\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/CoveredSchemes/#normalization-Tuple{AbsCoveredScheme}","page":"Covered schemes","title":"normalization","text":"normalization(X::AbsCoveredScheme; check::Bool=true) -> (AbsCoveredScheme, AbsCoveredSchemeMor, Vector{<:AbsCoveredSchemeMor})\n\nReturn the normalization of the reduced scheme X.\n\nInput:\n\na reduced scheme X,\nif check is true, then confirm that X is reduced; this is expensive.\n\nOutput:\n\nA triple (Y nucolon Y to X mathrminjs) where Y is a normal scheme, nu is the normalization, and mathrminjs is a vector of inclusion morphisms ı_icolon Y_i to Y, where Y_i are the connected components of the scheme Y. See Tag 0CDV in [Stacks] or Definition 7.5.1 in [Liu06] for normalization of non-integral schemes.\n\nExamples\n\njulia> R, (x, y, z) = graded_polynomial_ring(QQ, [:x, :y, :z]);\n\njulia> I = ideal(R, z*x^2 + y^3);\n\njulia> X = covered_scheme(proj(R, I))\nScheme\n over rational field\nwith default covering\n described by patches\n 1: scheme((y//x)^3 + (z//x))\n 2: scheme((x//y)^2*(z//y) + 1)\n 3: scheme((x//z)^2 + (y//z)^3)\n in the coordinate(s)\n 1: [(y//x), (z//x)]\n 2: [(x//y), (z//y)]\n 3: [(x//z), (y//z)]\n\njulia> Y, pr_mor = normalization(X);\n\njulia> Y\nScheme\n over rational field\nwith default covering\n described by patches\n 1: scheme((y//x)^3 + (z//x))\n 2: scheme((x//y)^2*(z//y) + 1)\n 3: scheme(-T(1)*y + x, T(1)*x + y^2, T(1)^2 + y, x^2 + y^3)\n in the coordinate(s)\n 1: [(y//x), (z//x)]\n 2: [(x//y), (z//y)]\n 3: [T(1), x, y]\n\njulia> pr_mor\nCovered scheme morphism\n from scheme over QQ covered with 3 patches\n 1a: [(y//x), (z//x)] scheme((y//x)^3 + (z//x))\n 2a: [(x//y), (z//y)] scheme((x//y)^2*(z//y) + 1)\n 3a: [T(1), x, y] scheme(-T(1)*y + x, T(1)*x + y^2, T(1)^2 + y, x^2 + y^3)\n to scheme over QQ covered with 3 patches\n 1b: [(y//x), (z//x)] scheme((y//x)^3 + (z//x))\n 2b: [(x//y), (z//y)] scheme((x//y)^2*(z//y) + 1)\n 3b: [(x//z), (y//z)] scheme((x//z)^2 + (y//z)^3)\ngiven by the pullback functions\n 1a -> 1b\n (y//x) -> (y//x)\n (z//x) -> (z//x)\n ----------------------------------------\n 2a -> 2b\n (x//y) -> (x//y)\n (z//y) -> (z//y)\n ----------------------------------------\n 3a -> 3b\n (x//z) -> x\n (y//z) -> y\n\njulia> inclusion_morphisms(pr_mor)\n1-element Vector{CoveredSchemeMorphism{CoveredScheme{QQField}, CoveredScheme{QQField}, AbsAffineSchemeMor}}:\n Hom: scheme over QQ covered with 3 patches -> scheme over QQ covered with 3 patches\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/CoveredSchemes/#The-modeling-of-covered-schemes-and-their-expected-behavior","page":"Covered schemes","title":"The modeling of covered schemes and their expected behavior","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: affine 2-space\n 2: affine 2-space\n 3: affine 2-space\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 SimplifiedAffineScheme 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 gluings 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 defined by a Julia function\n from integers\n to integers\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.Generic\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/FreeAssociativeAlgebra.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.FreeAssociativeAlgebraElem{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.FreeAssociativeAlgebra{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::FreeAssociativeAlgebra)\nbase_ring(a::FreeAssociativeAlgebraElem)\nparent(a::FreeAssociativeAlgebraElem)\ncharacteristic(R::FreeAssociativeAlgebra)","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.FreeAssociativeAlgebraElem{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.FreeAssociativeAlgebraElem{BigInt}[x, y, z])\n\njulia> B = MPolyBuildCtx(R)\nBuilder for an element of free associative algebra\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.FreeAssociativeAlgebraElem{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::FreeAssociativeAlgebra)\nnumber_of_variables(f::FreeAssociativeAlgebra)\ngens(S::FreeAssociativeAlgebra)\ngen(S::FreeAssociativeAlgebra, i::Int)\nis_gen(x::FreeAssociativeAlgebraElem)\ntotal_degree(a::FreeAssociativeAlgebraElem)\nlength(f::FreeAssociativeAlgebraElem)","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::FreeAssociativeAlgebraElem)\nleading_monomial(a::FreeAssociativeAlgebraElem)\nleading_term(a::FreeAssociativeAlgebraElem)\nleading_exponent_word(a::FreeAssociativeAlgebraElem)","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::FreeAssociativeAlgebraElem, n::Int)\nmonomial(f::FreeAssociativeAlgebraElem, n::Int)\nterm(f::FreeAssociativeAlgebraElem, 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.FreeAssociativeAlgebraElem{T}, i::Int) where T <: RingElement","category":"page"},{"location":"AbstractAlgebra/free_associative_algebra/#exponent_word-Union{Tuple{T}, Tuple{AbstractAlgebra.Generic.FreeAssociativeAlgebraElem{T}, Int64}} where T<:RingElement","page":"Free algebras","title":"exponent_word","text":"exponent_word(a::FreeAssociativeAlgebraElem{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.FreeAssociativeAlgebraElem{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/","page":"Free algebras","title":"Free algebras","text":"evaluate(a::AbstractAlgebra.FreeAssociativeAlgebraElem{T}, vals::Vector{U}) where {T <: RingElement, U <: NCRingElem}","category":"page"},{"location":"AbstractAlgebra/free_associative_algebra/#evaluate-Union{Tuple{U}, Tuple{T}, Tuple{FreeAssociativeAlgebraElem{T}, Vector{U}}} where {T<:RingElement, U<:NCRingElem}","page":"Free algebras","title":"evaluate","text":"evaluate(a::FreeAssociativeAlgebraElem{T}, vals::Vector{U}) where {T <: RingElement, U <: NCRingElem}\n\nEvaluate a 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 vals.\n\nThe syntax a(vals...) is also supported.\n\nExamples\n\njulia> R, (x, y) = free_associative_algebra(ZZ, [\"x\", \"y\"]);\n\njulia> f = x*y - y*x\nx*y - y*x\n\njulia> S = matrix_ring(ZZ, 2);\n\njulia> m1 = S([1 2; 3 4])\n[1 2]\n[3 4]\n\njulia> m2 = S([0 1; 1 0])\n[0 1]\n[1 0]\n\njulia> evaluate(f, [m1, m2])\n[-1 -3]\n[ 3 1]\n\njulia> m1*m2 - m2*m1 == evaluate(f, [m1, m2])\ntrue\n\njulia> m1*m2 - m2*m1 == f(m1, m2)\ntrue\n\n\n\n\n\n","category":"method"},{"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::FreeAssociativeAlgebraElem)\ncoefficients(p::FreeAssociativeAlgebraElem)\nmonomials(p::FreeAssociativeAlgebraElem)","category":"page"},{"location":"AbstractAlgebra/free_associative_algebra/","page":"Free algebras","title":"Free algebras","text":"exponent_words(a::FreeAssociativeAlgebraElem{T}) where T <: RingElement","category":"page"},{"location":"AbstractAlgebra/free_associative_algebra/#exponent_words-Union{Tuple{AbstractAlgebra.Generic.FreeAssociativeAlgebraElem{T}}, Tuple{T}} where T<:RingElement","page":"Free algebras","title":"exponent_words","text":"exponent_words(a::FreeAssociativeAlgebraElem{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.FreeAssociativeAlgebraElem{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":"AbstractAlgebra/free_associative_algebra/#Groebner-bases","page":"Free algebras","title":"Groebner bases","text":"","category":"section"},{"location":"AbstractAlgebra/free_associative_algebra/","page":"Free algebras","title":"Free algebras","text":"The function groebner_basis provides the computation of a Groebner basis of an ideal, given a set of generators of that ideal. Since such a Groebner basis is not necessarily finite, one can additionally pass a reduction_bound to the function, to only compute a partial Groebner basis.","category":"page"},{"location":"AbstractAlgebra/free_associative_algebra/","page":"Free algebras","title":"Free algebras","text":"groebner_basis(g::Vector{FreeAssociativeAlgebraElem{T}}, reduction_bound::Int = typemax(Int), remove_redundancies::Bool = false) where T <: FieldElement\n\nnormal_form(f::FreeAssociativeAlgebraElem{T}, g::Vector{FreeAssociativeAlgebraElem{T}}, aut::AhoCorasickAutomaton) where T\n\ninterreduce!(g::Vector{FreeAssociativeAlgebraElem{T}}) where T","category":"page"},{"location":"AbstractAlgebra/free_associative_algebra/#groebner_basis-Union{Tuple{Array{AbstractAlgebra.Generic.FreeAssociativeAlgebraElem{T}, 1}}, Tuple{T}, Tuple{Array{AbstractAlgebra.Generic.FreeAssociativeAlgebraElem{T}, 1}, Int64}, Tuple{Array{AbstractAlgebra.Generic.FreeAssociativeAlgebraElem{T}, 1}, Int64, Bool}} where T<:FieldElement","page":"Free algebras","title":"groebner_basis","text":"groebner_basis(g::Vector{FreeAssociativeAlgebraElem{T}}, reduction_bound::Int = typemax(Int), remove_redundancies::Bool = false)\n\nCompute a Groebner basis for the ideal generated by g. Stop when reduction_bound many non-zero entries have been added to the Groebner basis. If the computation stops due to the bound being exceeded, the result is in general not an actual Groebner basis, just a subset of one. However, whenever the normal form with respect to this incomplete Groebner basis is 0, it will also be 0 with respect to the full Groebner basis.\n\nIf remove_redundancies is set to true, some redundant obstructions will be removed during the computation, which might save time, however in practice it seems to inflate the running time regularly.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/free_associative_algebra/#normal_form-Union{Tuple{T}, Tuple{AbstractAlgebra.Generic.FreeAssociativeAlgebraElem{T}, Array{AbstractAlgebra.Generic.FreeAssociativeAlgebraElem{T}, 1}, AbstractAlgebra.Generic.AhoCorasickAutomaton}} where T","page":"Free algebras","title":"normal_form","text":"normal_form(f::FreeAssociativeAlgebraElem{T}, g::Vector{FreeAssociativeAlgebraElem{T}}, aut::AhoCorasickAutomaton)\n\nAssuming g is a Groebner basis and aut an Aho-Corasick automaton for the elements of g, compute the normal form of f with respect to g\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/free_associative_algebra/#interreduce!-Union{Tuple{Array{AbstractAlgebra.Generic.FreeAssociativeAlgebraElem{T}, 1}}, Tuple{T}} where T","page":"Free algebras","title":"interreduce!","text":"interreduce!(g::Vector{FreeAssociativeAlgebraElem{T}}) where T\n\nInterreduce a given Groebner basis with itself, i.e. compute the normal form of each element of g with respect to the rest of the elements and discard elements with normal form 0 and duplicates.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/free_associative_algebra/","page":"Free algebras","title":"Free algebras","text":"The implementation uses a non-commutative version of the Buchberger algorithm as described in","category":"page"},{"location":"AbstractAlgebra/free_associative_algebra/","page":"Free algebras","title":"Free algebras","text":"Xingqiang Xiu, Non-commutative Gröbner Bases and Applications, PhD thesis, 2012.","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 = @free_associative_algebra(GF(2), [:x, :y, :u, :v, :t, :s])\nFree associative algebra on 6 indeterminates x, y, u, v, ..., s\n over finite field F_2\n\njulia> g = Generic.groebner_basis([u*(x*y)^3 + u*(x*y)^2 + u + v, (y*x)^3*t + (y*x)^2*t + t + s])\n5-element Vector{AbstractAlgebra.Generic.FreeAssociativeAlgebraElem{AbstractAlgebra.GFElem{Int64}}}:\n u*x*y*x*y*x*y + u*x*y*x*y + u + v\n y*x*y*x*y*x*t + y*x*y*x*t + t + s\n u*x*s + v*x*t\n u*x*y*x*s + v*x*y*x*t\n u*x*y*x*y*x*s + v*x*y*x*y*x*t","category":"page"},{"location":"AbstractAlgebra/free_associative_algebra/","page":"Free algebras","title":"Free algebras","text":"In order to check whether a given element of the algebra is in the ideal generated by a Groebner basis g, one can compute its normal form.","category":"page"},{"location":"AbstractAlgebra/free_associative_algebra/","page":"Free algebras","title":"Free algebras","text":"julia> R = @free_associative_algebra(GF(2), [:x, :y, :u, :v, :t, :s]);\n\njulia> g = Generic.groebner_basis([u*(x*y)^3 + u*(x*y)^2 + u + v, (y*x)^3*t + (y*x)^2*t + t + s]);\n\njulia> normal_form(u*(x*y)^3*s*t + u*(x*y)^2*s*t +u*s*t + v*s*t, g)\n0","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 integral 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":"Currently, the project features the following:","category":"page"},{"location":"Experimental/QuadFormAndIsom/introduction/","page":"Quadratic forms and isometries","title":"Quadratic forms and isometries","text":"enumeration of conjugacy classes of isometries of finite order for even lattices (in the case of at most 2 prime divisors);\nenumeration of conjugacy classes of isometries with irreducible and reciprocal minimal polynomial for integral lattices (with maximal equation order);\nprimitive embeddings/extensions for integral lattices;\nequivariant primitive extensions for integral lattices;\nmiscellaneous operations on integral/rational quadratic form endowed with an isometry.","category":"page"},{"location":"Experimental/QuadFormAndIsom/introduction/#Current-applications-of-this-project","page":"Quadratic forms and isometries","title":"Current applications 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::NCRing, s::VarName; cached::Bool = true)","category":"page"},{"location":"AbstractAlgebra/polynomial/#polynomial_ring-Tuple{NCRing, Union{Char, AbstractString, Symbol}}-AbstractAlgebra-polynomial","page":"Univariate polynomial functionality","title":"polynomial_ring","text":"polynomial_ring(R::NCRing, s::VarName = :x; 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":"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, x = polynomial_ring(ZZ)\n(Univariate polynomial ring in x over integers, x)","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);\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(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\nis_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\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::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::MPolyRingElem)\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);\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":"Base.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\nsqrt(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\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(::PolyRingElem, b::T) where T <: RingElement","category":"page"},{"location":"AbstractAlgebra/polynomial/#evaluate-Union{Tuple{T}, Tuple{PolyRingElem, T}} where T<:RingElement","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(f::PolyRingElem, g::PolyRingElem; inner)\n\nCompose the polynomial a with the polynomial b and return the result.\n\nIf inner = :right, then f(g) is returned.\nIf inner = :left, then g(f) is returned.\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; inner = :second)\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::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::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::MPolyRingElem{T}, x::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\nderivative(a::Generic.PuiseuxSeriesElem{T}) where T <: RingElement\n\nReturn the derivative of the given Puiseux series a.\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(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\nintegral(f::RelPowerSeriesRingElem{T}) -> RelPowerSeriesRingElem\n\nReturn the integral of the power series f.\n\n\n\n\n\nintegral(a::Generic.PuiseuxSeriesElem{T}) where T <: RingElement\n\nReturn the integral of the given Puiseux series a.\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);\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::PolyRing{T}=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::AbstractUnitRange{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":"AbstractAlgebra/polynomial/#Ring-homomorphisms","page":"Univariate polynomial functionality","title":"Ring homomorphisms","text":"","category":"section"},{"location":"AbstractAlgebra/polynomial/","page":"Univariate polynomial functionality","title":"Univariate polynomial functionality","text":"hom(::PolyRing, ::NCRing, ::Any, ::Any)","category":"page"},{"location":"AbstractAlgebra/polynomial/#hom-Tuple{PolyRing, NCRing, Any, Any}","page":"Univariate polynomial functionality","title":"hom","text":"hom(R::AbstractAlgebra.PolyRing, S::NCRing, [coeff_map,] image)\n\nGiven a homomorphism coeff_map from C to S, where C is the coefficient ring of R, and given an element image of S, return the homomorphism from R to S whose restriction to C is coeff_map, and which sends the generator of R to image.\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\nExamples\n\njulia> Zx, x = ZZ[:x];\n\njulia> F = hom(Zx, Zx, x + 1);\n\njulia> F(x^2)\nx^2 + 2*x + 1\n\njulia> Fp = GF(3); Fpy, y = Fp[:y];\n\njulia> G = hom(Zx, Fpy, c -> Fp(c), y^3);\n\njulia> G(5*x + 1)\n2*y^3 + 1\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/latwithisom/","page":"Lattices with isometry","title":"Lattices with isometry","text":"CurrentModule = Oscar","category":"page"},{"location":"Experimental/QuadFormAndIsom/latwithisom/#Lattices-with-isometry","page":"Lattices with isometry","title":"Lattices with isometry","text":"","category":"section"},{"location":"Experimental/QuadFormAndIsom/latwithisom/","page":"Lattices with isometry","title":"Lattices 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":"Lattices with isometry","title":"Lattices with isometry","text":"In Oscar, such a pair is encoded in the type called ZZLatWithIsom:","category":"page"},{"location":"Experimental/QuadFormAndIsom/latwithisom/","page":"Lattices with isometry","title":"Lattices with isometry","text":"ZZLatWithIsom","category":"page"},{"location":"Experimental/QuadFormAndIsom/latwithisom/#ZZLatWithIsom","page":"Lattices with isometry","title":"ZZLatWithIsom","text":"ZZLatWithIsom\n\nA container type for pairs (L f) consisting of an integer lattice L of type ZZLat and an isometry f given as a QQMatrix representing the action on the basis matrix of L.\n\nWe store the ambient space V of L together with an isometry f_a inducing f on L seen as a pair (V f_a) 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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"type"},{"location":"Experimental/QuadFormAndIsom/latwithisom/","page":"Lattices with isometry","title":"Lattices with isometry","text":"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":"Lattices with isometry","title":"Lattices 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":"Lattices with isometry","title":"Lattices 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":"Lattices 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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/latwithisom/#ambient_space-Tuple{ZZLatWithIsom}","page":"Lattices 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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/latwithisom/#isometry-Tuple{ZZLatWithIsom}","page":"Lattices 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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/latwithisom/#lattice-Tuple{ZZLatWithIsom}","page":"Lattices 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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/latwithisom/#order_of_isometry-Tuple{ZZLatWithIsom}","page":"Lattices 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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/latwithisom/","page":"Lattices with isometry","title":"Lattices 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/#Constructors","page":"Lattices with isometry","title":"Constructors","text":"","category":"section"},{"location":"Experimental/QuadFormAndIsom/latwithisom/","page":"Lattices with isometry","title":"Lattices 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":"Lattices with isometry","title":"Lattices 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":"Lattices with isometry","title":"integer_lattice_with_isometry","text":"integer_lattice_with_isometry(L::ZZLat, f::QQMatrix; check::Bool = true,\n ambient_representation = true)\n -> 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 as long as f preserves L.\n\nOtherwise, 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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/latwithisom/#integer_lattice_with_isometry-Tuple{ZZLat}","page":"Lattices 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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/latwithisom/","page":"Lattices with isometry","title":"Lattices 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":"Lattices with isometry","title":"Lattices 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":"Lattices with isometry","title":"Lattices 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":"Lattices 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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/latwithisom/#lattice-Tuple{QuadSpaceWithIsom, MatElem{<:Union{Integer, QQFieldElem, ZZRingElem, Rational}}}","page":"Lattices 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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/latwithisom/#lattice_in_same_ambient_space-Tuple{ZZLatWithIsom, MatElem}","page":"Lattices 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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/latwithisom/#Attributes-and-first-operations","page":"Lattices with isometry","title":"Attributes and first operations","text":"","category":"section"},{"location":"Experimental/QuadFormAndIsom/latwithisom/","page":"Lattices with isometry","title":"Lattices 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":"Lattices with isometry","title":"Lattices 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_elementary(::ZZLatWithIsom, ::IntegerUnion)\nis_elementary_with_prime(::ZZLatWithIsom)\nis_integral(::ZZLatWithIsom)\nis_positive_definite(::ZZLatWithIsom)\nis_primary(::ZZLatWithIsom, ::IntegerUnion)\nis_primary_with_prime(::ZZLatWithIsom)\nis_negative_definite(::ZZLatWithIsom)\nis_unimodular(::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":"Lattices 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> 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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/latwithisom/#characteristic_polynomial-Tuple{ZZLatWithIsom}","page":"Lattices 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":"Lattices 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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/latwithisom/#det-Tuple{ZZLatWithIsom}","page":"Lattices 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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/latwithisom/#discriminant-Tuple{ZZLatWithIsom}","page":"Lattices 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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/latwithisom/#genus-Tuple{ZZLatWithIsom}","page":"Lattices 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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/latwithisom/#gram_matrix-Tuple{ZZLatWithIsom}","page":"Lattices 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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/latwithisom/#is_definite-Tuple{ZZLatWithIsom}","page":"Lattices 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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/latwithisom/#is_even-Tuple{ZZLatWithIsom}","page":"Lattices 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_elementary-Tuple{ZZLatWithIsom, Union{Integer, ZZRingElem}}","page":"Lattices with isometry","title":"is_elementary","text":"is_elementary(Lf::ZZLatWithIsom, p::IntegerUnion) -> Bool\n\nGiven a lattice with isometry (L f) and a prime number p, return whether L is p-elementary, that is whether its discriminant group is an elementary p-group.\n\nExamples\n\njulia> L = root_lattice(:E, 7);\n\njulia> Lf = integer_lattice_with_isometry(L);\n\njulia> is_elementary(Lf, 3)\nfalse\n\njulia> is_elementary(Lf, 2)\ntrue\n\njulia> genus(Lf)\nGenus symbol for integer lattices\nSignatures: (7, 0, 0)\nLocal symbol:\n Local genus symbol at 2: 1^6 2^1_7\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/latwithisom/#is_elementary_with_prime-Tuple{ZZLatWithIsom}","page":"Lattices with isometry","title":"is_elementary_with_prime","text":"is_elementary_with_prime(Lf::ZZLatWithIsom) -> Bool, ZZRingElem\n\nGiven a lattice with isometry (L f), return whether L is elementary, that is whether L is integral and its 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\nExamples\n\njulia> L = root_lattice(:A, 7);\n\njulia> Lf = integer_lattice_with_isometry(L);\n\njulia> is_elementary_with_prime(Lf)\n(false, -1)\n\njulia> is_primary(Lf, 2)\ntrue\n\njulia> genus(Lf)\nGenus symbol for integer lattices\nSignatures: (7, 0, 0)\nLocal symbol:\n Local genus symbol at 2: 1^6 8^1_7\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/latwithisom/#is_integral-Tuple{ZZLatWithIsom}","page":"Lattices 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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/latwithisom/#is_positive_definite-Tuple{ZZLatWithIsom}","page":"Lattices 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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/latwithisom/#is_primary-Tuple{ZZLatWithIsom, Union{Integer, ZZRingElem}}","page":"Lattices with isometry","title":"is_primary","text":"is_primary(Lf::ZZLatWithIsom, p::IntegerUnion) -> Bool\n\nGiven a lattice with isometry (L f) and a prime number p, return whether L is p-primary, that is whether its discriminant group is a p-group.\n\nExamples\n\njulia> L = root_lattice(:A, 6);\n\njulia> Lf = integer_lattice_with_isometry(L);\n\njulia> is_primary(Lf, 7)\ntrue\n\njulia> genus(Lf)\nGenus symbol for integer lattices\nSignatures: (6, 0, 0)\nLocal symbols:\n Local genus symbol at 2: 1^6\n Local genus symbol at 7: 1^-5 7^-1\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/latwithisom/#is_primary_with_prime-Tuple{ZZLatWithIsom}","page":"Lattices with isometry","title":"is_primary_with_prime","text":"is_primary_with_prime(Lf::ZZLatWithIsom) -> Bool, ZZRingElem\n\nGiven a lattice with isometry (L f), return whether L is primary, that is whether L is integral and its 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\nExamples\n\njulia> L = root_lattice(:A, 5);\n\njulia> Lf = integer_lattice_with_isometry(L);\n\njulia> is_primary_with_prime(Lf)\n(false, -1)\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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/latwithisom/#is_negative_definite-Tuple{ZZLatWithIsom}","page":"Lattices 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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/latwithisom/#is_unimodular-Tuple{ZZLatWithIsom}","page":"Lattices with isometry","title":"is_unimodular","text":"is_unimodular(Lf::ZZLatWithIsom) -> Bool\n\nGiven a lattice with isometry (L f), return whether `L is unimodular, that is whether its discriminant group is trivial.\n\nExamples\n\njulia> L = root_lattice(:E, 8);\n\njulia> Lf = integer_lattice_with_isometry(L);\n\njulia> is_unimodular(Lf)\ntrue\n\njulia> genus(Lf)\nGenus symbol for integer lattices\nSignatures: (8, 0, 0)\nLocal symbol:\n Local genus symbol at 2: 1^8\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/latwithisom/#minimum-Tuple{ZZLatWithIsom}","page":"Lattices 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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/latwithisom/#minimal_polynomial-Tuple{ZZLatWithIsom}","page":"Lattices 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":"Lattices 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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/latwithisom/#rank-Tuple{ZZLatWithIsom}","page":"Lattices 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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/latwithisom/#rational_span-Tuple{ZZLatWithIsom}","page":"Lattices 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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/latwithisom/#scale-Tuple{ZZLatWithIsom}","page":"Lattices 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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/latwithisom/#signature_tuple-Tuple{ZZLatWithIsom}","page":"Lattices 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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/latwithisom/","page":"Lattices with isometry","title":"Lattices with isometry","text":"Similarly, some basic operations on mathbb Z-lattices and matrices are available for integer lattices with isometry.","category":"page"},{"location":"Experimental/QuadFormAndIsom/latwithisom/","page":"Lattices with isometry","title":"Lattices with isometry","text":"Base.:^(::ZZLatWithIsom, ::Int)\nbiproduct(::Vector{ZZLatWithIsom})\ndirect_product(::Vector{ZZLatWithIsom})\ndirect_sum(::Vector{ZZLatWithIsom})\ndual(::ZZLatWithIsom)\nlll(::ZZLatWithIsom)\northogonal_submodule(::ZZLatWithIsom, ::QQMatrix)\nrescale(::ZZLatWithIsom, ::RationalUnion)","category":"page"},{"location":"Experimental/QuadFormAndIsom/latwithisom/#^-Tuple{ZZLatWithIsom, Int64}","page":"Lattices 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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/latwithisom/#biproduct-Tuple{Vector{ZZLatWithIsom}}","page":"Lattices 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: quadratic space -> quadratic space, Map: quadratic space -> quadratic space], AbstractSpaceMor[Map: quadratic space -> quadratic space, Map: quadratic space -> quadratic space])\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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/latwithisom/#direct_product-Tuple{Vector{ZZLatWithIsom}}","page":"Lattices 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: quadratic space -> quadratic space, Map: quadratic space -> quadratic space])\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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/latwithisom/#direct_sum-Tuple{Vector{ZZLatWithIsom}}","page":"Lattices 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: quadratic space -> quadratic space, Map: quadratic space -> quadratic space])\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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/latwithisom/#dual-Tuple{ZZLatWithIsom}","page":"Lattices 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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/latwithisom/#lll-Tuple{ZZLatWithIsom}","page":"Lattices 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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/latwithisom/#orthogonal_submodule-Tuple{ZZLatWithIsom, QQMatrix}","page":"Lattices with isometry","title":"orthogonal_submodule","text":"orthogonal_submodule(Lf::ZZLatWithIsom, B::QQMatrix) -> ZZLatWithIsom\n\nGiven a lattice with isometry (L f) and a matrix B with rational entries defining an f-stable sublattice of L, return the largest submodule of L orthogonal to each row of B, equipped with the induced action from f.\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> orthogonal_submodule(Lf, B)\nInteger lattice of rank 2 and degree 5\n with isometry of finite order 2\n given by\n [-1 0]\n [ 0 -1]\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/latwithisom/#rescale-Tuple{ZZLatWithIsom, Union{Integer, QQFieldElem, ZZRingElem, Rational}}","page":"Lattices 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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/latwithisom/#Type-for-finite-order-isometries","page":"Lattices with isometry","title":"Type for finite order isometries","text":"","category":"section"},{"location":"Experimental/QuadFormAndIsom/latwithisom/","page":"Lattices with isometry","title":"Lattices 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.","category":"page"},{"location":"Experimental/QuadFormAndIsom/latwithisom/","page":"Lattices with isometry","title":"Lattices with isometry","text":"type(::ZZLatWithIsom)","category":"page"},{"location":"Experimental/QuadFormAndIsom/latwithisom/#type-Tuple{ZZLatWithIsom}","page":"Lattices 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 the pair (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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/latwithisom/","page":"Lattices with isometry","title":"Lattices 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":"Lattices with isometry","title":"Lattices 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":"Lattices 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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/latwithisom/#is_of_same_type-Tuple{ZZLatWithIsom, ZZLatWithIsom}","page":"Lattices 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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/latwithisom/","page":"Lattices with isometry","title":"Lattices 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":"Lattices with isometry","title":"Lattices with isometry","text":"These names 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":"Lattices with isometry","title":"Lattices with isometry","text":"is_of_hermitian_type(::ZZLatWithIsom)\nis_hermitian(::Dict)","category":"page"},{"location":"Experimental/QuadFormAndIsom/latwithisom/#is_of_hermitian_type-Tuple{ZZLatWithIsom}","page":"Lattices 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 and the associated order is maximal.\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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/latwithisom/#is_hermitian-Tuple{Dict}","page":"Lattices 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-structures-and-trace-equivalence","page":"Lattices with isometry","title":"Hermitian structures and trace equivalence","text":"","category":"section"},{"location":"Experimental/QuadFormAndIsom/latwithisom/","page":"Lattices with isometry","title":"Lattices 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":"Lattices with isometry","title":"Lattices with isometry","text":"hermitian_structure(::ZZLatWithIsom)","category":"page"},{"location":"Experimental/QuadFormAndIsom/latwithisom/#hermitian_structure-Tuple{ZZLatWithIsom}","page":"Lattices 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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/latwithisom/#Discriminant-groups","page":"Lattices with isometry","title":"Discriminant groups","text":"","category":"section"},{"location":"Experimental/QuadFormAndIsom/latwithisom/","page":"Lattices with isometry","title":"Lattices 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":"Lattices with isometry","title":"Lattices with isometry","text":"discriminant_group(::ZZLatWithIsom)","category":"page"},{"location":"Experimental/QuadFormAndIsom/latwithisom/#discriminant_group-Tuple{ZZLatWithIsom}","page":"Lattices 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 D_L of the underlying lattice L as well as the image D_f of the underlying isometry f inside O(D_L).\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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/latwithisom/","page":"Lattices with isometry","title":"Lattices 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. For the remaining cases, we use the hermitian version of Miranda-Morrison theory as presented in [BH23]. The general computation of G_L f has been implemented in this project and it can be indirectly used through the general following method:","category":"page"},{"location":"Experimental/QuadFormAndIsom/latwithisom/","page":"Lattices with isometry","title":"Lattices with isometry","text":"image_centralizer_in_Oq(::ZZLatWithIsom)","category":"page"},{"location":"Experimental/QuadFormAndIsom/latwithisom/#image_centralizer_in_Oq-Tuple{ZZLatWithIsom}","page":"Lattices 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(D_L D_f) of the centralizer O(L f) of f in O(L). Here D_L denotes the discriminant group of L and D_f is the isometry of D_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, Hom: group of isometries of Finite quadratic module generated by 2 elements -> group of isometries of Finite quadratic module generated by 1 elements)\n\njulia> order(G)\n2\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/latwithisom/","page":"Lattices with isometry","title":"Lattices with isometry","text":"Note: hermitian Miranda-Morrison is only available for even lattices.","category":"page"},{"location":"Experimental/QuadFormAndIsom/latwithisom/","page":"Lattices with isometry","title":"Lattices with isometry","text":"For an implementation of the regular Miranda-Morrison 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":"Lattices with isometry","title":"Lattices with isometry","text":"More generally, for a finitely generated subgroup G of O(L), we have implemented a function which computes the representation of G on D_L:","category":"page"},{"location":"Experimental/QuadFormAndIsom/latwithisom/","page":"Lattices with isometry","title":"Lattices with isometry","text":"discriminant_representation(::ZZLat, ::MatrixGroup)","category":"page"},{"location":"Experimental/QuadFormAndIsom/latwithisom/#discriminant_representation-Tuple{ZZLat, MatrixGroup}","page":"Lattices with isometry","title":"discriminant_representation","text":"discriminant_representation(L::ZZLat, G::MatrixGroup;\n ambient_representation::Bool = true,\n check::Bool = true) -> GAPGroupHomomorphism\n\nGiven an integer lattice L and a group G of isometries of L, return the orthogonal representation Gto O(D_L) of G on the discriminant group D_L of L.\n\nIf ambient_representation is set to true, then the isometries in G are considered as matrix representation of their action on the standard basis of the ambient space of L. Otherwise, they are considered as matrix representation of their action on the basis matrix of L.\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/latwithisom/","page":"Lattices with isometry","title":"Lattices 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":"Lattices with isometry","title":"Kernel sublattices","text":"","category":"section"},{"location":"Experimental/QuadFormAndIsom/latwithisom/","page":"Lattices with isometry","title":"Lattices 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":"Lattices with isometry","title":"Lattices 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":"Lattices with isometry","title":"kernel_lattice","text":"kernel_lattice(Lf::ZZLatWithIsom, p::Union{ZZPolyRingElem, 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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/latwithisom/#kernel_lattice-Tuple{ZZLatWithIsom, Integer}","page":"Lattices 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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/latwithisom/","page":"Lattices with isometry","title":"Lattices 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":"Lattices with isometry","title":"Lattices with isometry","text":"coinvariant_lattice(::ZZLatWithIsom)\ninvariant_lattice(::ZZLatWithIsom)\ninvariant_coinvariant_pair(::ZZLatWithIsom)","category":"page"},{"location":"Experimental/QuadFormAndIsom/latwithisom/#coinvariant_lattice-Tuple{ZZLatWithIsom}","page":"Lattices 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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/latwithisom/#invariant_lattice-Tuple{ZZLatWithIsom}","page":"Lattices 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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/latwithisom/#invariant_coinvariant_pair-Tuple{ZZLatWithIsom}","page":"Lattices with isometry","title":"invariant_coinvariant_pair","text":"invariant_coinvariant_pair(Lf::ZZLatWithIsom) -> ZZLatWithIsom, ZZLatWithIsom\n\nGiven a lattice with isometry (L f), return the pair of lattices with isometries consisting of (L^f f_mid L^f) and (L_f f_mid L_f), the invariant and coinvariant sublattices with isometry of (L f).\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/latwithisom/","page":"Lattices with isometry","title":"Lattices 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":"Lattices with isometry","title":"Lattices 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":"Lattices 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, 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 considered as matrix representation of their action on the standard basis of the ambient space of L. Otherwise, they are considered as matrix representation of their action on the basis matrices of L and L_G respectively.\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 QQ)\n\njulia> L == L2\ntrue\n\njulia> G == G2\ntrue\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/latwithisom/#invariant_lattice-Tuple{ZZLat, MatrixGroup}","page":"Lattices 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 considered as matrix representation of their action on the standard basis of the ambient space of L. Otherwise, they are considered as matrix representation of their action on the basis matrix 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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/latwithisom/#invariant_coinvariant_pair-Tuple{ZZLat, MatrixGroup}","page":"Lattices 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, 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 on L.\n\nIf ambient_representation is set to true, the isometries in G and H are considered as matrix representation of their action on the standard basis of the ambient space of L. Otherwise, they are considered as matrix representation of their action on the basis matrices of L and L_G respectively.\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 QQ)\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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/latwithisom/#Signatures","page":"Lattices with isometry","title":"Signatures","text":"","category":"section"},{"location":"Experimental/QuadFormAndIsom/latwithisom/","page":"Lattices with isometry","title":"Lattices 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 intrinsically 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":"Lattices with isometry","title":"Lattices with isometry","text":"signatures(::ZZLatWithIsom)","category":"page"},{"location":"Experimental/QuadFormAndIsom/latwithisom/#signatures-Tuple{ZZLatWithIsom}","page":"Lattices 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 the pair (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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/latwithisom/#Spinor-norm","page":"Lattices with isometry","title":"Spinor norm","text":"","category":"section"},{"location":"Experimental/QuadFormAndIsom/latwithisom/","page":"Lattices with isometry","title":"Lattices with isometry","text":"Given an integer lattice with isometry (L f), one often would like to know the spinor norm of f seen as an isometry of the rational quadratic space Ltimes mathbbQ. See rational_spinor_norm(::QuadSpaceWithIsom) for a definition.","category":"page"},{"location":"Experimental/QuadFormAndIsom/latwithisom/","page":"Lattices with isometry","title":"Lattices with isometry","text":"rational_spinor_norm(::ZZLatWithIsom)","category":"page"},{"location":"Experimental/QuadFormAndIsom/latwithisom/#rational_spinor_norm-Tuple{ZZLatWithIsom}","page":"Lattices with isometry","title":"rational_spinor_norm","text":"rational_spinor_norm(Lf::ZZLatWithIsom; b::Int = -1) -> QQFieldElem\n\nGiven a lattice with isometry (L b f), return the rational spinor norm of the extension of f to Lotimes mathbbQ.\n\nIf Phi is the form on Lotimes mathbbQ, then the spinor norm is computed with respect to bPhi.\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/QuadFormAndIsom/latwithisom/#Equality","page":"Lattices with isometry","title":"Equality","text":"","category":"section"},{"location":"Experimental/QuadFormAndIsom/latwithisom/","page":"Lattices with isometry","title":"Lattices 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":"AlgebraicGeometry/ToricVarieties/BlowupMorphisms/","page":"Toric Blowups (Experimental)","title":"Toric Blowups (Experimental)","text":"CurrentModule = Oscar","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/BlowupMorphisms/#Toric-Blowups-(Experimental)","page":"Toric Blowups (Experimental)","title":"Toric Blowups (Experimental)","text":"","category":"section"},{"location":"AlgebraicGeometry/ToricVarieties/BlowupMorphisms/","page":"Toric Blowups (Experimental)","title":"Toric Blowups (Experimental)","text":"It is a common goal in algebraic geometry to resolve singularities. Certainly, toric varieties and their subvarieties are no exception and we provide a growing set of functionality for such tasks.","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/BlowupMorphisms/","page":"Toric Blowups (Experimental)","title":"Toric Blowups (Experimental)","text":"In general, resolutions of toric varieties need not be toric. Indeed, some of the functionality below requires fully-fledge schemes machinery, which – as of October 2023 – is still in Oscar's experimental state. For this reason, the methods below should be considered experimental.","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/BlowupMorphisms/","page":"Toric Blowups (Experimental)","title":"Toric Blowups (Experimental)","text":"We focus mainly on toric blowups given by a star subdivision of a polyhedral fan along a primitive vector, see 11.1 Star Subdivisions in [CLS11]. Below, we refer to this new primitive vector as new_ray. The main constructor is the following","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/BlowupMorphisms/","page":"Toric Blowups (Experimental)","title":"Toric Blowups (Experimental)","text":"blow_up(Y::NormalToricVariety, new_ray::AbstractVector{<:IntegerUnion}; coordinate_name::String)","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/BlowupMorphisms/","page":"Toric Blowups (Experimental)","title":"Toric Blowups (Experimental)","text":"This will also construct the underlying toric morphism. We can specify the name for the coordinate in the Cox ring that is assigned to new_ray using the optional argument coordinate_name.","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/BlowupMorphisms/","page":"Toric Blowups (Experimental)","title":"Toric Blowups (Experimental)","text":"More generally, we can construct a blowup along a closed subscheme given by an ideal in the Cox ring or by an ideal sheaf of the corresponding covered scheme. In general, this will result in a non-toric variety.","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/BlowupMorphisms/#Constructors","page":"Toric Blowups (Experimental)","title":"Constructors","text":"","category":"section"},{"location":"AlgebraicGeometry/ToricVarieties/BlowupMorphisms/","page":"Toric Blowups (Experimental)","title":"Toric Blowups (Experimental)","text":"The following methods blow up toric varieties. The closed subscheme along which the blowup is constructed can be provided in different formats. We discuss the methods in ascending generality.","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/BlowupMorphisms/","page":"Toric Blowups (Experimental)","title":"Toric Blowups (Experimental)","text":"For our most specialized blowup method, we focus on the n-th cone in the fan of the variety v in question. This cone need not be maximal. The ensuing star subdivision will subdivide this cone about its \"diagonal\" (the sum of all its rays). The result of this will always be a toric variety:","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/BlowupMorphisms/","page":"Toric Blowups (Experimental)","title":"Toric Blowups (Experimental)","text":"blow_up(v::NormalToricVariety, n::Int; coordinate_name::String = \"e\")","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/BlowupMorphisms/#blow_up-Tuple{NormalToricVariety, Int64}","page":"Toric Blowups (Experimental)","title":"blow_up","text":"blow_up(v::NormalToricVariety, n::Int; coordinate_name::String = \"e\")\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 morphism.\n\nBy default, we pick \"e\" as the name of the homogeneous coordinate for the exceptional prime divisor. As third optional argument one can supply a custom variable name.\n\nExamples\n\njulia> P3 = projective_space(NormalToricVariety, 3)\nNormal toric variety\n\njulia> f = blow_up(P3, 5)\nToric blowup morphism\n\njulia> bP3 = domain(f)\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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/BlowupMorphisms/","page":"Toric Blowups (Experimental)","title":"Toric Blowups (Experimental)","text":"More generally, we can provide a primitive element in the fan of the variety in question and construct a toric morphism as in Section 11.1 Star Subdivisions in [CLS11]. The resulting star subdivision leads to a polyhedral fan, or put differently, the blowup is always toric:","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/BlowupMorphisms/","page":"Toric Blowups (Experimental)","title":"Toric Blowups (Experimental)","text":"blow_up(v::NormalToricVariety, new_ray::AbstractVector{<:IntegerUnion}; coordinate_name::String = \"e\")","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/BlowupMorphisms/#blow_up-Tuple{NormalToricVariety, AbstractVector{<:Union{Integer, ZZRingElem}}}","page":"Toric Blowups (Experimental)","title":"blow_up","text":"blow_up(v::NormalToricVariety, new_ray::AbstractVector{<:IntegerUnion}; coordinate_name::String)\n\nBlow up the toric variety by subdividing the fan of the variety with the provided new ray. This function returns the corresponding morphism.\n\nNote that this ray must be a primitive element in the lattice Z^d, with d the dimension of the fan. In particular, it is currently impossible to blow up along a ray which corresponds to a non-Q-Cartier divisor.\n\nBy default, we pick \"e\" as the name of the homogeneous coordinate for the exceptional prime divisor. As optional argument one can supply a custom variable name.\n\nwarning: Warning\nThis function is type unstable. The type of the field center_unnormalized is always a subtype of AbsIdealSheaf (meaning that center_unnormalized(f) isa Oscar.AbsIdealSheaf is always true). Sometimes, the function computes and sets the field center_unnormalized for the output f, giving it the type ToricIdealSheafFromCoxRingIdeal (meaning that center_unnormalized(f) isa Oscar.ToricIdealSheafFromCoxRingIdeal is true and center_unnormalized(f) isa IdealSheaf is false). If it does not, then calling center_unnormalized(f) computes and sets the field center_unnormalized and it will have the type IdealSheaf (meaning that center_unnormalized(f) isa Oscar.ToricIdealSheafFromCoxRingIdeal is false and center_unnormalized(f) isa IdealSheaf is true).\n\nExamples\n\nIn the example below center_unnormalized(f) has type ToricIdealSheafFromCoxRingIdeal and we can access the corresponding ideal in the Cox ring using Oscar.ideal_in_cox_ring.\n\njulia> P3 = projective_space(NormalToricVariety, 3)\nNormal toric variety\n\njulia> f = blow_up(P3, [0, 2, 3])\nToric blowup morphism\n\njulia> bP3 = domain(f)\nNormal toric variety\n\njulia> cox_ring(bP3)\nMultivariate polynomial ring in 5 variables over QQ graded by\n x1 -> [1 0]\n x2 -> [1 2]\n x3 -> [1 3]\n x4 -> [1 0]\n e -> [0 -1]\n\njulia> typeof(center_unnormalized(f))\nOscar.ToricIdealSheafFromCoxRingIdeal{NormalToricVariety, AbsAffineScheme, Ideal, Map}\n\njulia> Oscar.ideal_in_cox_ring(center_unnormalized(f))\nIdeal generated by\n x2^2\n x3^3\n\nIn the below example, center_unnormalized(f) has type IdealSheaf and we cannot access the corresponding ideal in the Cox ring.\n\nExamples\n\njulia> rs = [1 1; -1 1]\n2×2 Matrix{Int64}:\n 1 1\n -1 1\n\njulia> max_cones = incidence_matrix([[1, 2]])\n1×2 IncidenceMatrix\n[1, 2]\n\njulia> v = normal_toric_variety(max_cones, rs)\nNormal toric variety\n\njulia> f = blow_up(v, [0, 1])\nToric blowup morphism\n\njulia> center_unnormalized(f)\nSheaf of ideals\n on normal, non-smooth toric variety\nwith restriction\n 1: Ideal (x_3_1, x_2_1, x_1_1)\n\njulia> typeof(center_unnormalized(f))\nIdealSheaf{NormalToricVariety, AbsAffineScheme, Ideal, Map}\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/BlowupMorphisms/","page":"Toric Blowups (Experimental)","title":"Toric Blowups (Experimental)","text":"Most generally, we encode the closed subscheme along which we blow up by a homogeneous ideal in the Cox ring. Such blowups are often non-toric, i.e. the return value of the following method could well be non-toric.","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/BlowupMorphisms/","page":"Toric Blowups (Experimental)","title":"Toric Blowups (Experimental)","text":"blow_up(v::NormalToricVariety, I::MPolyIdeal; coordinate_name::String = \"e\")","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/BlowupMorphisms/#blow_up-Tuple{NormalToricVariety, MPolyIdeal}","page":"Toric Blowups (Experimental)","title":"blow_up","text":"blow_up(v::NormalToricVariety, I::MPolyIdeal; coordinate_name::String = \"e\")\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 prime divisor. As third optional argument one can supply a custom variable name.\n\nExamples\n\njulia> P3 = projective_space(NormalToricVariety, 3)\nNormal toric variety\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 generated by\n x2\n 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\njulia> I2 = ideal([x2 * x3])\nIdeal generated by\n x2*x3\n\njulia> b2P3 = blow_up(P3, I2);\n\njulia> codomain(b2P3) === P3\ntrue\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/BlowupMorphisms/","page":"Toric Blowups (Experimental)","title":"Toric Blowups (Experimental)","text":"Instead of providing the ideal, it is possible to turn a homogeneous ideal in the Cox ring into an ideal sheaf. Consequently, we also provide the support for the following method.","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/BlowupMorphisms/","page":"Toric Blowups (Experimental)","title":"Toric Blowups (Experimental)","text":"blow_up(m::NormalToricVariety, I::ToricIdealSheafFromCoxRingIdeal; coordinate_name::String = \"e\")","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/BlowupMorphisms/#blow_up-Tuple{NormalToricVariety, Oscar.ToricIdealSheafFromCoxRingIdeal}","page":"Toric Blowups (Experimental)","title":"blow_up","text":"blow_up(m::NormalToricVariety, I::ToricIdealSheafFromCoxRingIdeal; coordinate_name::String = \"e\")\n\nBlow up the toric variety along a toric ideal sheaf.\n\nwarning: Warning\nThis function is type unstable. The type of the domain of the output f is always a subtype of AbsCoveredScheme (meaning that domain(f) isa AbsCoveredScheme is always true). Sometimes, the type of the domain will be a toric variety (meaning that domain(f) isa NormalToricVariety is true) if the algorithm can successfully detect this. In the future, the detection algorithm may be improved so that this is successful more often.\n\nExamples\n\njulia> P3 = projective_space(NormalToricVariety, 3)\nNormal toric variety\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> II = ideal_sheaf(P3, ideal([x1*x2]))\nSheaf of ideals\n on normal toric variety\nwith restrictions\n 1: Ideal (x_1_1*x_2_1)\n 2: Ideal (x_2_2)\n 3: Ideal (x_1_3)\n 4: Ideal (x_1_4*x_2_4)\n\njulia> f = blow_up(P3, II)\nBlowup\n of normal toric variety\n in sheaf of ideals with restrictions\n 1b: Ideal (x_1_1*x_2_1)\n 2b: Ideal (x_2_2)\n 3b: Ideal (x_1_3)\n 4b: Ideal (x_1_4*x_2_4)\nwith domain\n scheme over QQ covered with 4 patches\n 1a: [x_1_1, x_2_1, x_3_1] scheme(0)\n 2a: [x_1_2, x_2_2, x_3_2] scheme(0)\n 3a: [x_1_3, x_2_3, x_3_3] scheme(0)\n 4a: [x_1_4, x_2_4, x_3_4] scheme(0)\nand exceptional divisor\n effective cartier divisor defined by\n sheaf of ideals with restrictions\n 1a: Ideal (x_1_1*x_2_1)\n 2a: Ideal (x_2_2)\n 3a: Ideal (x_1_3)\n 4a: Ideal (x_1_4*x_2_4)\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/BlowupMorphisms/#Attributes","page":"Toric Blowups (Experimental)","title":"Attributes","text":"","category":"section"},{"location":"AlgebraicGeometry/ToricVarieties/BlowupMorphisms/","page":"Toric Blowups (Experimental)","title":"Toric Blowups (Experimental)","text":"underlying_morphism(bl::ToricBlowupMorphism)\nindex_of_new_ray(bl::ToricBlowupMorphism)\ncenter_data(bl::ToricBlowupMorphism)\ncenter_unnormalized(bl::ToricBlowupMorphism)\nexceptional_prime_divisor(bl::ToricBlowupMorphism)","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/BlowupMorphisms/#underlying_morphism-Tuple{Oscar.ToricBlowupMorphism}","page":"Toric Blowups (Experimental)","title":"underlying_morphism","text":"underlying_morphism(bl::ToricBlowupMorphism)\n\nReturn the underlying toric morphism of a toric blowup. Access to other attributes such as domain, codomain, covering_morphism are executed via underlying_morphism.\n\nExamples\n\njulia> P3 = projective_space(NormalToricVariety, 3)\nNormal toric variety\n\njulia> f = blow_up(P3, [0, 1, 1])\nToric blowup morphism\n\njulia> Oscar.underlying_morphism(f)\nToric morphism\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/BlowupMorphisms/#index_of_new_ray-Tuple{Oscar.ToricBlowupMorphism}","page":"Toric Blowups (Experimental)","title":"index_of_new_ray","text":"index_of_new_ray(bl::ToricBlowupMorphism)\n\nReturn the index of the new ray used in the construction of the toric blowup.\n\nExamples\n\njulia> P3 = projective_space(NormalToricVariety, 3)\nNormal toric variety\n\njulia> f = blow_up(P3, [0, 1, 1])\nToric blowup morphism\n\njulia> index_of_new_ray(f)\n5\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/BlowupMorphisms/#center_data-Tuple{Oscar.ToricBlowupMorphism}","page":"Toric Blowups (Experimental)","title":"center_data","text":"center_data(bl::ToricBlowupMorphism)\n\nReturns the ideal, ideal sheaf or ray that was used to construct the morphism.\n\nExamples\n\njulia> P3 = projective_space(NormalToricVariety, 3)\nNormal toric variety\n\njulia> f = blow_up(P3, [0, 2, 3])\nToric blowup morphism\n\njulia> center_data(f)\n3-element Vector{Int64}:\n 0\n 2\n 3\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/BlowupMorphisms/#center_unnormalized-Tuple{Oscar.ToricBlowupMorphism}","page":"Toric Blowups (Experimental)","title":"center_unnormalized","text":"center_unnormalized(bl::ToricBlowupMorphism)\n\nReturns an ideal sheaf I such that the normalization of the blowup along I gives the morphism bl.\n\nExamples\n\njulia> P3 = projective_space(NormalToricVariety, 3)\nNormal toric variety\n\njulia> f = blow_up(P3, [0, 2, 3])\nToric blowup morphism\n\njulia> center_unnormalized(f)\nSheaf of ideals\n on normal, smooth toric variety\nwith restrictions\n 1: Ideal (x_2_1^2, x_3_1^3)\n 2: Ideal (x_2_2^2, x_3_2^3)\n 3: Ideal (1)\n 4: Ideal (1)\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/BlowupMorphisms/#exceptional_prime_divisor-Tuple{Oscar.ToricBlowupMorphism}","page":"Toric Blowups (Experimental)","title":"exceptional_prime_divisor","text":"exceptional_prime_divisor(bl::ToricBlowupMorphism)\n\nReturn the exceptional prime Weil divisor (as a toric divisor) of the ray used to construct the toric blowup. Note that this divisor need not be Cartier and this divisor need not coincide with the locus where the morphism is not an isomorphism.\n\nExamples\n\njulia> P3 = projective_space(NormalToricVariety, 3)\nNormal toric variety\n\njulia> f = blow_up(P3, [0, 2, 3])\nToric blowup morphism\n\njulia> E = exceptional_prime_divisor(f)\nTorus-invariant, prime divisor on a normal toric variety\n\njulia> is_cartier(E)\nfalse\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/BlowupMorphisms/","page":"Toric Blowups (Experimental)","title":"Toric Blowups (Experimental)","text":"Based on underlying_morphism, also the following attributes of toric morphisms are supported for toric blowups:","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/BlowupMorphisms/","page":"Toric Blowups (Experimental)","title":"Toric Blowups (Experimental)","text":"grid_morphism(bl::ToricBlowupMorphism),\nmorphism_on_torusinvariant_weil_divisor_group(bl::ToricBlowupMorphism),\nmorphism_on_torusinvariant_cartier_divisor_group(bl::ToricBlowupMorphism),\nmorphism_on_class_group(bl::ToricBlowupMorphism),\nmorphism_on_picard_group(bl::ToricBlowupMorphism).","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/BlowupMorphisms/","page":"Toric Blowups (Experimental)","title":"Toric Blowups (Experimental)","text":"The total and strict transform of ideal sheaves along blowups, not necessarily toric, can be computed:","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/BlowupMorphisms/","page":"Toric Blowups (Experimental)","title":"Toric Blowups (Experimental)","text":"total_transform(f::AbsSimpleBlowupMorphism, II::AbsIdealSheaf)","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/BlowupMorphisms/#total_transform-Tuple{Oscar.AbsSimpleBlowupMorphism, Oscar.AbsIdealSheaf}","page":"Toric Blowups (Experimental)","title":"total_transform","text":"total_transform(f::AbsSimpleBlowupMorphism, II::IdealSheaf)\n\nComputes the total transform of an ideal sheaf along a blowup.\n\nIn particular, this applies in the toric setting. However, note that currently (October 2023), ideal sheaves are only supported on smooth toric varieties.\n\nExamples\n\njulia> P2 = projective_space(NormalToricVariety, 2)\nNormal toric variety\n\njulia> bl = blow_up(P2, [1, 1])\nToric blowup morphism\n\njulia> S = cox_ring(P2);\n\njulia> x, y, z = gens(S);\n\njulia> I = ideal_sheaf(P2, ideal([x*y]))\nSheaf of ideals\n on normal, smooth toric variety\nwith restrictions\n 1: Ideal (x_1_1*x_2_1)\n 2: Ideal (x_2_2)\n 3: Ideal (x_1_3)\n\njulia> total_transform(bl, I)\nSheaf of ideals\n on normal toric variety\nwith restrictions\n 1: Ideal (x_1_1*x_2_1^2)\n 2: Ideal (x_1_2^2*x_2_2)\n 3: Ideal (x_2_3)\n 4: Ideal (x_1_4)\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/BlowupMorphisms/#Arithmetics","page":"Toric Blowups (Experimental)","title":"Arithmetics","text":"","category":"section"},{"location":"AlgebraicGeometry/ToricVarieties/BlowupMorphisms/","page":"Toric Blowups (Experimental)","title":"Toric Blowups (Experimental)","text":"Toric blowups can be added, subtracted and multiplied by rational numbers. The results of such operations will not be toric morphisms, i.e. they no longer correspond to the blowup of a certain closed subscheme. Arithmetics among toric blowups and general toric morphisms is also supported, as well as equality for toric blowups.","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 = free_module(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 = vector_space(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 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)\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 = free_module(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 = vector_space(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 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)\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":"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":"Saving and loading files","title":"Saving and loading files","text":"","category":"section"},{"location":"General/serialization/#Introduction","page":"Saving and loading files","title":"Introduction","text":"","category":"section"},{"location":"General/serialization/","page":"Saving and loading files","title":"Saving and loading files","text":"For some of our datatypes we provide a way to save them in and load them from JSON format. The most common OSCAR types are supported, but it will take some time until all corners of OSCAR are covered by this effort. Our overall goal is threefold:","category":"page"},{"location":"General/serialization/","page":"Saving and loading files","title":"Saving and loading files","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 of OSCAR (or other computer algebra systems).","category":"page"},{"location":"General/serialization/","page":"Saving and loading files","title":"Saving and loading files","text":"For more details read the developer documentation. Work on serialization is supported by the MaRDI project. You can find out more about its Task Area 1 (Computer Algebra) here.","category":"page"},{"location":"General/serialization/","page":"Saving and loading files","title":"Saving and loading files","text":"save\nload","category":"page"},{"location":"General/serialization/#save","page":"Saving and loading files","title":"save","text":"save(io::IO, obj::Any; metadata::MetaData=nothing, with_attrs::Bool=true)\nsave(filename::String, obj::Any, metadata::MetaData=nothing, with_attrs::Bool=true)\n\nSave an object obj to the given io stream respectively to the file filename. When used with with_attrs=true then the object will save it's attributes along with all the attributes of the types used in the object's struct. The attributes that will be saved are defined during type registration see @register_serialization_type\n\nSee load.\n\nExamples\n\njulia> meta = metadata(author_orcid=\"0000-0000-0000-0042\", name=\"42\", description=\"The meaning of life, the universe and everything\")\nOscar.MetaData(\"0000-0000-0000-0042\", \"42\", \"The meaning of life, the universe and everything\")\n\njulia> save(\"/tmp/fourtitwo.mrdi\", 42; metadata=meta);\n\njulia> read_metadata(\"/tmp/fourtitwo.mrdi\")\n{\n \"author_orcid\": \"0000-0000-0000-0042\",\n \"name\": \"42\",\n \"description\": \"The meaning of life, the universe and everything\"\n}\n\njulia> load(\"/tmp/fourtitwo.mrdi\")\n42\n\n\n\n\n\n","category":"function"},{"location":"General/serialization/#load","page":"Saving and loading files","title":"load","text":"load(io::IO; params::Any = nothing, type::Any = nothing, with_attrs::Bool=true)\nload(filename::String; params::Any = nothing, type::Any = nothing, with_attrs::Bool=true)\n\nLoad the object stored in the given io stream respectively in the file filename.\n\nIf params is specified, then the root object of the loaded data either will attempt a load using these parameters. In the case of Rings this results in setting its parent, or in the case of a container of ring types such as Vector or Tuple, then the parent of the entries will be set using their params.\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\nIf with_attrs=true the object will be loaded with attributes available from the file (or serialized data).\n\nSee save.\n\nExamples\n\njulia> save(\"/tmp/fourtitwo.mrdi\", 42);\n\njulia> load(\"/tmp/fourtitwo.mrdi\")\n42\n\njulia> load(\"/tmp/fourtitwo.mrdi\"; 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.mrdi\", p)\n\njulia> p_loaded = load(\"/tmp/p.mrdi\", params=R)\nx^2 - x + 1\n\njulia> parent(p_loaded) === R\ntrue\n\njulia> save(\"/tmp/p_v.mrdi\", [p, p])\n\njulia> loaded_p_v = load(\"/tmp/p_v.mrdi\", params=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/#Objects-that-can-be-serialized","page":"Saving and loading files","title":"Objects that can be serialized","text":"","category":"section"},{"location":"General/serialization/","page":"Saving and loading files","title":"Saving and loading files","text":"In this section we will list a selection of objects that may be (de-)serialized. ","category":"page"},{"location":"General/serialization/","page":"Saving and loading files","title":"Saving and loading files","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":"Saving and loading files","title":"Combinatorics","text":"","category":"section"},{"location":"General/serialization/","page":"Saving and loading files","title":"Saving and loading files","text":"Graph\nSimplicialComplex","category":"page"},{"location":"General/serialization/#Commutative-Algebra","page":"Saving and loading files","title":"Commutative Algebra","text":"","category":"section"},{"location":"General/serialization/","page":"Saving and loading files","title":"Saving and loading files","text":"Ideal\nPolyRing\nPolyRingElem\nMPolyRing\nMPolyRingElem","category":"page"},{"location":"General/serialization/#Groups","page":"Saving and loading files","title":"Groups","text":"","category":"section"},{"location":"General/serialization/","page":"Saving and loading files","title":"Saving and loading files","text":"FPGroup\nFinGenAbGroup\nPcGroup\nPermGroup\nSubFPGroup\nSubPcGroup","category":"page"},{"location":"General/serialization/#Polyhedral-Geometry","page":"Saving and loading files","title":"Polyhedral Geometry","text":"","category":"section"},{"location":"General/serialization/","page":"Saving and loading files","title":"Saving and loading files","text":"Cone\nLinearProgram\nPolyhedralFan\nPolyhedralComplex\nPolyhedron\nSubdivisionOfPoints","category":"page"},{"location":"General/serialization/#Toric-Geometry","page":"Saving and loading files","title":"Toric Geometry","text":"","category":"section"},{"location":"General/serialization/","page":"Saving and loading files","title":"Saving and loading files","text":"NormalToricVariety\nToricDivisor","category":"page"},{"location":"General/serialization/#Tropical-Geometry","page":"Saving and loading files","title":"Tropical Geometry","text":"","category":"section"},{"location":"General/serialization/","page":"Saving and loading files","title":"Saving and loading files","text":"TropicalCurve\nTropicalHypersurface","category":"page"},{"location":"General/serialization/#Listing-all-serializable-types-of-the-current-session","page":"Saving and loading files","title":"Listing all serializable types of the current session","text":"","category":"section"},{"location":"General/serialization/","page":"Saving and loading files","title":"Saving and loading files","text":"If you are curious about whether your type can already be serialized given your version of Oscar you can run the following command in your active session.","category":"page"},{"location":"General/serialization/","page":"Saving and loading files","title":"Saving and loading files","text":"using Oscar","category":"page"},{"location":"General/serialization/","page":"Saving and loading files","title":"Saving and loading files","text":"Oscar.reverse_type_map","category":"page"},{"location":"CommutativeAlgebra/ideals/","page":"Ideals in Multivariate Rings","title":"Ideals in Multivariate Rings","text":"CurrentModule = Oscar\nDocTestSetup = Oscar.doctestsetup()","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 generated by\n x*y - 3*x\n -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 generated by\n 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,\nnumber_of_generators(I) / ngens(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 generated by\n x^2\n x*y\n 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> number_of_generators(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 generated by\n -x^2 + y\n 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(TropV::TropicalVariety)\n\nSee codim(::PolyhedralComplex).\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 generated by\n x\n z^2\n x^3 + y^3\n y^4\n 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 generated by\n 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 with coefficients in a field, 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 [MS21].\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 generated by\n -x^2 + y\n 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 generated by\n x\n y\n\njulia> I^3\nIdeal generated by\n x^3\n x^2*y\n x*y^2\n 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 generated by\n x\n y\n\njulia> J = ideal(R, [z^2])\nIdeal generated by\n z^2\n\njulia> I+J\nIdeal generated by\n x\n y\n 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 generated by\n x\n y\n\njulia> J = ideal(R, [z^2])\nIdeal generated by\n z^2\n\njulia> I*J\nIdeal generated by\n x*z^2\n 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","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 generated by\n x^3*y - x*y - y^3\n x^4 - x^2 - x*y^2\n\njulia> intersect([I, J])\nIdeal generated by\n x^3*y - x*y - y^3\n x^4 - x^2 - x*y^2\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 generated by\n x^4 + x^2*y*z + y^3*z\n x^3*z + x*y^2*z + y^4\n x^3*y + x*y^3\n\njulia> J = ideal(R, [x, y, z])^2\nIdeal generated by\n x^2\n x*y\n x*z\n y^2\n y*z\n z^2\n\njulia> L = quotient(I, J)\nIdeal generated by\n x^3*z + x*y^2*z + y^4\n x^3*y + x*y^3\n x^4 + x^2*y*z + y^3*z\n x^3*z^2 - x^2*y*z^2 + x*y^2*z^2 - y^3*z^2\n x^2*y^2*z - x^2*y*z^2 - y^3*z^2\n x^3*z^2 + x^2*y^3 - x^2*y^2*z + x*y^2*z^2\n\njulia> I:J\nIdeal generated by\n x^3*z + x*y^2*z + y^4\n x^3*y + x*y^3\n x^4 + x^2*y*z + y^3*z\n x^3*z^2 - x^2*y*z^2 + x*y^2*z^2 - y^3*z^2\n x^2*y^2*z - x^2*y*z^2 - y^3*z^2\n x^3*z^2 + x^2*y^3 - x^2*y^2*z + x*y^2*z^2\n\njulia> I:x\nIdeal generated by\n x^2*y + y^3\n x^3*z + x*y^2*z + y^4\n x^2*z^2 + x*y^3 - x*y^2*z + y^2*z^2\n x^4\n x^3*z^2 - x^2*z^3 + 2*x*y^2*z^2 - y^2*z^3\n -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}; iteration::Bool=false) 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}, \n J::MPolyIdeal{T} = ideal(base_ring(I), gens(base_ring(I))); \n iteration::Bool=false) where T\n\nReturn the saturation of I with respect to J.\n\nIf the second ideal J is not given, the ideal generated by the generators (variables) of base_ring(I) is used.\n\nIf iteration is set to true, the saturation is done by carrying out successive ideal quotient computations as in the definition of saturation. Otherwise, a more sophisticated Gröbner basis approach is used which is typically faster. Applying the two approaches may lead to different generating sets of the saturation.\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 generated by\n z^3\n y*z^2\n x*z^2\n y^2*z\n x*y*z\n x^2*z\n x*y^2\n x^2*y\n\njulia> J = ideal(R, [x, y, z])\nIdeal generated by\n x\n y\n z\n\njulia> K = saturation(I, J)\nIdeal generated by\n z\n x*y\n\njulia> K = saturation(I)\nIdeal generated by\n z\n x*y\n\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}, \n J::MPolyIdeal{T} = ideal(base_ring(I), gens(base_ring(I)))) where T\n\nReturn IJ^infty together with the smallest integer m such that IJ^m = IJ^infty (saturation index).\n\nIf the second ideal J is not given, the ideal generated by the generators (variables) of base_ring(I) is used.\n\nnote: Note\nIf the saturation index is not needed, we recommend to use saturation(I, J) which is typically faster.\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 generated by\n z^3\n y*z^2\n x*z^2\n y^2*z\n x*y*z\n x^2*z\n x*y^2\n x^2*y\n\njulia> J = ideal(R, [x, y, z])\nIdeal generated by\n x\n y\n z\n\njulia> K, m = saturation_with_index(I, J)\n(Ideal (z, x*y), 2)\n\njulia> K, m = saturation_with_index(I)\n(Ideal (z, x*y), 2)\n\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 generated by\n t - x\n t^2 - y\n t^3 - z\n\njulia> A = [t]\n1-element Vector{QQMPolyRingElem}:\n t\n\njulia> TC = eliminate(I, A)\nIdeal generated by\n -x*z + y^2\n x*y - z\n x^2 - y\n\njulia> A = [1]\n1-element Vector{Int64}:\n 1\n\njulia> TC = eliminate(I, A)\nIdeal generated by\n -x*z + y^2\n x*y - z\n 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::FinGenAbGroupElem)","category":"page"},{"location":"CommutativeAlgebra/ideals/#truncate-Tuple{MPolyIdeal, FinGenAbGroupElem}","page":"Ideals in Multivariate Rings","title":"truncate","text":"truncate(I::MPolyIdeal, g::FinGenAbGroupElem)\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 generated by\n x\n y^4\n z^6\n\njulia> truncate(I, 3)\nIdeal generated by\n x*z^2\n x*y*z\n x*y^2\n x^2*z\n x^2*y\n x^3\n y^4\n 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 generated by\n x\n y^4\n z^6\n\njulia> truncate(I, 3)\nIdeal generated by\n x\n y^4\n z^6\n\njulia> truncate(I, 4)\nIdeal generated by\n x*z\n z^6\n 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 generated by\n -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 generated by\n x\n x + y\n 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, J::MPolyIdeal)","category":"page"},{"location":"CommutativeAlgebra/ideals/#is_subset-Tuple{MPolyIdeal, MPolyIdeal}","page":"Ideals in Multivariate Rings","title":"is_subset","text":"is_subset(I::MPolyIdeal, J::MPolyIdeal)\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 generated by\n x^2\n\njulia> J = ideal(R, [x, y])^2\nIdeal generated by\n x^2\n x*y\n 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, J::MPolyIdeal)","category":"page"},{"location":"CommutativeAlgebra/ideals/#==-Tuple{MPolyIdeal, MPolyIdeal}","page":"Ideals in Multivariate Rings","title":"==","text":"==(I::MPolyIdeal, J::MPolyIdeal)\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 generated by\n x^2\n\njulia> J = ideal(R, [x, y])^2\nIdeal generated by\n x^2\n x*y\n 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 generated by\n x^2\n x*y\n 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 generated by\n 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 generated by\n x^2\n x*y\n 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 generated by\n x^2\n x*y\n 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 [DGP99] 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(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","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 [GTZ88], [SY96], and [PSS11].\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\nwarning: Warning\nIf computations are done in a ring over a number field, then the output may contain redundant components.\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 generated by\n x^3*y - x*y - y^3\n x^4 - x^2 - x*y^2\n\njulia> I = intersect(I, ideal(R, [x-y-1])^2)\nIdeal generated by\n 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\n 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 generated by\n 1326*a^2*d^5\n 1989*a^2*c^5\n 102*b^4*d^5\n 153*b^4*c^5\n 663*a^2*c^5*d^5\n 51*b^4*c^5*d^5\n 78*a^2*d^15\n 117*a^2*c^15\n 78*a^15*d^5\n 117*a^15*c^5\n 6*a^2*b^4*d^15\n 9*a^2*b^4*c^15\n 39*a^2*c^5*d^15\n 39*a^2*c^15*d^5\n 6*a^2*b^15*d^5\n 9*a^2*b^15*c^5\n 6*a^15*b^4*d^5\n 9*a^15*b^4*c^5\n 39*a^15*c^5*d^5\n 3*a^2*b^4*c^5*d^15\n 3*a^2*b^4*c^15*d^5\n 3*a^2*b^15*c^5*d^5\n 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\nwarning: Warning\nOver number fields this proceduce might return redundant output.\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 generated by\n z^8 + z^6 + 4*z^5 + 4*z^3 + 4*z^2 + 4\n 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{AbsSimpleNumFieldElem}}, 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^2), 3)\n\njulia> AP = AL[1][3]\nIdeal generated by\n z - _a\n 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 generated by\n 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{AbsSimpleNumFieldElem, AbstractAlgebra.Generic.MPoly{AbsSimpleNumFieldElem}}}, Int64}}:\n (Ideal (x^2 + y^2), Ideal (x^2 + y^2), Ideal (x + _a*y), 2)\n\njulia> AP = AL[1][3]\nIdeal generated by\n 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 [GTZ88] and [PSS11].\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 generated by\n x^3*y - x*y - y^3\n x^4 - x^2 - x*y^2\n\njulia> I = intersect(I, ideal(R, [x-y-1])^2)\nIdeal generated by\n 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\n 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 generated by\n 1326*a^2*d^5\n 1989*a^2*c^5\n 102*b^4*d^5\n 153*b^4*c^5\n 663*a^2*c^5*d^5\n 51*b^4*c^5*d^5\n 78*a^2*d^15\n 117*a^2*c^15\n 78*a^15*d^5\n 117*a^15*c^5\n 6*a^2*b^4*d^15\n 9*a^2*b^4*c^15\n 39*a^2*c^5*d^15\n 39*a^2*c^15*d^5\n 6*a^2*b^15*d^5\n 9*a^2*b^15*c^5\n 6*a^15*b^4*d^5\n 9*a^15*b^4*c^5\n 39*a^15*c^5*d^5\n 3*a^2*b^4*c^5*d^15\n 3*a^2*b^4*c^15*d^5\n 3*a^2*b^15*c^5*d^5\n 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 [EHV92].\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 generated by\n x^3*y - x*y - y^3\n x^4 - x^2 - x*y^2\n\njulia> I = intersect(I, ideal(R, [x-y-1])^2)\nIdeal generated by\n 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\n 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 with 1 generator\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 [KL91] and [Kem02].\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 generated by\n x^3*y - x*y - y^3\n x^4 - x^2 - x*y^2\n\njulia> I = intersect(I, ideal(R, [x-y-1])^2)\nIdeal generated by\n 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\n 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 [GTZ88], [KL91], and [PSS11].\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 generated by\n x^3*y - x*y - y^3\n x^4 - x^2 - x*y^2\n\njulia> I = intersect(I, ideal(R, [x-y-1])^2)\nIdeal generated by\n 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\n 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 generated by\n 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 generated by\n 1326*a^2*d^5\n 1989*a^2*c^5\n 102*b^4*d^5\n 153*b^4*c^5\n 663*a^2*c^5*d^5\n 51*b^4*c^5*d^5\n 78*a^2*d^15\n 117*a^2*c^15\n 78*a^15*d^5\n 117*a^15*c^5\n 6*a^2*b^4*d^15\n 9*a^2*b^4*c^15\n 39*a^2*c^5*d^15\n 39*a^2*c^15*d^5\n 6*a^2*b^15*d^5\n 9*a^2*b^15*c^5\n 6*a^15*b^4*d^5\n 9*a^15*b^4*c^5\n 39*a^15*c^5*d^5\n 3*a^2*b^4*c^5*d^15\n 3*a^2*b^4*c^15*d^5\n 3*a^2*b^15*c^5*d^5\n 3*a^15*b^4*c^5*d^5\n\njulia> L = equidimensional_hull(I)\nIdeal generated by\n 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 [KL91] and [Kem02].\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 generated by\n x^3*y - x*y - y^3\n x^4 - x^2 - x*y^2\n\njulia> I = intersect(I, ideal(R, [x-y-1])^2)\nIdeal generated by\n 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\n 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 generated by\n 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 [KR05] 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":"homogenizer(P::MPolyRing{T}, h::VarName; pos::Int=1+ngens(P)) where T\nhomogenizer(P::MPolyRing{T}, W::Union{ZZMatrix, Matrix{<:IntegerUnion}}, h::VarName; pos::Int) where T\ndehomogenizer(H::Homogenizer)","category":"page"},{"location":"CommutativeAlgebra/ideals/#homogenizer-Union{Tuple{T}, Tuple{MPolyRing{T}, Union{Char, AbstractString, Symbol}}} where T","page":"Ideals in Multivariate Rings","title":"homogenizer","text":"homogenizer(P::MPolyRing, h::VarName; pos::Int=1+ngens(P))\n\nCreate a \"homogenizing operator\" assuming a standard grading; h is the name of the homogenizing variable; pos indicates where to put the homogenizing variable in the list of generators of the graded polynomial ring (default is after all the other variables).\n\nExamples\n\njulia> P, (x,y) = polynomial_ring(QQ, [:x, :y]);\n\njulia> H = homogenizer(P, \"h\");\n\njulia> H(x^2+y)\nx^2 + y*h\n\njulia> V = H.([x^2+y, x+y^2]);\n\njulia> parent(V[1]) == parent(V[2])\ntrue\n\njulia> H(ideal([x^2+y]))\nIdeal generated by\n x^2 + y*h\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/ideals/#homogenizer-Union{Tuple{T}, Tuple{MPolyRing{T}, Union{ZZMatrix, Matrix{<:Union{Integer, ZZRingElem}}}, Union{Char, AbstractString, Symbol}}} where T","page":"Ideals in Multivariate Rings","title":"homogenizer","text":"homogenizer(P::MPolyRing, W::Union{ZZMatrix, Matrix{<:IntegerUnion}}, h::VarName; pos::Int=1+ngens(P))\n\nCreate a \"homogenizing operator\" using the grading specified by the columns of W; h is the prefix for the homogenizing variables; pos indicates where to put the homogenizing variables in the list of generators of the graded polynomial ring (default is after all the other variables).\n\nExamples\n\njulia> P, (x,y) = polynomial_ring(QQ, [:x, :y]);\n\njulia> W = ZZMatrix(2,2, [2,3,5,7]);\n\njulia> H = homogenizer(P, W, \"h\");\n\njulia> H(x^2+y)\nx^2 + y*h[1]*h[2]^3\n\njulia> V = H.([x^2+y, x+y^2]);\n\njulia> parent(V[1]) == parent(V[2])\ntrue\n\njulia> H(ideal([x^2+y]))\nIdeal generated by\n x^2 + y*h[1]*h[2]^3\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/ideals/#dehomogenizer-Tuple{Oscar.Homogenizer}","page":"Ideals in Multivariate Rings","title":"dehomogenizer","text":"dehomogenizer(H::Homogenizer)\n\nCreate a \"dehomogenizing operator\" from a Homogenizer; it is effectively a polynomial ring homomorphism mapping all homogenizing variables to 1. A Dehomogenizer is a post-inverse for the Homogenizer it was created from.\n\nExamples\n\njulia> P, (x,y) = polynomial_ring(QQ, [:x, :y]);\n\njulia> H = homogenizer(P, \"h\");\n\njulia> DH = dehomogenizer(H);\n\njulia> F = H(x^2+y)\nx^2 + y*h\n\njulia> DH(F)\nx^2 + y\n\njulia> V = [x^2+y, x*y+y^2]; HV = H.(V);\n\njulia> parent(DH(HV[1])) == P && parent(DH(HV[2])) == P\ntrue\n\njulia> DH(H(ideal(V)))\nIdeal generated by\n x*y + y^2\n x^2 + y\n y^3 + y^2\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/ideals/","page":"Ideals in Multivariate Rings","title":"Ideals in Multivariate Rings","text":"julia> P, (x, y) = polynomial_ring(QQ, [:x, :y]);\n\njulia> I = ideal([x^2+y, x*y+y^2]);\n\njulia> H = homogenizer(P, \"h\");\n\njulia> Ih = H(I) # homogenization of ideal I\nIdeal generated by\n x*y + y^2\n x^2 + y*h\n y^3 + y^2*h\n\njulia> DH = dehomogenizer(H);\n\njulia> DH(Ih) == I # dehomogenization of Ih\ntrue","category":"page"},{"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 generated by\n x1 + 2*x2 + 2*x3 - 1\n x1^2 - x1 + 2*x2^2 + 2*x3^2\n 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 generated by\n x + 2*y + 2*z - 1\n x^2 - x + 2*y^2 + 2*z^2\n 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/MatRing.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 rings of mtimes m matrices are implemented in src/generic/MatRing.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.MatRingElem{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 MatSpace{T}. Parents of matrices in a matrix algebra have type Generic.MatRing{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 all matrix space parents are of the concrete type MatSpace{T}. On the other hand, the generic matrix algebra matrix types belong to the abstract type MatRingElem{T} and the parent types belong to the abstract MatRing{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::MatRing{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 = matrix_ring(QQ, 2)\nMatrix ring 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 = matrix_ring(ZZ, 2)\nMatrix ring 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\nblock_diagonal_matrix(xs::Vector{SMat})\n\nReturn the block diagonal matrix with the matrices in xs on the diagonal. Requires all blocks to have the same base ring.\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,-iteration-and-broacasting","page":"Matrix functionality","title":"Conversion to Julia matrices, iteration and broacasting","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<:NCRingElement}\nMatrix{U}(A::MatrixElem{T}) where {U<:NCRingElement, T<:NCRingElement}\n\nConvert A to a Julia Matrix{U} of the same dimensions with the same elements. If U is omitted then eltype(M) is used in its place.\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\njulia> Matrix{Int}(A)\n2×3 Matrix{Int64}:\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 <: NCRingElement\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/","page":"Matrix functionality","title":"Matrix functionality","text":"Matrices also support broadcasting, which amounts to elementwise application of functions to matrices:","category":"page"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"julia> k = GF(5);\n\njulia> A = ZZ[1 2; 3 4];\n\njulia> k.(A)\n[1 2]\n[3 4]\n\njulia> 3 .* A .+ 2\n[ 5 8]\n[11 14]\n\njulia> B = ZZ[3 4; 5 6];\n\njulia> ((x, y) -> x^2 + y^2).(A, B)\n[10 20]\n[34 52]","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":"number_of_rows(::MatSpace)\nnumber_of_columns(::MatSpace)","category":"page"},{"location":"AbstractAlgebra/matrix/#number_of_rows-Tuple{MatSpace}","page":"Matrix functionality","title":"number_of_rows","text":"number_of_rows(a::MatSpace)\n\nReturn the number of rows of the given matrix space.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/matrix/#number_of_columns-Tuple{MatSpace}","page":"Matrix functionality","title":"number_of_columns","text":"number_of_columns(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":"number_of_rows(::MatrixElem{T}) where T <: RingElement\nnumber_of_columns(::MatrixElem{T}) where T <: RingElement","category":"page"},{"location":"AbstractAlgebra/matrix/#number_of_rows-Union{Tuple{MatrixElem{T}}, Tuple{T}} where T<:RingElement","page":"Matrix functionality","title":"number_of_rows","text":"number_of_rows(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/#number_of_columns-Union{Tuple{MatrixElem{T}}, Tuple{T}} where T<:RingElement","page":"Matrix functionality","title":"number_of_columns","text":"number_of_columns(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":"ones_matrix(::Ring, ::Int, ::Int)","category":"page"},{"location":"AbstractAlgebra/matrix/#ones_matrix-Tuple{Ring, Int64, Int64}","page":"Matrix functionality","title":"ones_matrix","text":"ones_matrix(R::Ring, r::Int, c::Int)\n\nReturn the r times c ones matrix over R.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"scalar_matrix(R::Ring, n::Int, a::RingElement)","category":"page"},{"location":"AbstractAlgebra/matrix/#scalar_matrix-Tuple{Ring, Int64, RingElement}","page":"Matrix functionality","title":"scalar_matrix","text":"scalar_matrix(R::NCRing, n::Int, a::NCRingElement)\nscalar_matrix(n::Int, a::NCRingElement)\n\nReturn the n times n matrix over R with a along the main diagonal and zeroes elsewhere. If R is not specified, it defaults to parent(a).\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::NCRingElement, 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 <: NCRingElement}\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 <: NCRingElement}\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 <: NCRingElement}\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 <: NCRingElement}\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_lower_triangular(::MatrixElem)","category":"page"},{"location":"AbstractAlgebra/matrix/#is_lower_triangular-Tuple{MatrixElem}","page":"Matrix functionality","title":"is_lower_triangular","text":"is_lower_triangular(A::MatrixElem)\n\nReturn true if A is an lower triangular matrix, that is, all entries above the main diagonal are zero. Note that this definition also applies to non-square matrices.\n\nAlias for LinearAlgebra.istril.\n\nExamples\n\njulia> is_lower_triangular(QQ[1 2 ; 0 4])\nfalse\n\njulia> is_lower_triangular(QQ[1 0 ; 3 4])\ntrue\n\njulia> is_lower_triangular(QQ[1 2 ;])\nfalse\n\njulia> is_lower_triangular(QQ[1 ; 2])\ntrue\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"is_upper_triangular(::MatrixElem)","category":"page"},{"location":"AbstractAlgebra/matrix/#is_upper_triangular-Tuple{MatrixElem}","page":"Matrix functionality","title":"is_upper_triangular","text":"is_upper_triangular(A::MatrixElem)\n\nReturn true if A is an upper triangular matrix, that is, all entries below the main diagonal are zero. Note that this definition also applies to non-square matrices.\n\nAlias for LinearAlgebra.istriu.\n\nExamples\n\njulia> is_upper_triangular(QQ[1 2 ; 0 4])\ntrue\n\njulia> is_upper_triangular(QQ[1 0 ; 3 4])\nfalse\n\njulia> is_upper_triangular(QQ[1 2 ;])\ntrue\n\njulia> is_upper_triangular(QQ[1 ; 2])\nfalse\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"is_diagonal(::MatrixElem)","category":"page"},{"location":"AbstractAlgebra/matrix/#is_diagonal-Tuple{MatrixElem}","page":"Matrix functionality","title":"is_diagonal","text":"is_diagonal(A::MatrixElem)\n\nReturn true if A is a diagonal matrix, that is, all entries off the main diagonal are zero. Note that this definition also applies to non-square matrices.\n\nAlias for LinearAlgebra.isdiag.\n\nExamples\n\njulia> is_diagonal(QQ[1 0 ; 0 4])\ntrue\n\njulia> is_diagonal(QQ[1 2 ; 3 4])\nfalse\n\njulia> is_diagonal(QQ[1 0 ;])\ntrue\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 = number_of_rows(B)\n3\n\njulia> c = number_of_columns(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 <: NCRingElement\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\ntranspose(A::SMat) -> SMat\n\nReturns the transpose of A.\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 <: NCRingElement\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 <: NCRingElement\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 <: NCRingElement\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 <: NCRingElement\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(::MatrixElem)","category":"page"},{"location":"AbstractAlgebra/matrix/#is_symmetric-Tuple{MatrixElem}","page":"Matrix functionality","title":"is_symmetric","text":"is_symmetric(M::MatrixElem)\n\nReturn true if the given matrix is symmetric with respect to its main diagonal, i.e., transpose(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(::MatrixElem)","category":"page"},{"location":"AbstractAlgebra/matrix/#is_skew_symmetric-Tuple{MatrixElem}","page":"Matrix functionality","title":"is_skew_symmetric","text":"is_skew_symmetric(M::MatrixElem)\n\nReturn true if the given matrix is skew symmetric with respect to its main diagonal, i.e., transpose(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::MatrixElem{T}) where T <: NCRingElement\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\ntr(x::AbstractAssociativeAlgebraElem{T}) where T -> T\n\nReturns the trace of x.\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 <: NCRingElement\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, = residue_field(R, x^3 + 3x + 1); a = K(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, = residue_field(R, x^3 + 3x + 1); a = K(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> A = R[x 1; 1 x^2];\n\njulia> d = det(A)\nx^3 - 1\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> A = QQ[1 2; 3 4];\n\njulia> d = rank(A)\n2\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/matrix/#Nilpotency","page":"Matrix functionality","title":"Nilpotency","text":"","category":"section"},{"location":"AbstractAlgebra/matrix/","page":"Matrix functionality","title":"Matrix functionality","text":"is_nilpotent(::MatrixElem{T}) where {T <: RingElement}","category":"page"},{"location":"AbstractAlgebra/matrix/#is_nilpotent-Union{Tuple{MatrixElem{T}}, Tuple{T}} where T<:RingElement","page":"Matrix functionality","title":"is_nilpotent","text":"is_nilpotent(A::MatrixElem{T}) where {T <: RingElement}\n\nReturn if A is nilpotent, i.e. if there exists a natural number k such that A^k = 0. If A is not square an exception is raised.\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":"See Linear Solving & Kernel","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 n times m matrix A over a ring, return a tuple (flag, B). If side is :right and flag is true, B is a right inverse of A i.e. A B is the n times n unit matrix. If side is :left and flag is true, B is a left inverse of A i.e. B A is the m times m unit matrix. If flag is false, no right or left inverse exists.\n\nTo get the space of all inverses, note that if B and C are both right inverses, then A (B - C) = 0, and similar for left inverses. Hence from one inverse one can find all by making suitable use of kernel.\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, = residue_field(R, x^3 + 3x + 1); a = K(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/#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);\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}(::PolyRing{T}, ::MatrixElem{T})","category":"page"},{"location":"AbstractAlgebra/matrix/#charpoly-Union{Tuple{T}, Tuple{PolyRing{T}, MatrixElem{T}}} where T<:RingElem","page":"Matrix functionality","title":"charpoly","text":"charpoly(Y::MatrixElem{T}) where {T <: RingElement}\ncharpoly(S::PolyRing{T}, Y::MatrixElem{T}) where {T <: RingElement}\n\nReturn the characteristic polynomial p of the square matrix Y. If a polynomial ring S over the same base ring as Y is supplied, the resulting polynomial is an element of it.\n\nExamples\n\njulia> R, = residue_ring(ZZ, 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, y = polynomial_ring(R, :y)\n(Univariate polynomial ring in y over residue ring, y)\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)\ny^4 + 2*y^2 + 6*y + 2\n\njulia> A = charpoly(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}(::PolyRing{T}, ::MatElem{T}, ::Bool)","category":"page"},{"location":"AbstractAlgebra/matrix/#minpoly-Union{Tuple{T}, Tuple{PolyRing{T}, MatElem{T}, Bool}} where T<:RingElem","page":"Matrix functionality","title":"minpoly","text":"minpoly(M::MatElem{T}, charpoly_only::Bool = false) where {T <: RingElement}\nminpoly(S::PolyRing{T}, M::MatElem{T}, charpoly_only::Bool = false) where {T <: RingElement}\n\nReturn the minimal polynomial p of the square matrix M. If a polynomial ring S over the same base ring as Y is supplied, the resulting polynomial is an element of it.\n\nExamples\n\njulia> R = GF(13)\nFinite field F_13\n\njulia> S, 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(S, M)\ny^2 + 10*y\n\njulia> A = minpoly(M)\nx^2 + 10*x\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);\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":"Experimental/IntersectionTheory/AbstractVarietyMaps/","page":"Abstract Variety Maps","title":"Abstract Variety Maps","text":"CurrentModule = Oscar","category":"page"},{"location":"Experimental/IntersectionTheory/AbstractVarietyMaps/#Abstract-Variety-Maps","page":"Abstract Variety Maps","title":"Abstract Variety Maps","text":"","category":"section"},{"location":"Experimental/IntersectionTheory/AbstractVarietyMaps/#Constructors","page":"Abstract Variety Maps","title":"Constructors","text":"","category":"section"},{"location":"Experimental/IntersectionTheory/AbstractVarietyMaps/","page":"Abstract Variety Maps","title":"Abstract Variety Maps","text":"hom(X::AbstractVariety, Y::AbstractVariety, fˣ::Vector, fₓ = nothing; inclusion::Bool = false, symbol::String = \"x\")","category":"page"},{"location":"Experimental/IntersectionTheory/AbstractVarietyMaps/#hom","page":"Abstract Variety Maps","title":"hom","text":"hom(X::AbstractVariety, Y::AbstractVariety, fˣ::Vector, fₓ = nothing; inclusion::Bool = false, symbol::String = \"x\")\n\nReturn an abstract variety map X rightarrow Y by specifying the pullbacks of the generators of the Chow ring of Y. \n\nnote: Note\nThe corresponding pushforward can be automatically computed in certain cases.\n\nIn case of an inclusion iXhookrightarrow Y where the class of X is not present in the Chow ring of Y, use the argument inclusion = true. Then, a copy of Y will be created, with extra classes added so that one can pushforward all classes on X.\n\nExamples\n\njulia> P2xP2 = abstract_projective_space(2, symbol = \"k\")*abstract_projective_space(2, symbol = \"l\")\nAbstractVariety of dim 4\n\njulia> P8 = abstract_projective_space(8)\nAbstractVariety of dim 8\n\njulia> k, l = gens(P2xP2)\n2-element Vector{MPolyQuoRingElem{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}}:\n k\n l\n\njulia> Se = hom(P2xP2, P8, [k+l]) # Segre embedding\nAbstractVarietyMap from AbstractVariety of dim 4 to AbstractVariety of dim 8\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"function"},{"location":"Experimental/IntersectionTheory/AbstractVarietyMaps/#Underlying-Data-of-an-Abstract-Variety-Map","page":"Abstract Variety Maps","title":"Underlying Data of an Abstract Variety Map","text":"","category":"section"},{"location":"Experimental/IntersectionTheory/AbstractVarietyMaps/","page":"Abstract Variety Maps","title":"Abstract Variety Maps","text":"An abstract variety map is made up from (a selection of) the data discussed here:","category":"page"},{"location":"Experimental/IntersectionTheory/AbstractVarietyMaps/","page":"Abstract Variety Maps","title":"Abstract Variety Maps","text":"domain(f:: AbstractVarietyMap)","category":"page"},{"location":"Experimental/IntersectionTheory/AbstractVarietyMaps/#domain-Tuple{AbstractVarietyMap}","page":"Abstract Variety Maps","title":"domain","text":" domain(f::AbstractVarietyMap)\n\nReturn the domain of f.\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/IntersectionTheory/AbstractVarietyMaps/","page":"Abstract Variety Maps","title":"Abstract Variety Maps","text":"codomain(f:: AbstractVarietyMap)","category":"page"},{"location":"Experimental/IntersectionTheory/AbstractVarietyMaps/#codomain-Tuple{AbstractVarietyMap}","page":"Abstract Variety Maps","title":"codomain","text":" codomain(f::AbstractVarietyMap)\n\nReturn the codomain of f.\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/IntersectionTheory/AbstractVarietyMaps/","page":"Abstract Variety Maps","title":"Abstract Variety Maps","text":"dim(f::AbstractVarietyMap)","category":"page"},{"location":"Experimental/IntersectionTheory/AbstractVarietyMaps/#dim-Tuple{AbstractVarietyMap}","page":"Abstract Variety Maps","title":"dim","text":"dim(f::AbstractVarietyMap)\n\nReturn the relative dimension of f, that is, return dim(domain(f)) - dim(codomain(f)).\n\nExamples\n\njulia> P2 = abstract_projective_space(2)\nAbstractVariety of dim 2\n\njulia> P5 = abstract_projective_space(5, symbol = \"H\")\nAbstractVariety of dim 5\n\njulia> h = gens(P2)[1]\nh\n\njulia> i = hom(P2, P5, [2*h])\nAbstractVarietyMap from AbstractVariety of dim 2 to AbstractVariety of dim 5\n\njulia> dim(i)\n-3\n\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/IntersectionTheory/AbstractVarietyMaps/","page":"Abstract Variety Maps","title":"Abstract Variety Maps","text":"pullback(f::AbstractVarietyMap, x::MPolyDecRingElem)","category":"page"},{"location":"Experimental/IntersectionTheory/AbstractVarietyMaps/#pullback-Tuple{AbstractVarietyMap, MPolyDecRingElem}","page":"Abstract Variety Maps","title":"pullback","text":"pullback(f::AbstractVarietyMap, y::MPolyDecRingElem)\n\nReturn the pullback of y via f.\n\nExamples\n\njulia> P2 = abstract_projective_space(2)\nAbstractVariety of dim 2\n\njulia> P5 = abstract_projective_space(5, symbol = \"H\")\nAbstractVariety of dim 5\n\njulia> h = gens(P2)[1]\nh\n\njulia> H = gens(P5)[1]\nH\n\njulia> i = hom(P2, P5, [2*h])\nAbstractVarietyMap from AbstractVariety of dim 2 to AbstractVariety of dim 5\n\njulia> pullback(i, H)\n2*h\n\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/IntersectionTheory/AbstractVarietyMaps/","page":"Abstract Variety Maps","title":"Abstract Variety Maps","text":"pushforward(f::AbstractVarietyMap, x::MPolyDecRingElem)","category":"page"},{"location":"Experimental/IntersectionTheory/AbstractVarietyMaps/#pushforward-Tuple{AbstractVarietyMap, MPolyDecRingElem}","page":"Abstract Variety Maps","title":"pushforward","text":"pushforward(f::AbstractVarietyMap, x::MPolyDecRingElem)\n\nReturn the pushforward of x via f.\n\nExamples\n\njulia> P2 = abstract_projective_space(2)\nAbstractVariety of dim 2\n\njulia> P5 = abstract_projective_space(5, symbol = \"H\")\nAbstractVariety of dim 5\n\njulia> h = gens(P2)[1]\nh\n\njulia> i = hom(P2, P5, [2*h])\nAbstractVarietyMap from AbstractVariety of dim 2 to AbstractVariety of dim 5\n\njulia> pushforward(i, h)\n2*H^4\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/IntersectionTheory/AbstractVarietyMaps/","page":"Abstract Variety Maps","title":"Abstract Variety Maps","text":"tangent_bundle(f::AbstractVarietyMap)","category":"page"},{"location":"Experimental/IntersectionTheory/AbstractVarietyMaps/#tangent_bundle-Tuple{AbstractVarietyMap}","page":"Abstract Variety Maps","title":"tangent_bundle","text":"tangent_bundle(f::AbstractVarietyMap)\n\nReturn the relative tangent bundle of f.\n\nExamples\n\njulia> P2 = abstract_projective_space(2)\nAbstractVariety of dim 2\n\njulia> T = tangent_bundle(P2)\nAbstractBundle of rank 2 on AbstractVariety of dim 2\n\njulia> PT = abstract_projective_bundle(T)\nAbstractVariety of dim 3\n\njulia> pi = structure_map(PT)\nAbstractVarietyMap from AbstractVariety of dim 3 to AbstractVariety of dim 2\n\njulia> PBT = pullback(pi, T)\nAbstractBundle of rank 2 on AbstractVariety of dim 3\n\njulia> PBT*OO(PT, 1) - OO(PT) == tangent_bundle(pi) # relative Euler sequence\ntrue\n\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/IntersectionTheory/AbstractVarietyMaps/#Further-Data-Associated-to-an-Abstract-Variety-Map","page":"Abstract Variety Maps","title":"Further Data Associated to an Abstract Variety Map","text":"","category":"section"},{"location":"Experimental/IntersectionTheory/AbstractVarietyMaps/","page":"Abstract Variety Maps","title":"Abstract Variety Maps","text":"cotangent_bundle(f::AbstractVarietyMap)","category":"page"},{"location":"Experimental/IntersectionTheory/AbstractVarietyMaps/#cotangent_bundle-Tuple{AbstractVarietyMap}","page":"Abstract Variety Maps","title":"cotangent_bundle","text":"cotangent_bundle(f::AbstractVarietyMap)\n\nReturn the relative cotangent bundle of f.\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/IntersectionTheory/AbstractVarietyMaps/","page":"Abstract Variety Maps","title":"Abstract Variety Maps","text":"todd_class(f::AbstractVarietyMap)","category":"page"},{"location":"Experimental/IntersectionTheory/AbstractVarietyMaps/#todd_class-Tuple{AbstractVarietyMap}","page":"Abstract Variety Maps","title":"todd_class","text":"todd_class(f::AbstractVarietyMap)\n\nReturn the Todd class of the relative tangent bundle of f.\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/IntersectionTheory/AbstractVarietyMaps/#Operations-on-Abstract-Variety-Maps","page":"Abstract Variety Maps","title":"Operations on Abstract Variety Maps","text":"","category":"section"},{"location":"Experimental/IntersectionTheory/AbstractVarietyMaps/","page":"Abstract Variety Maps","title":"Abstract Variety Maps","text":"compose(f::AbstractVarietyMap, g::AbstractVarietyMap)","category":"page"},{"location":"Experimental/IntersectionTheory/AbstractVarietyMaps/#compose-Tuple{AbstractVarietyMap, AbstractVarietyMap}","page":"Abstract Variety Maps","title":"compose","text":"compose(f::AbstractVarietyMap, g::AbstractVarietyMap)\n\nGiven abstract variety maps f : X to Y and g : Y to Z, say, return their composition.\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/misc/FacElem/#Factored-Elements","page":"Factored Elements","title":"Factored Elements","text":"","category":"section"},{"location":"Hecke/manual/misc/FacElem/","page":"Factored Elements","title":"Factored Elements","text":"CurrentModule = Hecke","category":"page"},{"location":"Hecke/manual/misc/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/manual/misc/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/manual/misc/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/manual/misc/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/manual/misc/FacElem/","page":"Factored Elements","title":"Factored Elements","text":"Important special cases are","category":"page"},{"location":"Hecke/manual/misc/FacElem/","page":"Factored Elements","title":"Factored Elements","text":"FacElem{ZZRingElem, ZZRing}, factored integers\nFacElem{AbsSimpleNumFieldElem, AbsSimpleNumField}, factored algerbaic numbers\nFacElem{AbsNumFieldOrderIdeal, AbsNumFieldOrderIdealSet}, factored ideals","category":"page"},{"location":"Hecke/manual/misc/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/manual/misc/FacElem/#Construction","page":"Factored Elements","title":"Construction","text":"","category":"section"},{"location":"Hecke/manual/misc/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/manual/misc/FacElem/","page":"Factored Elements","title":"Factored Elements","text":"FacElem\nFacElem(a::AbsSimpleNumFieldElem)","category":"page"},{"location":"Hecke/manual/misc/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/manual/misc/FacElem/#FacElem-Tuple{AbsSimpleNumFieldElem}","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/manual/misc/FacElem/","page":"Factored Elements","title":"Factored Elements","text":"ideal(::AbsSimpleNumFieldOrder, ::FacElem{AbsSimpleNumFieldElem, AbsSimpleNumField})","category":"page"},{"location":"Hecke/manual/misc/FacElem/#ideal-Tuple{AbsSimpleNumFieldOrder, FacElem{AbsSimpleNumFieldElem, AbsSimpleNumField}}","page":"Factored Elements","title":"ideal","text":" ideal(O::AbsSimpleNumFieldOrder, a::FacElem{AbsSimpleNumFieldElem, AbsSimpleNumField)\n\nThe factored fractional ideal a*O.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/misc/FacElem/#Conversion","page":"Factored Elements","title":"Conversion","text":"","category":"section"},{"location":"Hecke/manual/misc/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/manual/misc/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/manual/misc/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/manual/misc/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/manual/misc/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/manual/misc/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/manual/misc/FacElem/#Special-functions","page":"Factored Elements","title":"Special functions","text":"","category":"section"},{"location":"Hecke/manual/misc/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/manual/misc/FacElem/","page":"Factored Elements","title":"Factored Elements","text":"simplify(x::FacElem{AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}, AbsNumFieldOrderIdealSet{AbsSimpleNumField, AbsSimpleNumFieldElem}})\nsimplify(x::FacElem{QQFieldElem,S} where S)","category":"page"},{"location":"Hecke/manual/misc/FacElem/#simplify-Tuple{FacElem{AbsSimpleNumFieldOrderIdeal, Hecke.AbsNumFieldOrderIdealSet{AbsSimpleNumField, AbsSimpleNumFieldElem}}}","page":"Factored Elements","title":"simplify","text":"simplify(x::FacElem{AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}, AbsNumFieldOrderIdealSet{AbsSimpleNumField, AbsSimpleNumFieldElem}}) -> FacElem\nsimplify(x::FacElem{AbsSimpleNumFieldOrderFractionalIdeal, AbsNumFieldOrderFractionalIdealSet{AbsSimpleNumField, AbsSimpleNumFieldElem}}) -> 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/manual/misc/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/manual/misc/FacElem/","page":"Factored Elements","title":"Factored Elements","text":"The simplified version can then be used further:","category":"page"},{"location":"Hecke/manual/misc/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{AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}, AbsNumFieldOrderIdealSet{AbsSimpleNumField, AbsSimpleNumFieldElem}})\nfactor_coprime(::FacElem{AbsSimpleNumFieldOrderFractionalIdeal, AbsNumFieldOrderFractionalIdealSet{AbsSimpleNumField, AbsSimpleNumFieldElem}})\nfactor_coprime(::AbsNumFieldOrderIdealSet{AbsSimpleNumField, AbsSimpleNumFieldElem}, ::FacElem{AbsSimpleNumFieldElem, AbsSimpleNumField})\nfactor(::FacElem{AbsSimpleNumFieldOrderFractionalIdeal, AbsNumFieldOrderFractionalIdealSet{AbsSimpleNumField, AbsSimpleNumFieldElem}})\nfactor(::AbsNumFieldOrderIdealSet{AbsSimpleNumField, AbsSimpleNumFieldElem}, ::FacElem{AbsSimpleNumFieldElem, AbsSimpleNumField})","category":"page"},{"location":"Hecke/manual/misc/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/manual/misc/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/manual/misc/FacElem/#factor_coprime-Tuple{FacElem{AbsSimpleNumFieldOrderIdeal, Hecke.AbsNumFieldOrderIdealSet{AbsSimpleNumField, AbsSimpleNumFieldElem}}}","page":"Factored Elements","title":"factor_coprime","text":"factor_coprime(x::FacElem{AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}, AbsNumFieldOrderIdealSet{AbsSimpleNumField, AbsSimpleNumFieldElem}}) -> Dict{AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}, 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/manual/misc/FacElem/#factor_coprime-Tuple{FacElem{AbsSimpleNumFieldOrderFractionalIdeal, Hecke.AbsNumFieldOrderFractionalIdealSet{AbsSimpleNumField, AbsSimpleNumFieldElem}}}","page":"Factored Elements","title":"factor_coprime","text":"factor_coprime(Q::FacElem{AbsSimpleNumFieldOrderFractionalIdeal, AbsNumFieldOrderFractionalIdealSet{AbsSimpleNumField, AbsSimpleNumFieldElem}}) -> Dict{AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}, 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/manual/misc/FacElem/#factor_coprime-Tuple{Hecke.AbsNumFieldOrderIdealSet{AbsSimpleNumField, AbsSimpleNumFieldElem}, FacElem{AbsSimpleNumFieldElem, AbsSimpleNumField}}","page":"Factored Elements","title":"factor_coprime","text":"factor_coprime(I::AbsNumFieldOrderIdealSet{AbsSimpleNumField, AbsSimpleNumFieldElem}, a::FacElem{AbsSimpleNumFieldElem, AbsSimpleNumField}) -> Dict{AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}, 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/manual/misc/FacElem/#factor-Tuple{FacElem{AbsSimpleNumFieldOrderFractionalIdeal, Hecke.AbsNumFieldOrderFractionalIdealSet{AbsSimpleNumField, AbsSimpleNumFieldElem}}}","page":"Factored Elements","title":"factor","text":" factor(Q::FacElem{AbsSimpleNumFieldOrderFractionalIdeal, AbsNumFieldOrderFractionalIdealSet{AbsSimpleNumField, AbsSimpleNumFieldElem}}) -> Dict{AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}, Int}\n\nThe factorisation of Q, by refining a coprime factorisation.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/misc/FacElem/#factor-Tuple{Hecke.AbsNumFieldOrderIdealSet{AbsSimpleNumField, AbsSimpleNumFieldElem}, FacElem{AbsSimpleNumFieldElem, AbsSimpleNumField}}","page":"Factored Elements","title":"factor","text":"factor(I::AbsNumFieldOrderIdealSet{AbsSimpleNumField, AbsSimpleNumFieldElem}, a::FacElem{AbsSimpleNumFieldElem, AbsSimpleNumField}) -> Dict{AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}, ZZRingElem}\n\nFactors the principal ideal generated by a by refining a coprime factorisation.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/misc/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/manual/misc/FacElem/","page":"Factored Elements","title":"Factored Elements","text":"compact_presentation(a::FacElem{AbsSimpleNumFieldElem, AbsSimpleNumField}, n::Int = 2)","category":"page"},{"location":"Hecke/manual/misc/FacElem/#compact_presentation","page":"Factored Elements","title":"compact_presentation","text":"compact_presentation(a::FacElem{AbsSimpleNumFieldElem, AbsSimpleNumField}, 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/manual/misc/FacElem/","page":"Factored Elements","title":"Factored Elements","text":"valuation(::FacElem{AbsSimpleNumFieldElem,AbsSimpleNumField}, ::AbsNumFieldOrderIdeal{AbsSimpleNumField,AbsSimpleNumFieldElem})\nvaluation(::FacElem{AbsNumFieldOrderIdeal{AbsSimpleNumField,AbsSimpleNumFieldElem},Hecke.AbsNumFieldOrderIdealSet{AbsSimpleNumField,AbsSimpleNumFieldElem}}, ::AbsNumFieldOrderIdeal{AbsSimpleNumField,AbsSimpleNumFieldElem})\nevaluate_mod(::FacElem{AbsSimpleNumFieldElem,AbsSimpleNumField}, ::AbsSimpleNumFieldOrderFractionalIdeal)\nreduce_ideal(::FacElem{AbsNumFieldOrderIdeal{AbsSimpleNumField,AbsSimpleNumFieldElem},Hecke.AbsNumFieldOrderIdealSet{AbsSimpleNumField,AbsSimpleNumFieldElem}})\nmodular_proj(::FacElem{AbsSimpleNumFieldElem,AbsSimpleNumField}, ::Hecke.modular_env)","category":"page"},{"location":"Hecke/manual/misc/FacElem/#valuation-Tuple{FacElem{AbsSimpleNumFieldElem, AbsSimpleNumField}, AbsSimpleNumFieldOrderIdeal}","page":"Factored Elements","title":"valuation","text":"valuation(a::FacElem{AbsSimpleNumFieldElem, AbsSimpleNumField}, P::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}) -> ZZRingElem\n\nThe valuation of a at P.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/misc/FacElem/#valuation-Tuple{FacElem{AbsSimpleNumFieldOrderIdeal, Hecke.AbsNumFieldOrderIdealSet{AbsSimpleNumField, AbsSimpleNumFieldElem}}, AbsSimpleNumFieldOrderIdeal}","page":"Factored Elements","title":"valuation","text":"valuation(A::FacElem{AbsSimpleNumFieldOrderFractionalIdeal, AbsNumFieldOrderFractionalIdealSet{AbsSimpleNumField, AbsSimpleNumFieldElem}}, p::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem})\nvaluation(A::FacElem{AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}, AbsNumFieldOrderIdealSet{AbsSimpleNumField, AbsSimpleNumFieldElem}}, p::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem})\n\nThe valuation of A at P.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/misc/FacElem/#evaluate_mod-Tuple{FacElem{AbsSimpleNumFieldElem, AbsSimpleNumField}, AbsSimpleNumFieldOrderFractionalIdeal}","page":"Factored Elements","title":"evaluate_mod","text":"evaluate_mod(a::FacElem{AbsSimpleNumFieldElem, AbsSimpleNumField}, B::AbsSimpleNumFieldOrderFractionalIdeal) -> AbsSimpleNumFieldElem\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/manual/misc/FacElem/#reduce_ideal-Tuple{FacElem{AbsSimpleNumFieldOrderIdeal, Hecke.AbsNumFieldOrderIdealSet{AbsSimpleNumField, AbsSimpleNumFieldElem}}}","page":"Factored Elements","title":"reduce_ideal","text":"reduce_ideal(A::FacElem{AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}}) -> AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}, FacElem{AbsSimpleNumFieldElem}\n\nComputes B and alpha in factored form, such that alpha B = A.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/misc/FacElem/#modular_proj-Tuple{FacElem{AbsSimpleNumFieldElem, AbsSimpleNumField}, Hecke.modular_env}","page":"Factored Elements","title":"modular_proj","text":"modular_proj(a::FacElem{AbsSimpleNumFieldElem, AbsSimpleNumField}, 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/manual/misc/FacElem/#Positivity-and-Signs","page":"Factored Elements","title":"Positivity & Signs","text":"","category":"section"},{"location":"Hecke/manual/misc/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/manual/misc/FacElem/#Miscellaneous","page":"Factored Elements","title":"Miscellaneous","text":"","category":"section"},{"location":"Hecke/manual/misc/FacElem/","page":"Factored Elements","title":"Factored Elements","text":"max_exp(a::FacElem)\nmin_exp(a::FacElem)\nmaxabs_exp(a::FacElem)","category":"page"},{"location":"Hecke/manual/misc/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/manual/misc/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/manual/misc/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":"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":"feasible_region(milp::MixedIntegerLinearProgram)\nambient_dim(milp::MixedIntegerLinearProgram)\noptimal_value(milp::MixedIntegerLinearProgram{T}) where T<:scalar_types\noptimal_solution\nsolve_milp","category":"page"},{"location":"PolyhedralGeometry/mixed_integer_linear_programs/#feasible_region-Tuple{MixedIntegerLinearProgram}","page":"Mixed Integer Linear Programs","title":"feasible_region","text":"feasible_region(milp::MixedIntegerLinearProgram)\n\nReturn the feasible region of the mixed integer linear program milp, which is a Polyhedron.\n\n\n\n\n\n","category":"method"},{"location":"PolyhedralGeometry/mixed_integer_linear_programs/#ambient_dim-Tuple{MixedIntegerLinearProgram}","page":"Mixed Integer Linear Programs","title":"ambient_dim","text":"ambient_dim(MILP::MixedIntegerLinearProgram)\n\nReturn the ambient dimension of the feasible reagion of MILP.\n\n\n\n\n\n","category":"method"},{"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)\nPolytope 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)\nPolytope 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)\nPolytope 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\nConstruct 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 x, y\n over rational field\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 x, y\n over rational field\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\n of multivariate polynomial ring in 2 variables x, y\n over rational field\n by ideal (x)\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(::AbsAffineScheme, ::AbsAffineScheme) 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_names::AbstractVector{<:VarName}) 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::VarName=\"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 x1, x2 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, AbstractVector{<:Union{Char, AbstractString, Symbol}}}} where BRT<:Ring","page":"Affine schemes","title":"affine_space","text":"affine_space(kk::BRT, var_names::AbstractVector{<:VarName}) where {BRT<:Ring}\n\nCreate 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, [:x, :y, :z])\nAffine space of dimension 3\n over rational field\nwith coordinates [x, y, z]\n\njulia> affine_space(QQ, ['x', 'y', 'z'])\nAffine space of dimension 3\n over rational field\nwith coordinates [x, y, z]\n\njulia> affine_space(QQ, [\"x\", \"y\", \"z\"])\nAffine space of dimension 3\n over rational field\nwith coordinates [x, y, z]\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::AbsAffineScheme, f::Vector{<:RingElem})\nsubscheme(X::AbsAffineScheme, I::Ideal)","category":"page"},{"location":"AlgebraicGeometry/Schemes/AffineSchemes/#subscheme-Tuple{AbsAffineScheme, Vector{<:RingElem}}","page":"Affine schemes","title":"subscheme","text":"subscheme(X::AbsAffineScheme, 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 x1, x2, x3\n over rational field\n by ideal (x1)\n\njulia> subscheme(X,[x1,x2])\nSpectrum\n of quotient\n of multivariate polynomial ring in 3 variables x1, x2, x3\n over rational field\n by ideal (x1, x2)\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/AffineSchemes/#subscheme-Tuple{AbsAffineScheme, Ideal}","page":"Affine schemes","title":"subscheme","text":"subscheme(X::AbsAffineScheme, 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 x1, x2, x3\n over rational field\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::AbsAffineScheme{BRT, <:Ring}, Y::AbsAffineScheme{BRT, <:Ring}) where {BRT<:Ring}","category":"page"},{"location":"AlgebraicGeometry/Schemes/AffineSchemes/#intersect-Union{Tuple{BRT}, Tuple{AbsAffineScheme{BRT}, AbsAffineScheme{BRT}}} where BRT<:Ring","page":"Affine schemes","title":"intersect","text":"Base.intersect(X::AbsAffineScheme, Y::AbsAffineScheme)\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 x1, x2, x3\n over rational field\n by ideal (x1)\n\njulia> Y2 = subscheme(X,[x2])\nSpectrum\n of quotient\n of multivariate polynomial ring in 3 variables x1, x2, x3\n over rational field\n by ideal (x2)\n\njulia> intersect(Y1, Y2)\nSpectrum\n of quotient\n of multivariate polynomial ring in 3 variables x1, x2, x3\n over rational field\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::AbsAffineScheme, f::RingElem)\nhypersurface_complement(X::AbsAffineScheme, f::Vector{<:RingElem})","category":"page"},{"location":"AlgebraicGeometry/Schemes/AffineSchemes/#hypersurface_complement-Tuple{AbsAffineScheme, RingElem}","page":"Affine schemes","title":"hypersurface_complement","text":"hypersurface_complement(X::AbsAffineScheme, 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 x1, x2, x3\n over rational field\n at products of (x1)\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/AffineSchemes/#hypersurface_complement-Tuple{AbsAffineScheme, Vector{<:RingElem}}","page":"Affine schemes","title":"hypersurface_complement","text":"hypersurface_complement(X::AbsAffineScheme, 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 x1, x2, x3\n over rational field\n at products of (x1, x2)\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::AbsAffineScheme, Y::AbsAffineScheme)","category":"page"},{"location":"AlgebraicGeometry/Schemes/AffineSchemes/#closure-Tuple{AbsAffineScheme, AbsAffineScheme}","page":"Affine schemes","title":"closure","text":"closure(X::AbsAffineScheme, Y::AbsAffineScheme)\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 x1, x2, x3\n over rational field\n by ideal (x1)\n\njulia> closure(H, X)\nSpectrum\n of quotient\n of multivariate polynomial ring in 3 variables x1, x2, x3\n over rational field\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::AbsAffineScheme)","category":"page"},{"location":"AlgebraicGeometry/Schemes/AffineSchemes/#ambient_space-Tuple{AbsAffineScheme}","page":"Affine schemes","title":"ambient_space","text":"ambient_space(X::AbsAffineScheme)\n\nReturn the ambient affine space of X.\n\nUse ambient_embedding(::AbsAffineScheme) 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 x, y\n over rational field\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 x, y\n over rational field\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\n of multivariate polynomial ring in 2 variables x, y\n over rational field\n by ideal (x)\n at products of (y)\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 generated by\n 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 x, y\n over rational field\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 x, y\n over rational field\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\n of multivariate polynomial ring in 2 variables x, y\n over rational field\n by ideal (x)\n at products of (y)\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::AbsAffineScheme)\ncodim(X::AbsAffineScheme)\nambient_embedding(X::AbsAffineScheme)\ndim(X::AbsAffineScheme)\nname(X::AbsAffineScheme)\nOO(X::AbsAffineScheme)","category":"page"},{"location":"AlgebraicGeometry/Schemes/AffineSchemes/#base_ring-Tuple{AbsAffineScheme}","page":"Affine schemes","title":"base_ring","text":"base_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\nbase_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 generated by\n x^2\n x*y\n 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::AbsAffineScheme)\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\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/AffineSchemes/#codim-Tuple{AbsAffineScheme}","page":"Affine schemes","title":"codim","text":"codim(X::AbsAffineScheme)\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 x1, x2, x3\n over rational field\n by ideal (x1)\n\njulia> codim(Y)\n1\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/AffineSchemes/#ambient_embedding-Tuple{AbsAffineScheme}","page":"Affine schemes","title":"ambient_embedding","text":"ambient_embedding(X::AbsAffineScheme)\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 x, y\n over rational field\n by ideal (x)\n\njulia> inc = ambient_embedding(Y)\nAffine scheme morphism\n from [x, y] scheme(x)\n to [x, y] affine 2-space over QQ\ngiven by the pullback function\n x -> x\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{AbsAffineScheme}","page":"Affine schemes","title":"dim","text":"dim(X::AbsAffineScheme)\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{AbsAffineScheme}","page":"Affine schemes","title":"name","text":"name(X::AbsAffineScheme)\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{AbsAffineScheme}","page":"Affine schemes","title":"OO","text":"OO(X::AbsAffineScheme)\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::AbsAffineScheme, Y::AbsAffineScheme)\nis_closed_embedding(X::AbsAffineScheme, Y::AbsAffineScheme)\nisempty(X::AbsAffineScheme)\nis_subscheme(X::AbsAffineScheme, Y::AbsAffineScheme)","category":"page"},{"location":"AlgebraicGeometry/Schemes/AffineSchemes/#is_open_embedding-Tuple{AbsAffineScheme, AbsAffineScheme}","page":"Affine schemes","title":"is_open_embedding","text":"is_open_embedding(X::AbsAffineScheme, Y::AbsAffineScheme)\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 x1, x2, x3\n over rational field\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 x1, x2, x3\n over rational field\n at products of (x1)\n\njulia> is_open_embedding(Z, X)\ntrue\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/AffineSchemes/#is_closed_embedding-Tuple{AbsAffineScheme, AbsAffineScheme}","page":"Affine schemes","title":"is_closed_embedding","text":"is_closed_embedding(X::AbsAffineScheme, Y::AbsAffineScheme)\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 x1, x2, x3\n over rational field\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 x1, x2, x3\n over rational field\n at products of (x1)\n\njulia> is_closed_embedding(Z, X)\nfalse\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/AffineSchemes/#isempty-Tuple{AbsAffineScheme}","page":"Affine schemes","title":"isempty","text":"is_empty(X::AbsAffineScheme)\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/#is_subscheme-Tuple{AbsAffineScheme, AbsAffineScheme}","page":"Affine schemes","title":"is_subscheme","text":"is_subscheme(X::AbsAffineScheme, Y::AbsAffineScheme)\n\nCheck whether X is a subset of Y based on the comparison of their coordinate rings. See inclusion_morphism(::AbsAffineScheme, ::AbsAffineScheme) 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 x1, x2, x3\n over rational field\n by ideal (x1*x2)\n\njulia> is_subscheme(X, Y)\nfalse\n\njulia> is_subscheme(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::AbsAffineScheme{<:Field}, P::AbsAffineRationalPoint)\nis_normal(X::AbsAffineScheme; check::Bool=true)\nnormalization(X::AbsAffineScheme; check::Bool=true, algorithm=:equidimDec)","category":"page"},{"location":"AlgebraicGeometry/Schemes/AffineSchemes/#tangent_space-Tuple{AbsAffineScheme{<:Field}, AbsAffineRationalPoint}","page":"Affine schemes","title":"tangent_space","text":"tangent_space(X::AbsAffineScheme{<: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/#is_normal-Tuple{AbsAffineScheme}","page":"Affine schemes","title":"is_normal","text":"is_normal(X::AbsAffineScheme; check::Bool=true) -> Bool\n\nInput:\n\na reduced scheme X,\nif check is true, then confirm that X is reduced; this is expensive.\n\nOutput:\n\nReturns whether the scheme X is normal.\n\nExamples\n\njulia> R, (x, y, z) = QQ[:x, :y, :z];\n\njulia> X = spec(R);\n\njulia> is_normal(X)\ntrue\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/AffineSchemes/#normalization-Tuple{AbsAffineScheme}","page":"Affine schemes","title":"normalization","text":"normalization(X::AbsAffineScheme) -> Vector{Tuple{AbsAffineScheme, AbsAffineSchemeMor}}\n\nReturn the normalization of the reduced affine scheme X.\n\nInput:\n\nA reduced affine scheme X\nif check is true confirm that X is reduced; this is expensive\nthe keyword argument algorithm is passed on to normalization(::MPolyQuoRing)\n\nOutput:\n\nA list of pairs (Y_i f_i) where Y_i is a normal scheme and f_i is a morphism from Y_i to X. The disjoint union of the Y_i is the normalization of X and the f_i are the restrictions of the normalization morphism to Y_i.\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::AbsAffineScheme)","category":"page"},{"location":"AlgebraicGeometry/Schemes/AffineSchemes/#is_non_zero_divisor-Tuple{RingElem, AbsAffineScheme}","page":"Affine schemes","title":"is_non_zero_divisor","text":"is_non_zero_divisor(f::RingElem, X::AbsAffineScheme)\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 = Oscar.doctestsetup()","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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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<:FieldElem}","category":"page"},{"location":"Experimental/LieAlgebras/modules/#*-Union{Tuple{C}, Tuple{LieAlgebraElem{C}, LieAlgebraModuleElem{C, LieT} where LieT<:LieAlgebraElem{C}}} where C<:FieldElem","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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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":"trivial_module(L::LieAlgebra, d::IntegerUnion=1)\nstandard_module(::LinearLieAlgebra)\ndual(::LieAlgebraModule{C}) where {C<:FieldElem}\ndirect_sum(::LieAlgebraModule{C}, ::LieAlgebraModule{C}) where {C<:FieldElem}\ntensor_product(::LieAlgebraModule{C}, ::LieAlgebraModule{C}) where {C<:FieldElem}\nexterior_power(::LieAlgebraModule{C}, ::Int) where {C<:FieldElem}\nsymmetric_power(::LieAlgebraModule{C}, ::Int) where {C<:FieldElem}\ntensor_power(::LieAlgebraModule{C}, ::Int) where {C<:FieldElem}\nabstract_module(::LieAlgebra{C}, ::Int, ::Vector{<:MatElem{C}}, ::Vector{<:VarName}; ::Bool) where {C<:FieldElem}\nabstract_module(::LieAlgebra{C}, ::Int, ::Matrix{SRow{C}}, ::Vector{<:VarName}; ::Bool) where {C<:FieldElem}","category":"page"},{"location":"Experimental/LieAlgebras/modules/#trivial_module","page":"Lie algebra modules","title":"trivial_module","text":"trivial_module(L::LieAlgebra{C}, d=1) -> LieAlgebraModule{C}\n\nConstruct the d-dimensional module of the Lie algebra L with trivial action.\n\nExamples\n\njulia> L = special_linear_lie_algebra(QQ, 3);\n\njulia> trivial_module(L)\nAbstract Lie algebra module\n of dimension 1\nover special linear Lie algebra of degree 3 over QQ\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"function"},{"location":"Experimental/LieAlgebras/modules/#standard_module-Tuple{LinearLieAlgebra}","page":"Lie algebra modules","title":"standard_module","text":"standard_module(L::LinearLieAlgebra{C}; cached::Bool=true) -> 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\nnote: Note\nThis uses the left action of L, and converts that to internally use the equivalent right action.\n\nExamples\n\njulia> L = special_linear_lie_algebra(QQ, 3);\n\njulia> standard_module(L)\nStandard module\n of dimension 3\nover special linear Lie algebra of degree 3 over QQ\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/modules/#dual-Union{Tuple{LieAlgebraModule{C, LieT} where LieT<:LieAlgebraElem{C}}, Tuple{C}} where C<:FieldElem","page":"Lie algebra modules","title":"dual","text":"dual(V::LieAlgebraModule{C}; cached::Bool=true) -> LieAlgebraModule{C}\n\nConstruct the dual module of V.\n\nExamples\n\njulia> L = special_linear_lie_algebra(QQ, 3);\n\njulia> V = exterior_power(standard_module(L), 2)[1]; # some module\n\njulia> dual(V)\nDual module\n of dimension 3\n dual of\n 2nd exterior power of\n standard module\nover special linear Lie algebra of degree 3 over QQ\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/modules/#direct_sum-Union{Tuple{C}, Tuple{LieAlgebraModule{C, LieT} where LieT<:LieAlgebraElem{C}, LieAlgebraModule{C, LieT} where LieT<:LieAlgebraElem{C}}} where C<:FieldElem","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\nExamples\n\njulia> L = special_linear_lie_algebra(QQ, 3);\n\njulia> V1 = exterior_power(standard_module(L), 2)[1]; # some module\n\njulia> V2 = symmetric_power(standard_module(L), 3)[1]; # some module\n\njulia> direct_sum(V1, V2)\nDirect sum module\n of dimension 13\n direct sum with direct summands\n 2nd exterior power of\n standard module\n 3rd symmetric power of\n standard module\nover special linear Lie algebra of degree 3 over QQ\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/modules/#tensor_product-Union{Tuple{C}, Tuple{LieAlgebraModule{C, LieT} where LieT<:LieAlgebraElem{C}, LieAlgebraModule{C, LieT} where LieT<:LieAlgebraElem{C}}} where C<:FieldElem","page":"Lie algebra modules","title":"tensor_product","text":"tensor_product(Vs::LieAlgebraModule{C}...) -> LieAlgebraModule{C}\n⊗(Vs::LieAlgebraModule{C}...) -> LieAlgebraModule{C}\n\nGiven modules V_1dotsV_n over the same Lie algebra L, construct their tensor product V_1 otimes cdots otimes V_n.\n\nExamples\n\njulia> L = special_linear_lie_algebra(QQ, 3);\n\njulia> V1 = exterior_power(standard_module(L), 2)[1]; # some module\n\njulia> V2 = symmetric_power(standard_module(L), 3)[1]; # some module\n\njulia> tensor_product(V1, V2)\nTensor product module\n of dimension 30\n tensor product with tensor factors\n 2nd exterior power of\n standard module\n 3rd symmetric power of\n standard module\nover special linear Lie algebra of degree 3 over QQ\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/modules/#exterior_power-Union{Tuple{C}, Tuple{LieAlgebraModule{C, LieT} where LieT<:LieAlgebraElem{C}, Int64}} where C<:FieldElem","page":"Lie algebra modules","title":"exterior_power","text":"exterior_power(V::LieAlgebraModule{C}, k::Int; cached::Bool=true) -> LieAlgebraModule{C}, Map\n\nConstruct the k-th exterior power bigwedge^k (V) of the module V, together with a map that computes the wedge product of k elements of V.\n\nExamples\n\njulia> L = special_linear_lie_algebra(QQ, 2);\n\njulia> V = symmetric_power(standard_module(L), 2)[1]; # some module\n\njulia> E, map = exterior_power(V, 2)\n(Exterior power module of dimension 3 over L, Map: parent of tuples of type Tuple{LieAlgebraModuleElem{QQFieldElem, LinearLieAlgebraElem{QQFieldElem}}, LieAlgebraModuleElem{QQFieldElem, LinearLieAlgebraElem{QQFieldElem}}} -> E)\n\njulia> E\nExterior power module\n of dimension 3\n 2nd exterior power of\n 2nd symmetric power of\n standard module\nover special linear Lie algebra of degree 2 over QQ\n\njulia> basis(E)\n3-element Vector{LieAlgebraModuleElem{QQFieldElem, LinearLieAlgebraElem{QQFieldElem}}}:\n (v_1^2)^(v_1*v_2)\n (v_1^2)^(v_2^2)\n (v_1*v_2)^(v_2^2)\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/modules/#symmetric_power-Union{Tuple{C}, Tuple{LieAlgebraModule{C, LieT} where LieT<:LieAlgebraElem{C}, Int64}} where C<:FieldElem","page":"Lie algebra modules","title":"symmetric_power","text":"symmetric_power(V::LieAlgebraModule{C}, k::Int; cached::Bool=true) -> LieAlgebraModule{C}, Map\n\nConstruct the k-th symmetric power S^k (V) of the module V, together with a map that computes the product of k elements of V.\n\nExamples\n\njulia> L = special_linear_lie_algebra(QQ, 4);\n\njulia> V = exterior_power(standard_module(L), 3)[1]; # some module\n\njulia> S, map = symmetric_power(V, 2)\n(Symmetric power module of dimension 10 over L, Map: parent of tuples of type Tuple{LieAlgebraModuleElem{QQFieldElem, LinearLieAlgebraElem{QQFieldElem}}, LieAlgebraModuleElem{QQFieldElem, LinearLieAlgebraElem{QQFieldElem}}} -> S)\n\njulia> S\nSymmetric power module\n of dimension 10\n 2nd symmetric power of\n 3rd exterior power of\n standard module\nover special linear Lie algebra of degree 4 over QQ\n\njulia> basis(S)\n10-element Vector{LieAlgebraModuleElem{QQFieldElem, LinearLieAlgebraElem{QQFieldElem}}}:\n (v_1^v_2^v_3)^2\n (v_1^v_2^v_3)*(v_1^v_2^v_4)\n (v_1^v_2^v_3)*(v_1^v_3^v_4)\n (v_1^v_2^v_3)*(v_2^v_3^v_4)\n (v_1^v_2^v_4)^2\n (v_1^v_2^v_4)*(v_1^v_3^v_4)\n (v_1^v_2^v_4)*(v_2^v_3^v_4)\n (v_1^v_3^v_4)^2\n (v_1^v_3^v_4)*(v_2^v_3^v_4)\n (v_2^v_3^v_4)^2\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/modules/#tensor_power-Union{Tuple{C}, Tuple{LieAlgebraModule{C, LieT} where LieT<:LieAlgebraElem{C}, Int64}} where C<:FieldElem","page":"Lie algebra modules","title":"tensor_power","text":"tensor_power(V::LieAlgebraModule{C}, k::Int; cached::Bool=true) -> LieAlgebraModule{C}, Map\n\nConstruct the k-th tensor power T^k (V) of the module V, together with a map that computes the tensor product of k elements of V.\n\nExamples\n\njulia> L = special_linear_lie_algebra(QQ, 3);\n\njulia> V = exterior_power(standard_module(L), 2)[1]; # some module\n\njulia> T, map = tensor_power(V, 2)\n(Tensor power module of dimension 9 over L, Map: parent of tuples of type Tuple{LieAlgebraModuleElem{QQFieldElem, LinearLieAlgebraElem{QQFieldElem}}, LieAlgebraModuleElem{QQFieldElem, LinearLieAlgebraElem{QQFieldElem}}} -> T)\n\njulia> T\nTensor power module\n of dimension 9\n 2nd tensor power of\n 2nd exterior power of\n standard module\nover special linear Lie algebra of degree 3 over QQ\n\njulia> basis(T)\n9-element Vector{LieAlgebraModuleElem{QQFieldElem, LinearLieAlgebraElem{QQFieldElem}}}:\n (v_1^v_2)(x)(v_1^v_2)\n (v_1^v_2)(x)(v_1^v_3)\n (v_1^v_2)(x)(v_2^v_3)\n (v_1^v_3)(x)(v_1^v_2)\n (v_1^v_3)(x)(v_1^v_3)\n (v_1^v_3)(x)(v_2^v_3)\n (v_2^v_3)(x)(v_1^v_2)\n (v_2^v_3)(x)(v_1^v_3)\n (v_2^v_3)(x)(v_2^v_3)\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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<:FieldElem","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 right 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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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<:FieldElem","page":"Lie algebra modules","title":"abstract_module","text":"abstract_module(L::LieAlgebra{C}, dimV::Int, struct_consts::Matrix{sparse_row_type{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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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":"[Koz08]","category":"page"},{"location":"Combinatorics/simplicialcomplexes/#Construction","page":"Simplicial Complexes","title":"Construction","text":"","category":"section"},{"location":"Combinatorics/simplicialcomplexes/","page":"Simplicial Complexes","title":"Simplicial Complexes","text":"simplicial_complex(K::Vector{Vector{Int}})","category":"page"},{"location":"Combinatorics/simplicialcomplexes/#simplicial_complex-Tuple{Vector{Vector{Int64}}}","page":"Simplicial Complexes","title":"simplicial_complex","text":"simplical_complex(generators::Union{Vector{Vector{Int}}, Vector{Set{Int}}})\n\nConstruct an abstract simplicial complex from a set of faces. While arbitrary non-negative integers are allowed as vertices, they will be relabeled to consecutive integers starting at 1.\n\nExamples\n\njulia> K = simplicial_complex([[1,2,3],[2,3,4]])\nAbstract simplicial complex of dimension 2 on 4 vertices\n\njulia> G = complete_bipartite_graph(2,3)\nUndirected graph with 5 nodes and the following edges:\n(3, 1)(3, 2)(4, 1)(4, 2)(5, 1)(5, 2)\n\njulia> K = simplicial_complex(G)\nAbstract simplicial complex of dimension 1 on 5 vertices\n\nSimplicial complex comprising the empty set only:\n\njulia> empty = simplicial_complex(Vector{Set{Int}}([]))\nAbstract simplicial complex of dimension -1 on 0 vertices\n\nThe original vertices can be recovered:\n\njulia> L = simplicial_complex([[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 = simplicial_complex([[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 = simplicial_complex([[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":"n_vertices(K::SimplicialComplex)\nn_facets(K::SimplicialComplex)\ndim(K::SimplicialComplex)\nf_vector(K::SimplicialComplex)\nh_vector(K::SimplicialComplex)\neuler_characteristic(K::SimplicialComplex)","category":"page"},{"location":"Combinatorics/simplicialcomplexes/#n_vertices-Tuple{SimplicialComplex}","page":"Simplicial Complexes","title":"n_vertices","text":"n_vertices(K::SimplicialComplex)\n\nReturn the number of vertices of the abstract simplicial complex K.\n\nExamples\n\njulia> n_vertices(torus())\n7\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/simplicialcomplexes/#n_facets-Tuple{SimplicialComplex}","page":"Simplicial Complexes","title":"n_facets","text":"n_facets(K::SimplicialComplex)\n\nReturn the number of facets of the abstract simplicial complex K.\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 integral homology group of K.\n\nExamples\n\njulia> [ homology(real_projective_plane(), i) for i in [0,1,2] ]\n3-element Vector{FinGenAbGroup}:\n Z\n Z/2\n 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 integral cohomology group of K.\n\nExamples\n\njulia> K = simplicial_complex([[0,1],[1,2],[0,2]]);\n\njulia> cohomology(K,1)\nZ\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/#Recognizing-topological-spaces","page":"Simplicial Complexes","title":"Recognizing topological spaces","text":"","category":"section"},{"location":"Combinatorics/simplicialcomplexes/","page":"Simplicial Complexes","title":"Simplicial Complexes","text":"is_sphere(K::SimplicialComplex)\nis_ball(K::SimplicialComplex)\nis_manifold(K::SimplicialComplex)","category":"page"},{"location":"Combinatorics/simplicialcomplexes/#is_sphere-Tuple{SimplicialComplex}","page":"Simplicial Complexes","title":"is_sphere","text":"is_sphere(K::SimplicialComplex)\n\nHeuristically check if the abstract simplicial complex K is a combinatorial sphere; see [JLLT22]. Note that this is undecidable in general. Returns true if recognized as a sphere. Returns false if not a sphere. Returns nothing if heuristics unsuccessful.\n\nExamples\n\njulia> K = simplicial_complex([[1,2,3],[2,3,4]]);\n\njulia> is_sphere(K)\nfalse\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/simplicialcomplexes/#is_ball-Tuple{SimplicialComplex}","page":"Simplicial Complexes","title":"is_ball","text":"is_ball(K::SimplicialComplex)\n\nHeuristically check if the abstract simplicial complex K is a combinatorial ball; see [JLLT22]. Note that this is undecidable in general. Returns true if recognized as a ball. Returns false if not a ball. Returns nothing if heuristics unsuccessful.\n\nExamples\n\njulia> K = simplicial_complex([[1,2,3],[2,3,4]]);\n\njulia> is_ball(K)\ntrue\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/simplicialcomplexes/#is_manifold-Tuple{SimplicialComplex}","page":"Simplicial Complexes","title":"is_manifold","text":"is_manifold(K::SimplicialComplex)\n\nCheck if the abstract simplicial complex K is a combinatorial manifold, possibly with boundary. Note that this is undecidable in general. Returns true if recognized as a manifold. Returns false if not a manifold. Returns nothing if heuristics unsuccessful.\n\nExamples\n\njulia> is_manifold(torus())\ntrue\n\njulia> is_manifold(simplicial_complex([[1,2],[2,3]]))\ntrue\n\njulia> is_manifold(simplicial_complex([[1,2],[2,3],[2,4]]))\nfalse\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 = simplicial_complex([[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 = simplicial_complex([[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 [BH09].","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 generated by\n x1*x2*x3\n x1*x2*x4\n x1*x5*x6\n x2*x5*x6\n x1*x3*x6\n x1*x4*x5\n x3*x4*x5\n x3*x4*x6\n x2*x3*x5\n 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 generated by\n a*b*c\n a*b*d\n a*e*f\n b*e*f\n a*c*f\n a*d*e\n c*d*e\n c*d*f\n b*c*e\n 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 = simplicial_complex([[1,2,3],[2,3,4]]);\n\njulia> stanley_reisner_ring(K)\n(Quotient of multivariate polynomial ring by ideal (x1*x4), Map: multivariate polynomial ring -> quotient of multivariate polynomial ring)\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 (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), Map: R -> quotient of multivariate polynomial ring)\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/simplicialcomplexes/#Helpful-functions","page":"Simplicial Complexes","title":"Helpful functions","text":"","category":"section"},{"location":"Combinatorics/simplicialcomplexes/","page":"Simplicial Complexes","title":"Simplicial Complexes","text":"is_isomorphic(K1::SimplicialComplex, K2::SimplicialComplex)\nconnected_sum(K1::SimplicialComplex, K2::SimplicialComplex, f1::Int=0, f2::Int=0)\ndeletion(K::SimplicialComplex, face::Union{<:AbstractSet{Int},<:AbstractVector{Int}})\nautomorphism_group(K::SimplicialComplex; action=:on_vertices)\non_simplicial_complex(K::SimplicialComplex, g::PermGroupElem)","category":"page"},{"location":"Combinatorics/simplicialcomplexes/#is_isomorphic-Tuple{SimplicialComplex, SimplicialComplex}","page":"Simplicial Complexes","title":"is_isomorphic","text":"is_isomorphic(K1::SimplicialComplex, K2::SimplicialComplex)\n\nChecks if the given simplicial complexes are isomorphic.\n\nExamples\n\njulia> K1 = simplicial_complex([[1,2,3],[2,3,4]]);\n\njulia> K2 = simplicial_complex([[1,2,3],[2,3,4]]);\n\njulia> is_isomorphic(K1, K2)\ntrue\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/simplicialcomplexes/#connected_sum","page":"Simplicial Complexes","title":"connected_sum","text":"connected_sum(K1::SimplicialComplex, K2::SimplicialComplex, f1::Int=0, f2::Int=0)\n\nCompute the connected sum of two abstract simplicial complexes. Parameters f1 and f2 specify which facet of the first and second complex correspondingly are glued together. Default is the 0-th facet of both. The vertices in the selected facets are identified with each other according to their order in the facet (that is, in increasing index order).\n\nExamples\n\njulia> K = torus();\n\njulia> surface_genus_2 = connected_sum(K, K)\nAbstract simplicial complex of dimension 2 on 11 vertices\n\njulia> homology(surface_genus_2, 1)\nZ^4\n\njulia> is_manifold(surface_genus_2)\ntrue\n\n\n\n\n\n","category":"function"},{"location":"Combinatorics/simplicialcomplexes/#deletion-Tuple{SimplicialComplex, Union{AbstractSet{Int64}, AbstractVector{Int64}}}","page":"Simplicial Complexes","title":"deletion","text":"deletion(K::SimplicialComplex, face::Union{<:AbstractSet{Int},<:AbstractVector{Int}})\n\nRemove the given face and all the faces containing it from an abstract simplicial complex K.\n\nExamples\n\njulia> K = simplicial_complex([[1, 2, 3], [2, 3, 4]]);\n\njulia> K_with_deletion = deletion(K, Set([1, 2]));\n\njulia> facets(K_with_deletion)\n2-element Vector{Set{Int64}}:\n Set([3, 1])\n Set([4, 2, 3])\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/simplicialcomplexes/#automorphism_group-Tuple{SimplicialComplex}","page":"Simplicial Complexes","title":"automorphism_group","text":"automorphism_group(K::SimplicialComplex; action=:on_vertices)\n\nGiven a simplicial complex K return its automorphism group as a PermGroup. The group can be returned as a subgroup of the permutation group of the vertices by passing :on_vertices to the action keyword argument or on the facets by passing :on_facets.\n\nExamples\n\njulia> K = simplicial_complex([[1, 2, 3], [2, 3, 4]])\nAbstract simplicial complex of dimension 2 on 4 vertices\n\njulia> automorphism_group(K)\nPermutation group of degree 4\n\n\n\n\n\n","category":"method"},{"location":"Combinatorics/simplicialcomplexes/#on_simplicial_complex-Tuple{SimplicialComplex, PermGroupElem}","page":"Simplicial Complexes","title":"on_simplicial_complex","text":"on_simplicial_complex(K::SimplicialComplex, g::PermGroupElem)\n\nGiven a simplicial complex K return the simplicial complex corresponding to a permutation on it's vertices given by g.\n\nExamples\n\njulia> K = simplicial_complex([[1, 2, 3], [2, 3, 4]])\nAbstract simplicial complex of dimension 2 on 4 vertices\n\njulia> G = automorphism_group(K)\nPermutation group of degree 4\n\njulia> g = collect(G)[2]\n(1,4)\n\njulia> facets(on_simplicial_complex(K, g))\n2-element Vector{Set{Int64}}:\n Set([2, 3, 1])\n Set([4, 2, 3])\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":"Experimental/PartitionedPermutations/introduction/","page":"Partitioned Permutations","title":"Partitioned Permutations","text":"CurrentModule = Oscar","category":"page"},{"location":"Experimental/PartitionedPermutations/introduction/#Partitioned-Permutations","page":"Partitioned Permutations","title":"Partitioned Permutations","text":"","category":"section"},{"location":"Experimental/PartitionedPermutations/introduction/","page":"Partitioned Permutations","title":"Partitioned Permutations","text":"Partitioned Permutations are used in the context of Free Probability Theory to model higher order freeness and higher order free cumulants, see e.g. [CMS07].","category":"page"},{"location":"Experimental/PartitionedPermutations/introduction/","page":"Partitioned Permutations","title":"Partitioned Permutations","text":"We provide basic functions for working with partitioned permutations. The focus is on factorizing partitioned permutations.","category":"page"},{"location":"Experimental/PartitionedPermutations/introduction/#Basics","page":"Partitioned Permutations","title":"Basics","text":"","category":"section"},{"location":"Experimental/PartitionedPermutations/introduction/","page":"Partitioned Permutations","title":"Partitioned Permutations","text":"Formally, a partitioned permutation (V pi) consists of a permutation pi and a partition V of the set 1 n such that the partition dominates the permutation in the sense that every cycle of pi is contained in one block of V. We call n the length of (V pi). Mathematically, another length function is more important. It is given by (V pi) = n - ( 2 cdot textnumber of blocks of V - textnumber of cycles of pi) and we call this the adjusted length of (V pi). Note that this terminology is not used in the literature.","category":"page"},{"location":"Experimental/PartitionedPermutations/introduction/","page":"Partitioned Permutations","title":"Partitioned Permutations","text":"PartitionedPermutation\nlength(pp::PartitionedPermutation)\nadjusted_length(pp::PartitionedPermutation)","category":"page"},{"location":"Experimental/PartitionedPermutations/introduction/#PartitionedPermutation","page":"Partitioned Permutations","title":"PartitionedPermutation","text":"PartitionedPermutation\n\nThe type of partitioned permutations. Fieldnames are\n\np::PermGroupElem - a permutation\nV::SetPartition - a partition\n\nIf the permutation has length n, then the partition must have n upper points and 0 lower points. Further, if W is the partition given by the cycles of p, then W must be dominated by V in the sense that every block of W is contained in one block of V. There is one inner constructer of PartitionedPermutation:\n\nPartitionedPermutation(p::PermGroupElem, V::Vector{Int}) constructs the partitioned permutation where the partition is given by the vector V.\n\nIf the optional flag check is set to false, then the constructor skips the validation of the requirements mentioned above.\n\nExamples\n\njulia> PartitionedPermutation(perm(symmetric_group(3), [2, 1, 3]), [1, 1, 2])\nPartitionedPermutation((1,2), SetPartition([1, 1, 2], Int64[]))\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"type"},{"location":"Experimental/PartitionedPermutations/introduction/#length-Tuple{PartitionedPermutation}","page":"Partitioned Permutations","title":"length","text":"length(pp::PartitionedPermutation)\n\nReturn the length of a partitioned permutation, i.e. the size of the underlying set.\n\nExamples\n\njulia> length(partitioned_permutation(perm(symmetric_group(2), [2, 1]), [1, 1]))\n2\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/PartitionedPermutations/introduction/#adjusted_length-Tuple{PartitionedPermutation}","page":"Partitioned Permutations","title":"adjusted_length","text":"adjusted_length(pp::PartitionedPermutation)\n\nReturn the adjusted length of a partitioned permutation as described in [CMS07] as |(V, pi)| for a partition V and a permutation pi.\n\nExamples\n\njulia> adjusted_length(partitioned_permutation(perm(symmetric_group(2), [2, 1]), [1, 1]))\n1\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/PartitionedPermutations/introduction/#Products-of-Partitioned-Permutations","page":"Partitioned Permutations","title":"Products of Partitioned Permutations","text":"","category":"section"},{"location":"Experimental/PartitionedPermutations/introduction/","page":"Partitioned Permutations","title":"Partitioned Permutations","text":"For two partitioned permutations (V pi) and (W sigma) one defines their product as (V pi) cdot (W sigma) = (V vee W pi sigma) if (V pi) + (W sigma) = (V vee W pi sigma). Otherwise, one sets (V pi) cdot (W sigma) = (O mathrmid). Here, O is the partition where every block consists of exactly one element, and V vee W denotes the join of the partitions V and W.","category":"page"},{"location":"Experimental/PartitionedPermutations/introduction/","page":"Partitioned Permutations","title":"Partitioned Permutations","text":"A major problem is the factorization of a partitioned permutation (V pi). This involves finding all pairs (W_1 sigma_1) (W_2 sigma_2) of partitioned permutations with (V pi) = (W_1 sigma_1) cdot (W_2 sigma_2).","category":"page"},{"location":"Experimental/PartitionedPermutations/introduction/","page":"Partitioned Permutations","title":"Partitioned Permutations","text":"*(pp_1::PartitionedPermutation, pp_2::PartitionedPermutation)\nenumerate_partitioned_permutations(n::Int)\nfactor(pp::PartitionedPermutation)","category":"page"},{"location":"Experimental/PartitionedPermutations/introduction/#*-Tuple{PartitionedPermutation, PartitionedPermutation}","page":"Partitioned Permutations","title":"*","text":"*(pp_1::PartitionedPermutation, pp_2::PartitionedPermutation)\n\nReturn the product of two partitioned permutations as described in [CMS07].\n\nExamples\n\njulia> x = partitioned_permutation(perm(symmetric_group(3), [1, 2, 3]), [1, 2, 3])\nPartitionedPermutation((), SetPartition([1, 2, 3], Int64[]))\n\njulia> y = partitioned_permutation(perm(symmetric_group(3), [2, 1, 3]), [1, 1, 3])\nPartitionedPermutation((1,2), SetPartition([1, 1, 2], Int64[]))\n\njulia> x*y\nPartitionedPermutation((1,2), SetPartition([1, 1, 2], Int64[]))\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/PartitionedPermutations/introduction/#enumerate_partitioned_permutations-Tuple{Int64}","page":"Partitioned Permutations","title":"enumerate_partitioned_permutations","text":"enumerate_partitioned_permutations(n::Int)\n\nReturn and calculate all PartitionedPermutation objects of length n\n\nExamples\n\njulia> length(enumerate_partitioned_permutations(6))\n4051\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/PartitionedPermutations/introduction/#factor-Tuple{PartitionedPermutation}","page":"Partitioned Permutations","title":"factor","text":"factor(pp::PartitionedPermutation)\n\nReturn the factorization of pp in form of a set of 2-tuples.\n\nExamples\n\njulia> length(factor(partitioned_permutation(perm(symmetric_group(3), [2, 1, 3]), [1, 1, 2])))\n2\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"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":"an evolving toolkit for dealing with PBW-algebras and their quotients modulo two-sided ideals,\nsome functionality 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":"[GP08]\n[DL06]\n[BGV03]","category":"page"},{"location":"NoncommutativeAlgebra/intro/","page":"Introduction","title":"Introduction","text":"and the thesis","category":"page"},{"location":"NoncommutativeAlgebra/intro/","page":"Introduction","title":"Introduction","text":"[Lev05]","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":"Hecke/manual/algebras/structureconstant/#SCA","page":"Structure constant algebras","title":"Structure constant algebras","text":"","category":"section"},{"location":"Hecke/manual/algebras/structureconstant/","page":"Structure constant algebras","title":"Structure constant algebras","text":"CurrentModule = Hecke\nDocTestSetup = quote\n using Hecke\nend","category":"page"},{"location":"Hecke/manual/algebras/structureconstant/#Creation","page":"Structure constant algebras","title":"Creation","text":"","category":"section"},{"location":"Hecke/manual/algebras/structureconstant/","page":"Structure constant algebras","title":"Structure constant algebras","text":"structure_constant_algebra(::Ring, ::Array{<:Any, 3})\nstructure_constant_algebra(::SimpleNumField)","category":"page"},{"location":"Hecke/manual/algebras/structureconstant/#structure_constant_algebra-Tuple{Ring, Array{<:Any, 3}}","page":"Structure constant algebras","title":"structure_constant_algebra","text":"structure_constant_algebra(R::Ring, sctable::Array{_, 3}; one::Vector = nothing,\n check::Bool = true)\n\nGiven an array with dimensions (d d d) and a ring R, return the d-dimensional structure constant algebra over R. The basis e of R satisfies e[i] * e[j] = sum(sctable[i,j,k] * e[k] for k in 1:d).\n\nUnless check = false, this includes (time consuming) associativity and distributivity checks. If one is given, record the element with the supplied coordinate vector as the one element of the algebra.\n\nExamples\n\njulia> associative_algebra(QQ, reshape([1, 0, 0, 2, 0, 1, 1, 0], (2, 2, 2)))\nStructure constant algebra of dimension 2 over QQ\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/algebras/structureconstant/#structure_constant_algebra-Tuple{SimpleNumField}","page":"Structure constant algebras","title":"structure_constant_algebra","text":"structure_constant_algebra(K::SimpleNumField) -> StructureConstantAlgebra, Map\n\nGiven a number field LK, return L as a K-algebra A together with a K-linear map A to L.\n\nExamples\n\njulia> L, = quadratic_field(2);\n\njulia> structure_constant_algebra(L)\n(Structure constant algebra of dimension 2 over QQ, Map: structure constant algebra -> real quadratic field)\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/algebras/structureconstant/#Structure-constant-table","page":"Structure constant algebras","title":"Structure constant table","text":"","category":"section"},{"location":"Hecke/manual/algebras/structureconstant/","page":"Structure constant algebras","title":"Structure constant algebras","text":"structure_constant_table(::StructureConstantAlgebra)","category":"page"},{"location":"Hecke/manual/algebras/structureconstant/#structure_constant_table-Tuple{StructureConstantAlgebra}","page":"Structure constant algebras","title":"structure_constant_table","text":"structure_constant_table(A::StructureConstantAlgebra; copy::Bool = true) -> Array{_, 3}\n\nGiven an algebra A, return the structure constant table of A. See structure_constant_algebra for the defining property.\n\nExamples\n\njulia> A = associative_algebra(QQ, reshape([1, 0, 0, 2, 0, 1, 1, 0], (2, 2, 2)));\n\njulia> structure_constant_table(A)\n2×2×2 Array{QQFieldElem, 3}:\n[:, :, 1] =\n 1 0\n 0 2\n\n[:, :, 2] =\n 0 1\n 1 0\n\n\n\n\n\n","category":"method"},{"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":"AlgebraicGeometry/Schemes/Cycles/","page":"Cycles and divisors","title":"Cycles and divisors","text":"CurrentModule = Oscar","category":"page"},{"location":"AlgebraicGeometry/Schemes/Cycles/#Cycles-and-divisors","page":"Cycles and divisors","title":"Cycles and divisors","text":"","category":"section"},{"location":"AlgebraicGeometry/Schemes/Cycles/#Algebraic-Cycles","page":"Cycles and divisors","title":"Algebraic Cycles","text":"","category":"section"},{"location":"AlgebraicGeometry/Schemes/Cycles/","page":"Cycles and divisors","title":"Cycles and divisors","text":"AbsAlgebraicCycle{CoveredSchemeType<:AbsCoveredScheme, CoefficientRingType<:AbstractAlgebra.Ring}","category":"page"},{"location":"AlgebraicGeometry/Schemes/Cycles/#AbsAlgebraicCycle","page":"Cycles and divisors","title":"AbsAlgebraicCycle","text":"AbsAlgebraicCycle{CoveredSchemeType<:AbsCoveredScheme, CoefficientRingType<:Ring}\n\nAn algebraic cycle D on a (locally) Noetherian integral scheme X with coefficients in a ring R is a formal linear combination sum_i a_i D_i with D_i subseteq X integral, closed subschemes and the a_i in R.\n\nSuch a cycle is represented non-uniquely as a formal sum E = sum_l b_l mathcalI_l of equidimensional ideal sheaves mathcalI_l subseteq mathcalO_X. For an equidimensional ideal sheaf mathcalI its interpretation as a cycle is as follows: Let V(mathcalI)=E_1 cup dots cup E_n be the decomposition of the vanishing locus of mathcalI into irreducible components E_i=V(mathcalP_i) with mathcalP_i prime. Then E corresponds to the cycle D = sum_i=1^n mathrmcolength_mathcalP_i(mathcalI)E_i.\n\nExamples\n\njulia> P2 = projective_space(QQ,2); (s0,s1,s2) = homogeneous_coordinates(P2);\n\njulia> I = ideal_sheaf(P2,ideal([s0,s1^2]))\nSheaf of ideals\n on scheme over QQ covered with 3 patches\n 1: [(s1//s0), (s2//s0)] affine 2-space\n 2: [(s0//s1), (s2//s1)] affine 2-space\n 3: [(s0//s2), (s1//s2)] affine 2-space\nwith restrictions\n 1: Ideal (1, (s1//s0)^2)\n 2: Ideal ((s0//s1), 1)\n 3: Ideal ((s0//s2), (s1//s2)^2)\n\njulia> D = algebraic_cycle(I)\nEffective algebraic cycle\n on scheme over QQ covered with 3 patches\nwith coefficients in integer ring\ngiven as the formal sum of\n 1 * sheaf of ideals\n\njulia> irreducible_decomposition(D)\nEffective algebraic cycle\n on scheme over QQ covered with 3 patches\nwith coefficients in integer ring\ngiven as the formal sum of\n 2 * sheaf of prime ideals\n\n\n\n\n\n\n","category":"type"},{"location":"AlgebraicGeometry/Schemes/Cycles/#Constructors","page":"Cycles and divisors","title":"Constructors","text":"","category":"section"},{"location":"AlgebraicGeometry/Schemes/Cycles/","page":"Cycles and divisors","title":"Cycles and divisors","text":"algebraic_cycle(X::AbsCoveredScheme, R::Ring)\nalgebraic_cycle(I::AbsIdealSheaf, R::Ring)\nalgebraic_cycle(I::AbsIdealSheaf)","category":"page"},{"location":"AlgebraicGeometry/Schemes/Cycles/#algebraic_cycle-Tuple{AbsCoveredScheme, Ring}","page":"Cycles and divisors","title":"algebraic_cycle","text":"algebraic_cycle(X::AbsCoveredScheme, R::Ring) -> AlgebraicCycle\n\nReturn the zero AlgebraicCycle over X with coefficients in R.\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 = proj(P, I);\n\njulia> Ycov = covered_scheme(Y);\n\njulia> R = ZZ;\n\njulia> algebraic_cycle(Ycov, R)\nZero algebraic cycle\n on scheme over QQ covered with 3 patches\nwith coefficients in integer ring\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/Cycles/#algebraic_cycle-Tuple{Oscar.AbsIdealSheaf, Ring}","page":"Cycles and divisors","title":"algebraic_cycle","text":"algebraic_cycle(I::AbsIdealSheaf, R::Ring) -> AlgebraicCycle\n\nReturn the AlgebraicCycle D = 1 I with coefficients in R for a sheaf of equidimensional ideals I.\n\nNote that I must be equidimensional.\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 = proj(P);\n\njulia> II = IdealSheaf(Y, I);\n\njulia> R = ZZ;\n\njulia> algebraic_cycle(II, R)\nEffective algebraic cycle\n on scheme over QQ covered with 3 patches\nwith coefficients in integer ring\ngiven as the formal sum of\n 1 * sheaf of ideals\n\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/Cycles/#algebraic_cycle-Tuple{Oscar.AbsIdealSheaf}","page":"Cycles and divisors","title":"algebraic_cycle","text":"algebraic_cycle(I::AbsIdealSheaf) -> AlgebraicCycle\n\nReturn the AlgebraicCycle D = 1 I with coefficients in ℤ for a sheaf of equidimensional ideals I.\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 = proj(P);\n\njulia> II = IdealSheaf(Y, I);\n\njulia> R = ZZ;\n\njulia> algebraic_cycle(II, R)\nEffective algebraic cycle\n on scheme over QQ covered with 3 patches\nwith coefficients in integer ring\ngiven as the formal sum of\n 1 * sheaf of ideals\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/Cycles/#Properties","page":"Cycles and divisors","title":"Properties","text":"","category":"section"},{"location":"AlgebraicGeometry/Schemes/Cycles/","page":"Cycles and divisors","title":"Cycles and divisors","text":"ambient_scheme(D::AbsAlgebraicCycle)\ncomponents(D::AbsAlgebraicCycle)\ndim(D::AbsAlgebraicCycle)\nirreducible_decomposition(D::AbsAlgebraicCycle)\nintegral(W::AbsAlgebraicCycle; check::Bool=true)","category":"page"},{"location":"AlgebraicGeometry/Schemes/Cycles/#ambient_scheme-Tuple{AbsAlgebraicCycle}","page":"Cycles and divisors","title":"ambient_scheme","text":"ambient_scheme(D::AbsAlgebraicCycle)\n\nReturn the CoveredScheme X on which D is defined.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/Cycles/#components-Tuple{AbsAlgebraicCycle}","page":"Cycles and divisors","title":"components","text":"components(D::AbsAlgebraicCycle)\n\nReturn a list of ideal sheaves such that D is a linear combination of the corresponding cycles.\n\nnote: Note\nThe order of the components may change in different julia sessions. It is however consistent with the printing.\n\nnote: Note\nThe ideal sheaves are only guaranteed equidimensional and may carry multiplicities. See irreducible_decomposition(::AbsAlgebraicCycle) for the more conventional decomposition. \n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/Cycles/#dim-Tuple{AbsAlgebraicCycle}","page":"Cycles and divisors","title":"dim","text":"dim(D::AbsAlgebraicCycle)\n\nReturn the dimension of the support of the cycle D.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/Cycles/#irreducible_decomposition-Tuple{AbsAlgebraicCycle}","page":"Cycles and divisors","title":"irreducible_decomposition","text":"irreducible_decomposition(D::AbsAlgebraicCycle)\n\nReturn a cycle E equal to D but as a formal sum E = ₖ aₖ Iₖ where the components Iₖ of E are all sheaves of prime ideals.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/Cycles/#integral-Tuple{AbsAlgebraicCycle}","page":"Cycles and divisors","title":"integral","text":"integral(W::AbsAlgebraicCycle)\n\nAssume W is an algebraic cycle on X. This returns the sum of the lengths of all the components of dimension 0 of W.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/Cycles/#Attributes","page":"Cycles and divisors","title":"Attributes","text":"","category":"section"},{"location":"AlgebraicGeometry/Schemes/Cycles/","page":"Cycles and divisors","title":"Cycles and divisors","text":"is_effective(A::AbsAlgebraicCycle)\nis_prime(D::AbsAlgebraicCycle)","category":"page"},{"location":"AlgebraicGeometry/Schemes/Cycles/#is_effective-Tuple{AbsAlgebraicCycle}","page":"Cycles and divisors","title":"is_effective","text":"is_effective(A::AbsAlgebraicCycle)\n\nReturn whether all the coefficients are non-negative.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/Cycles/#is_prime-Tuple{AbsAlgebraicCycle}","page":"Cycles and divisors","title":"is_prime","text":"is_prime(D::AbsAlgebraicCycle)\n\nAn algebraic cycle is called prime if it consists of a single irreducible subvariety.\n\nNote that this property is not stable under base extension. \n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/Cycles/#Methods","page":"Cycles and divisors","title":"Methods","text":"","category":"section"},{"location":"AlgebraicGeometry/Schemes/Cycles/","page":"Cycles and divisors","title":"Cycles and divisors","text":"Base.:<=(A::AbsAlgebraicCycle,B::AbsAlgebraicCycle)","category":"page"},{"location":"AlgebraicGeometry/Schemes/Cycles/#<=-Tuple{AbsAlgebraicCycle, AbsAlgebraicCycle}","page":"Cycles and divisors","title":"<=","text":"Base.:<=(A::AbsAlgebraicCycle, B::AbsAlgebraicCycle)\n\nA leq B\n\nif and only if B - A is effective.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/Cycles/#Weil-Divisors","page":"Cycles and divisors","title":"Weil Divisors","text":"","category":"section"},{"location":"AlgebraicGeometry/Schemes/Cycles/","page":"Cycles and divisors","title":"Cycles and divisors","text":"AbsWeilDivisor{CoveredSchemeType, CoefficientRingType}","category":"page"},{"location":"AlgebraicGeometry/Schemes/Cycles/#AbsWeilDivisor","page":"Cycles and divisors","title":"AbsWeilDivisor","text":"AbsWeilDivisor{CoveredSchemeType, CoefficientRingType} <: AbsAlgebraicCycle{CoveredSchemeType, CoefficientRingType}\n\nA Weil divisor with coefficients of type CoefficientRingType on a (locally) Noetherian integral scheme X of type CoveredSchemeType.\n\nExamples\n\njulia> P2 = projective_space(QQ,2); (s0,s1,s2) = homogeneous_coordinates(P2);\n\njulia> I = ideal((s0*s1)^2);\n\njulia> II = ideal_sheaf(P2, I);\n\njulia> D = weil_divisor(II)\nEffective weil divisor\n on scheme over QQ covered with 3 patches\nwith coefficients in integer ring\ngiven as the formal sum of\n 1 * sheaf of ideals\n\njulia> E = irreducible_decomposition(D)\nEffective weil divisor\n on scheme over QQ covered with 3 patches\nwith coefficients in integer ring\ngiven as the formal sum of\n 2 * prime ideal sheaf on scheme over QQ covered with 3 patches extended from ideal ((s1//s0)) on affine 2-space\n 2 * prime ideal sheaf on scheme over QQ covered with 3 patches extended from ideal ((s0//s1)) on affine 2-space\n\njulia> P = components(E)[1]\nPrime ideal sheaf on Scheme over QQ covered with 3 patches extended from Ideal ((s1//s0)) on Affine 2-space\n\njulia> components(D)[1] == II\ntrue\n\njulia> D[II] # to get the coefficient\n1\n\njulia> E[P]\n2\n\n\n\n\n\n","category":"type"},{"location":"AlgebraicGeometry/Schemes/Cycles/#Constructors-2","page":"Cycles and divisors","title":"Constructors","text":"","category":"section"},{"location":"AlgebraicGeometry/Schemes/Cycles/","page":"Cycles and divisors","title":"Cycles and divisors","text":"weil_divisor(X::AbsCoveredScheme, R::Ring)\nweil_divisor(I::AbsIdealSheaf; check::Bool=true)\nweil_divisor(I::AbsIdealSheaf, R::Ring; check::Bool=true)","category":"page"},{"location":"AlgebraicGeometry/Schemes/Cycles/#weil_divisor-Tuple{AbsCoveredScheme, Ring}","page":"Cycles and divisors","title":"weil_divisor","text":"weil_divisor(X::AbsCoveredScheme, R::Ring) -> WeilDivisor\n\nReturn the zero weil divisor on X with coefficients in the ring R.\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 = proj(P, I);\n\njulia> Ycov = covered_scheme(Y);\n\njulia> weil_divisor(Ycov, QQ)\nZero weil divisor\n on scheme over QQ covered with 3 patches\nwith coefficients in rational field\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/Cycles/#weil_divisor-Tuple{Oscar.AbsIdealSheaf}","page":"Cycles and divisors","title":"weil_divisor","text":"weil_divisor(I::AbsIdealSheaf) -> WeilDivisor\n\nGiven an ideal sheaf I of pure codimension 1, return the weil divisor D = 1 I with coefficients in the integer ring.\n\nExample\n\njulia> P, (x, y, z) = graded_polynomial_ring(QQ, [:x, :y, :z]);\n\njulia> Y = proj(P);\n\njulia> I = ideal([(x^3-y^2*z)]);\n\njulia> II = IdealSheaf(Y, I);\n\njulia> weil_divisor(II)\nEffective weil divisor\n on scheme over QQ covered with 3 patches\nwith coefficients in integer ring\ngiven as the formal sum of\n 1 * sheaf of ideals\n \njulia> JJ = II^2;\n\njulia> D = weil_divisor(JJ)\nEffective weil divisor\n on scheme over QQ covered with 3 patches\nwith coefficients in integer ring\ngiven as the formal sum of\n 1 * product of 2 ideal sheaves\n\njulia> irreducible_decomposition(D)\nEffective weil divisor\n on scheme over QQ covered with 3 patches\nwith coefficients in integer ring\ngiven as the formal sum of\n 2 * sheaf of prime ideals\n\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/Cycles/#weil_divisor-Tuple{Oscar.AbsIdealSheaf, Ring}","page":"Cycles and divisors","title":"weil_divisor","text":"weil_divisor(I::AbsIdealSheaf, R::Ring; check::Bool=true)\n\nGiven an ideal sheaf I of pure codimension 1 and a ring R, return the weil divisor D = 1 I with coefficients in R.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/Cycles/#Methods-2","page":"Cycles and divisors","title":"Methods","text":"","category":"section"},{"location":"AlgebraicGeometry/Schemes/Cycles/","page":"Cycles and divisors","title":"Cycles and divisors","text":"Besides the methods for AbsAlgebraicCycle the following are available.","category":"page"},{"location":"AlgebraicGeometry/Schemes/Cycles/","page":"Cycles and divisors","title":"Cycles and divisors","text":"is_in_linear_system(f::VarietyFunctionFieldElem, D::AbsWeilDivisor; regular_on_complement::Bool=false, check::Bool=true)\norder_of_vanishing(f::VarietyFunctionFieldElem, D::AbsWeilDivisor; check::Bool=true)\nintersect(D::AbsWeilDivisor, E::AbsWeilDivisor; covering::Covering=default_covering(scheme(D)))","category":"page"},{"location":"AlgebraicGeometry/Schemes/Cycles/#is_in_linear_system-Tuple{VarietyFunctionFieldElem, Oscar.AbsWeilDivisor}","page":"Cycles and divisors","title":"is_in_linear_system","text":"is_in_linear_system(f::VarietyFunctionFieldElem, D::WeilDivisor; regular_on_complement::Bool=true, check::Bool=true) -> Bool\n\nReturn whether the rational function f is in the linear system D, i.e. if (f) + D geq 0.\n\nInput\n\nregular_on_complement – set to true if f is regular on the complement of the support of D. \n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/Cycles/#order_of_vanishing-Tuple{VarietyFunctionFieldElem, Oscar.AbsWeilDivisor}","page":"Cycles and divisors","title":"order_of_vanishing","text":"order_of_vanishing(f::VarietyFunctionFieldElem, D::AbsWeilDivisor; check::Bool=true)\n\nReturn the order of vanishing of the rational function f on the prime divisor D.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/Cycles/#intersect-Tuple{Oscar.AbsWeilDivisor, Oscar.AbsWeilDivisor}","page":"Cycles and divisors","title":"intersect","text":"intersect(D::AbsWeilDivisor, E::AbsWeilDivisor; covering::Covering=default_covering(ambient_scheme(D)))\n\nReturn the intersection number of the the Weil divisors D and E on a complete smooth surface as defined in [Har77].\n\nInput\n\nThe optional keyword argument covering specifies the covering to be used for the computation.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/Cycles/#Linear-Systems","page":"Cycles and divisors","title":"Linear Systems","text":"","category":"section"},{"location":"AlgebraicGeometry/Schemes/Cycles/","page":"Cycles and divisors","title":"Cycles and divisors","text":"LinearSystem{DivisorType<:AbsWeilDivisor}\nweil_divisor(L::LinearSystem)\nvariety(L::LinearSystem)\nsubsystem(L::LinearSystem, D::AbsWeilDivisor)","category":"page"},{"location":"AlgebraicGeometry/Schemes/Cycles/#LinearSystem","page":"Cycles and divisors","title":"LinearSystem","text":"LinearSystem\n\nA linear system of a Weil divisor D on a variety X, generated by rational functions f₁fᵣ K(X).\n\n\n\n\n\n","category":"type"},{"location":"AlgebraicGeometry/Schemes/Cycles/#weil_divisor-Tuple{LinearSystem}","page":"Cycles and divisors","title":"weil_divisor","text":"weil_divisor(L::LinearSystem)\n\nReturn the divisor D of the linear system L = D.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/Cycles/#variety-Tuple{LinearSystem}","page":"Cycles and divisors","title":"variety","text":"variety(L::LinearSystem)\n\nReturn the variety on which L is defined.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/Cycles/#subsystem-Tuple{LinearSystem, Oscar.AbsWeilDivisor}","page":"Cycles and divisors","title":"subsystem","text":"subsystem(L::LinearSystem, D::AbsWeilDivisor) -> LinearSystem, MatElem\n\nGiven a linear system L = E and a divisor D leq E compute D and the matrix representing the inclusion D hookrightarrow E with respect to the given bases of both systems.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/Cycles/#Cartier-Divisors","page":"Cycles and divisors","title":"Cartier Divisors","text":"","category":"section"},{"location":"AlgebraicGeometry/Schemes/Cycles/","page":"Cycles and divisors","title":"Cycles and divisors","text":"CartierDivisor{CoveredSchemeType<:AbsCoveredScheme, CoeffType<:RingElem}\nEffectiveCartierDivisor{CoveredSchemeType<:AbsCoveredScheme}","category":"page"},{"location":"AlgebraicGeometry/Schemes/Cycles/#CartierDivisor","page":"Cycles and divisors","title":"CartierDivisor","text":"CartierDivisor{CoveredSchemeType<:AbsCoveredScheme, CoeffType<:RingElem}\n\nA Cartier divisor C on a scheme X with coefficients a_i in a ring R is a formal linear combination sum_i a_i D_i of effective Cartier divisors D_i.\n\nThe scheme X is of type CoveredSchemeType. The coefficients a_i are of type CoeffType.\n\n\n\n\n\n","category":"type"},{"location":"AlgebraicGeometry/Schemes/Cycles/#EffectiveCartierDivisor","page":"Cycles and divisors","title":"EffectiveCartierDivisor","text":"EffectiveCartierDivisor{CoveredSchemeType<:AbsCoveredScheme}\n\nAn effective Cartier divisor on a scheme X is a closed subscheme D subseteq X whose ideal sheaf mathcalI_D subseteq mathcalO_X is an invertible mathcalO_X-module. In particular, mathcalI_D is locally principal.\n\nInternally, C stores a trivializing_covering(C::EffectiveCartierDivisor). The scheme X is of type CoveredSchemeType.\n\n\n\n\n\n","category":"type"},{"location":"AlgebraicGeometry/Schemes/Cycles/","page":"Cycles and divisors","title":"Cycles and divisors","text":"Cartier divisors support elementary arithmetic.","category":"page"},{"location":"AlgebraicGeometry/Schemes/Cycles/#Constructors-3","page":"Cycles and divisors","title":"Constructors","text":"","category":"section"},{"location":"AlgebraicGeometry/Schemes/Cycles/","page":"Cycles and divisors","title":"Cycles and divisors","text":"effective_cartier_divisor(I::AbsIdealSheaf; trivializing_covering::Covering = default_covering(scheme(I)), check::Bool = true)\neffective_cartier_divisor(IP::AbsProjectiveScheme, f::Union{MPolyDecRingElem, MPolyQuoRingElem})\ncartier_divisor(E::EffectiveCartierDivisor)\ncartier_divisor(IP::AbsProjectiveScheme, f::Union{MPolyDecRingElem, MPolyQuoRingElem})","category":"page"},{"location":"AlgebraicGeometry/Schemes/Cycles/#effective_cartier_divisor-Tuple{Oscar.AbsIdealSheaf}","page":"Cycles and divisors","title":"effective_cartier_divisor","text":"effective_cartier_divisor(I::IdealSheaf;\n trivializing_covering::Covering = default_covering(scheme(I)))\n -> EffectiveCartierDivisor\n\nReturn the effective Cartier divisor defined by the ideal sheaf I, given that I is principal in the given covering of the scheme on which it is defined.\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 = proj(P);\n\njulia> II = IdealSheaf(Y, I);\n\njulia> effective_cartier_divisor(II)\nEffective cartier divisor\n on scheme over QQ covered with 3 patches\n 1: [(y//x), (z//x)] affine 2-space\n 2: [(x//y), (z//y)] affine 2-space\n 3: [(x//z), (y//z)] affine 2-space\ndefined by\n sheaf of ideals with restrictions\n 1: Ideal (-(y//x)^2*(z//x) + 1)\n 2: Ideal ((x//y)^3 - (z//y))\n 3: Ideal ((x//z)^3 - (y//z)^2)\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/Cycles/#effective_cartier_divisor-Tuple{AbsProjectiveScheme, Union{MPolyDecRingElem, MPolyQuoRingElem}}","page":"Cycles and divisors","title":"effective_cartier_divisor","text":"effective_cartier_divisor(IP::AbsProjectiveScheme, f::Union{MPolyDecRingElem, MPolyQuoRingElem})\n\nReturn the effective Cartier divisor on the projective scheme X defined by the homogeneous polynomial f. \n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/Cycles/#cartier_divisor-Tuple{EffectiveCartierDivisor}","page":"Cycles and divisors","title":"cartier_divisor","text":"cartier_divisor(E::EffectiveCartierDivisor) -> CartierDivisor\n\nConvert an EffectiveCartierDivisor into a CartierDivisor with coefficient 1 in the ring of integers.\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 = proj(P);\n\njulia> II = IdealSheaf(Y, I);\n\njulia> E = effective_cartier_divisor(II)\nEffective cartier divisor\n on scheme over QQ covered with 3 patches\n 1: [(y//x), (z//x)] affine 2-space\n 2: [(x//y), (z//y)] affine 2-space\n 3: [(x//z), (y//z)] affine 2-space\ndefined by\n sheaf of ideals with restrictions\n 1: Ideal (-(y//x)^2*(z//x) + 1)\n 2: Ideal ((x//y)^3 - (z//y))\n 3: Ideal ((x//z)^3 - (y//z)^2)\n\njulia> cartier_divisor(E)\nCartier divisor\n on scheme over QQ covered with 3 patches\nwith coefficients in integer ring\ndefined by the formal sum of\n 1 * effective cartier divisor on scheme over QQ covered with 3 patches\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/Cycles/#cartier_divisor-Tuple{AbsProjectiveScheme, Union{MPolyDecRingElem, MPolyQuoRingElem}}","page":"Cycles and divisors","title":"cartier_divisor","text":"cartier_divisor(IP::AbsProjectiveScheme, f::Union{MPolyDecRingElem, MPolyQuoRingElem})\n\nReturn the (effective) Cartier divisor on the projective scheme X defined by the homogeneous polynomial f. \n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/Cycles/#Attributes-2","page":"Cycles and divisors","title":"Attributes","text":"","category":"section"},{"location":"AlgebraicGeometry/Schemes/Cycles/","page":"Cycles and divisors","title":"Cycles and divisors","text":"ideal_sheaf(C::EffectiveCartierDivisor)\nambient_scheme(C::EffectiveCartierDivisor)\nambient_scheme(C::CartierDivisor)\ncoefficient_ring(C::CartierDivisor)\ncomponents(C::CartierDivisor)\ntrivializing_covering(C::EffectiveCartierDivisor)","category":"page"},{"location":"AlgebraicGeometry/Schemes/Cycles/#ideal_sheaf-Tuple{EffectiveCartierDivisor}","page":"Cycles and divisors","title":"ideal_sheaf","text":"ideal_sheaf(C::EffectiveCartierDivisor)\n\nReturn the sheaf of ideals mathcalI_C subseteq mathcalO_X representing C.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/Cycles/#ambient_scheme-Tuple{EffectiveCartierDivisor}","page":"Cycles and divisors","title":"ambient_scheme","text":"ambient_scheme(C::EffectiveCartierDivisor)\n\nReturn the ambient scheme containing C. \n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/Cycles/#ambient_scheme-Tuple{CartierDivisor}","page":"Cycles and divisors","title":"ambient_scheme","text":"ambient_scheme(C::CartierDivisor)\n\nReturn the ambient scheme containing C. \n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/Cycles/#coefficient_ring-Tuple{CartierDivisor}","page":"Cycles and divisors","title":"coefficient_ring","text":"coefficient_ring(C::CartierDivisor)\n\nReturn the ring of coefficients of C.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/Cycles/#components-Tuple{CartierDivisor}","page":"Cycles and divisors","title":"components","text":"components(C::CartierDivisor)\n\nReturn a list of effective Cartier divisors C_i such that C is a linear combination of the C_i.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/Cycles/#trivializing_covering-Tuple{EffectiveCartierDivisor}","page":"Cycles and divisors","title":"trivializing_covering","text":"trivializing_covering(C::EffectiveCartierDivisor)\n\nReturn the trivializing covering of the effective Cartier divisor C.\n\nA covering (U_i)_i in I is called trivializing for C if C(U_i) is principal for all i in I.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/CoveringsAndGluings/","page":"Coverings","title":"Coverings","text":"CurrentModule = Oscar","category":"page"},{"location":"AlgebraicGeometry/Schemes/CoveringsAndGluings/#Coverings","page":"Coverings","title":"Coverings","text":"","category":"section"},{"location":"AlgebraicGeometry/Schemes/CoveringsAndGluings/","page":"Coverings","title":"Coverings","text":"Coverings are the backbone data structure for CoveredSchemes in Oscar. ","category":"page"},{"location":"AlgebraicGeometry/Schemes/CoveringsAndGluings/","page":"Coverings","title":"Coverings","text":"Covering","category":"page"},{"location":"AlgebraicGeometry/Schemes/CoveringsAndGluings/#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/CoveringsAndGluings/#Constructors","page":"Coverings","title":"Constructors","text":"","category":"section"},{"location":"AlgebraicGeometry/Schemes/CoveringsAndGluings/","page":"Coverings","title":"Coverings","text":"Covering(patches::Vector{<:AbsAffineScheme})\ndisjoint_union(C1::Covering, C2::Covering)","category":"page"},{"location":"AlgebraicGeometry/Schemes/CoveringsAndGluings/#Covering-Tuple{Vector{<:AbsAffineScheme}}","page":"Coverings","title":"Covering","text":"Covering(patches::Vector{<:AbsAffineScheme})\n\nReturn a Covering with pairwise disjoint affine charts Uᵢ given by the entries of patches. This Covering will have no gluings except those gluings 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: affine 2-space\n 2: affine 2-space\n in the coordinate(s)\n 1: [x, y]\n 2: [u, v]\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/CoveringsAndGluings/#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 gluings of the disjoint union are given by the disjoint union of the charts and gluings 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: affine 2-space\n in the coordinate(s)\n 1: [x, y]\n\njulia> C2 = Covering(U2)\nCovering\n described by patches\n 1: affine 2-space\n in the coordinate(s)\n 1: [u, v]\n\njulia> C = disjoint_union(C1, C2)\nCovering\n described by patches\n 1: affine 2-space\n 2: affine 2-space\n in the coordinate(s)\n 1: [x, y]\n 2: [u, v]\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/CoveringsAndGluings/#Attributes","page":"Coverings","title":"Attributes","text":"","category":"section"},{"location":"AlgebraicGeometry/Schemes/CoveringsAndGluings/","page":"Coverings","title":"Coverings","text":"affine_charts(C::Covering)\ngluings(C::Covering)","category":"page"},{"location":"AlgebraicGeometry/Schemes/CoveringsAndGluings/#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/CoveringsAndGluings/#gluings-Tuple{Covering}","page":"Coverings","title":"gluings","text":"gluings(C::Covering)\n\nReturn a dictionary of gluings 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 gluing.\n\nNote: Gluings 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 gluings.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/CoveringsAndGluings/#Methods","page":"Coverings","title":"Methods","text":"","category":"section"},{"location":"AlgebraicGeometry/Schemes/CoveringsAndGluings/","page":"Coverings","title":"Coverings","text":"add_gluing!(C::Covering, G::AbsGluing)","category":"page"},{"location":"AlgebraicGeometry/Schemes/CoveringsAndGluings/#add_gluing!-Tuple{Covering, AbsGluing}","page":"Coverings","title":"add_gluing!","text":"add_gluing!(C::Covering, G::AbsGluing)\n\nAdd a gluing 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: affine 2-space\n 2: affine 2-space\n in the coordinate(s)\n 1: [x, y]\n 2: [u, v]\n\njulia> V1 = PrincipalOpenSubset(U1, x); # Preparations for gluing\n\njulia> V2 = PrincipalOpenSubset(U2, u);\n\njulia> f = morphism(V1, V2, [1//x, y//x]); # The gluing isomorphism\n\njulia> g = morphism(V2, V1, [1//u, v//u]); # and its inverse\n\njulia> G = Gluing(U1, U2, f, g); # Construct the gluing\n\njulia> add_gluing!(C, G) # Make the gluing part of the Covering\nCovering\n described by patches\n 1: affine 2-space\n 2: affine 2-space\n in the coordinate(s)\n 1: [x, y]\n 2: [u, v]\n\njulia> C[U1, U2] == G # Check whether the gluing of U1 and U2 in C is G.\ntrue\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/CoveringsAndGluings/#Gluings","page":"Coverings","title":"Gluings","text":"","category":"section"},{"location":"AlgebraicGeometry/Schemes/CoveringsAndGluings/","page":"Coverings","title":"Coverings","text":"Gluings 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/CoveringsAndGluings/#Types","page":"Coverings","title":"Types","text":"","category":"section"},{"location":"AlgebraicGeometry/Schemes/CoveringsAndGluings/","page":"Coverings","title":"Coverings","text":"The abstract type of any such gluing is ","category":"page"},{"location":"AlgebraicGeometry/Schemes/CoveringsAndGluings/","page":"Coverings","title":"Coverings","text":"AbsGluing","category":"page"},{"location":"AlgebraicGeometry/Schemes/CoveringsAndGluings/#AbsGluing","page":"Coverings","title":"AbsGluing","text":"AbsGluing\n\nA gluing of two affine schemes X and Y (the patches) along open subsets U in X and V in Y (the gluing_domains) along mutual isomorphisms f U V g (the gluing_morphisms).\n\n\n\n\n\n","category":"type"},{"location":"AlgebraicGeometry/Schemes/CoveringsAndGluings/","page":"Coverings","title":"Coverings","text":"The available concrete types are ","category":"page"},{"location":"AlgebraicGeometry/Schemes/CoveringsAndGluings/","page":"Coverings","title":"Coverings","text":"Gluing\nSimpleGluing","category":"page"},{"location":"AlgebraicGeometry/Schemes/CoveringsAndGluings/#Gluing","page":"Coverings","title":"Gluing","text":"Gluing\n\nConcrete instance of an AbsGluing for gluings of affine schemes X U V Y along open subsets U and V of type AffineSchemeOpenSubscheme.\n\n\n\n\n\n","category":"type"},{"location":"AlgebraicGeometry/Schemes/CoveringsAndGluings/#SimpleGluing","page":"Coverings","title":"SimpleGluing","text":"SimpleGluing\n\nConcrete instance of an AbsGluing for gluings 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/CoveringsAndGluings/#Constructors-2","page":"Coverings","title":"Constructors","text":"","category":"section"},{"location":"AlgebraicGeometry/Schemes/CoveringsAndGluings/","page":"Coverings","title":"Coverings","text":"Gluing(X::AbsAffineScheme, Y::AbsAffineScheme, f::SchemeMor, g::SchemeMor)","category":"page"},{"location":"AlgebraicGeometry/Schemes/CoveringsAndGluings/#Gluing-Tuple{AbsAffineScheme, AbsAffineScheme, SchemeMor, SchemeMor}","page":"Coverings","title":"Gluing","text":"Gluing(X::AbsAffineScheme, Y::AbsAffineScheme, 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 gluing\n\njulia> V2 = PrincipalOpenSubset(U2, u);\n\njulia> f = morphism(V1, V2, [1//x, y//x]); # The gluing isomorphism\n\njulia> g = morphism(V2, V1, [1//u, v//u]); # and its inverse\n\njulia> G = Gluing(U1, U2, f, g) # Construct the gluing\nGluing\n of affine 2-space\n and affine 2-space\nalong the open subsets\n [x, y] AA^2 \\ scheme(x)\n [u, v] AA^2 \\ scheme(u)\ngiven by the pullback function\n u -> 1/x\n v -> y/x\n\njulia> G isa SimpleGluing # Since the gluing domains were `PrincipalOpenSubsets`, this defaults to a `SimpleGluing`\ntrue\n\njulia> # Alternative using AffineSchemeOpenSubschemes as gluing domains:\n\njulia> W1 = AffineSchemeOpenSubscheme(U1, [x]); W2 = AffineSchemeOpenSubscheme(U2, [u]);\n\njulia> h1 = AffineSchemeOpenSubschemeMor(W1, W2, [1//x, y//x]);\n\njulia> h2 = AffineSchemeOpenSubschemeMor(W2, W1, [1//u, v//u]);\n\njulia> H = Gluing(U1, U2, h1, h2)\nGluing\n of affine 2-space\n and affine 2-space\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 affine scheme morphism\n from [x, y] AA^2 \\ scheme(x)\n to [u, v] affine 2-space\n given by the pullback function\n u -> 1/x\n v -> y/x\n\njulia> H isa Gluing\ntrue\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/CoveringsAndGluings/#Attributes-2","page":"Coverings","title":"Attributes","text":"","category":"section"},{"location":"AlgebraicGeometry/Schemes/CoveringsAndGluings/","page":"Coverings","title":"Coverings","text":"patches(G::AbsGluing)\ngluing_domains(G::AbsGluing)\ngluing_morphisms(G::AbsGluing)\ninverse(G::AbsGluing)","category":"page"},{"location":"AlgebraicGeometry/Schemes/CoveringsAndGluings/#patches-Tuple{AbsGluing}","page":"Coverings","title":"patches","text":"patches(G::AbsGluing)\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/CoveringsAndGluings/#gluing_domains-Tuple{AbsGluing}","page":"Coverings","title":"gluing_domains","text":"gluing_domains(G::AbsGluing)\n\nReturn a pair of open subsets U and V of the respective patches of G which are glued by G along the gluing_morphisms of G.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/CoveringsAndGluings/#gluing_morphisms-Tuple{AbsGluing}","page":"Coverings","title":"gluing_morphisms","text":"gluing_morphisms(G::AbsGluing)\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 gluing identification.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/CoveringsAndGluings/#inverse-Tuple{AbsGluing}","page":"Coverings","title":"inverse","text":"inverse(G::AbsGluing)\n\nReturn the gluing H with patches, gluing_domains, and gluing_morphisms in opposite order compared to G.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/CoveringsAndGluings/#Methods-2","page":"Coverings","title":"Methods","text":"","category":"section"},{"location":"AlgebraicGeometry/Schemes/CoveringsAndGluings/","page":"Coverings","title":"Coverings","text":"compose(G::AbsGluing, H::AbsGluing)\nmaximal_extension(G::Gluing)\nrestrict(G::AbsGluing, f::AbsAffineSchemeMor, g::AbsAffineSchemeMor; check::Bool=true)","category":"page"},{"location":"AlgebraicGeometry/Schemes/CoveringsAndGluings/#compose-Tuple{AbsGluing, AbsGluing}","page":"Coverings","title":"compose","text":"compose(G::AbsGluing, H::AbsGluing)\n\nGiven gluings X ↩ U ≅ V ↪ Y and Y ↩ V' ≅ W ↪ Z, return the gluing X ↩ V ∩ V' ↪ Z. \n\nWARNING: In general such a gluing will not provide a separated scheme. Use maximal_extension to extend the gluing.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/CoveringsAndGluings/#maximal_extension-Tuple{Gluing}","page":"Coverings","title":"maximal_extension","text":"maximal_extension(G::Gluing)\n\nGiven a gluing 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/CoveringsAndGluings/#restrict-Tuple{AbsGluing, AbsAffineSchemeMor, AbsAffineSchemeMor}","page":"Coverings","title":"restrict","text":"restrict(G::AbsGluing, f::AbsAffineSchemeMor, g::AbsAffineSchemeMor; check::Bool=true)\n\nGiven a gluing X U V Y and isomorphisms f X X and g Y Y, return the induced gluing of X and Y.\n\n\n\n\n\n","category":"method"},{"location":"InvariantTheory/finite_groups/","page":"Invariants of Finite Groups","title":"Invariants of Finite Groups","text":"CurrentModule = Oscar\nDocTestSetup = Oscar.doctestsetup()","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.\nIf 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 [DK15] and [DJ98] 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 [Kin13].","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-Finite-Groups-are-Given","page":"Invariants of Finite Groups","title":"How Finite 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)\ninvariant_ring(R::MPolyDecRing, G::MatrixGroup)\ninvariant_ring(R::MPolyDecRing, 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\nThe polynomial ring R on which G acts can be supplied as a first argument, in case an existing ring should be used.\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 = cyclotomic_field(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\n of matrix group of degree 3 over K\n\njulia> IRp = invariant_ring(symmetric_group(3))\nInvariant ring\n of Sym(3)\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 = cyclotomic_field(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\n over cyclotomic field of order 3\n\njulia> IR = invariant_ring(G)\nInvariant ring\n of matrix group of degree 3 over K\n\njulia> group(IR)\nMatrix group of degree 3\n over cyclotomic field of order 3\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 K graded by\n x[1] -> [1]\n x[2] -> [1]\n x[3] -> [1]\n\njulia> x = gens(R)\n3-element Vector{MPolyDecRingElem{AbsSimpleNumFieldElem, AbstractAlgebra.Generic.MPoly{AbsSimpleNumFieldElem}}}:\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::FinGroupInvarRing{FldT, GrpT, T}, f::T) where {FldT, GrpT, T <: MPolyRingElem}\n\nreynolds_operator(IR::FinGroupInvarRing{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.FinGroupInvarRing{FldT, GrpT, T}, T}} where {FldT, GrpT, T<:MPolyRingElem}","page":"Invariants of Finite Groups","title":"reynolds_operator","text":"reynolds_operator(IR::FinGroupInvarRing{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 = cyclotomic_field(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\n over cyclotomic field of order 3\n\njulia> IR = invariant_ring(G)\nInvariant ring\n of matrix group of degree 3 over K\n\njulia> R = polynomial_ring(IR)\nMultivariate polynomial ring in 3 variables over K graded by\n x[1] -> [1]\n x[2] -> [1]\n x[3] -> [1]\n\njulia> x = gens(R)\n3-element Vector{MPolyDecRingElem{AbsSimpleNumFieldElem, AbstractAlgebra.Generic.MPoly{AbsSimpleNumFieldElem}}}:\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\n over prime field of characteristic 3\n\njulia> IR = invariant_ring(G)\nInvariant ring\n of matrix group of degree 3 over GF(3)\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{FqFieldElem, FqMPolyRingElem}}:\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.FinGroupInvarRing{FldT, GrpT, T}, T, Oscar.GAPGroupClassFunction}} where {FldT, GrpT, T<:MPolyRingElem}","page":"Invariants of Finite Groups","title":"reynolds_operator","text":"reynolds_operator(IR::FinGroupInvarRing{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 [Sta79]. 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 = cyclotomic_field(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 S2, [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::FinGroupInvarRing, d::Int, algorithm::Symbol = :default)\n\nbasis(IR::FinGroupInvarRing, d::Int, chi::GAPGroupClassFunction)","category":"page"},{"location":"InvariantTheory/finite_groups/#basis","page":"Invariants of Finite Groups","title":"basis","text":"basis(IR::FinGroupInvarRing, 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 = cyclotomic_field(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\n over cyclotomic field of order 3\n\njulia> IR = invariant_ring(G)\nInvariant ring\n of matrix group of degree 3 over K\n\njulia> basis(IR, 6)\n4-element Vector{MPolyDecRingElem{AbsSimpleNumFieldElem, AbstractAlgebra.Generic.MPoly{AbsSimpleNumFieldElem}}}:\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\n over prime field of characteristic 3\n\njulia> IR = invariant_ring(G)\nInvariant ring\n of matrix group of degree 3 over GF(3)\n\njulia> basis(IR, 2)\n2-element Vector{MPolyDecRingElem{FqFieldElem, FqMPolyRingElem}}:\n x[1]^2 + x[2]^2\n x[3]^2\n\njulia> basis(IR, 3)\n2-element Vector{MPolyDecRingElem{FqFieldElem, FqMPolyRingElem}}:\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.FinGroupInvarRing, Int64, Oscar.GAPGroupClassFunction}","page":"Invariants of Finite Groups","title":"basis","text":"basis(IR::FinGroupInvarRing, 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 = cyclotomic_field(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{AbsSimpleNumFieldElem, AbstractAlgebra.Generic.MPoly{AbsSimpleNumFieldElem}}}:\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 ] ), [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::FinGroupInvarRing, d::Int, algorithm::Symbol = :default)\n\niterate_basis(IR::FinGroupInvarRing, d::Int, chi::GAPGroupClassFunction)","category":"page"},{"location":"InvariantTheory/finite_groups/#iterate_basis","page":"Invariants of Finite Groups","title":"iterate_basis","text":"iterate_basis(IR::FinGroupInvarRing, 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 = cyclotomic_field(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\n over cyclotomic field of order 3\n\njulia> IR = invariant_ring(G)\nInvariant ring\n of matrix group of degree 3 over K\n\njulia> B = iterate_basis(IR, 6)\nIterator over a basis of the component of degree 6\n of invariant ring of G\n\njulia> collect(B)\n4-element Vector{MPolyDecRingElem{AbsSimpleNumFieldElem, AbstractAlgebra.Generic.MPoly{AbsSimpleNumFieldElem}}}:\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\n over prime field of characteristic 3\n\njulia> IR = invariant_ring(G)\nInvariant ring\n of matrix group of degree 3 over GF(3)\n\njulia> B = iterate_basis(IR, 2)\nIterator over a basis of the component of degree 2\n of invariant ring of G\n\njulia> collect(B)\n2-element Vector{MPolyDecRingElem{FqFieldElem, FqMPolyRingElem}}:\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.FinGroupInvarRing, Int64, Oscar.GAPGroupClassFunction}","page":"Invariants of Finite Groups","title":"iterate_basis","text":"iterate_basis(IR::FinGroupInvarRing, 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 = cyclotomic_field(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\n of invariant ring of G\nrelative to a character\n\njulia> collect(B)\n4-element Vector{MPolyDecRingElem{AbsSimpleNumFieldElem, AbstractAlgebra.Generic.MPoly{AbsSimpleNumFieldElem}}}:\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 S2, [1, -1])\n\njulia> B = iterate_basis(R, 3, chi)\nIterator over a basis of the component of degree 3\n of invariant ring of S2\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::FinGroupInvarRing, [chi::GAPGroupClassFunction])","category":"page"},{"location":"InvariantTheory/finite_groups/#molien_series-Tuple{PolyRing, Oscar.FinGroupInvarRing, Oscar.GAPGroupClassFunction}","page":"Invariants of Finite Groups","title":"molien_series","text":"molien_series([S::PolyRing], I::FinGroupInvarRing, [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 [Sta79].\n\nExamples\n\njulia> K, a = cyclotomic_field(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 S2, [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::FinGroupInvarRing)","category":"page"},{"location":"InvariantTheory/finite_groups/#primary_invariants-Tuple{Oscar.FinGroupInvarRing}","page":"Invariants of Finite Groups","title":"primary_invariants","text":"primary_invariants(IR::FinGroupInvarRing;\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 [Kem99].\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 cancelation 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 cancelation. However, the default value ensure_minimality = 0 corresponds to no cancelation.\n\nExamples\n\njulia> K, a = cyclotomic_field(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{AbsSimpleNumFieldElem, AbstractAlgebra.Generic.MPoly{AbsSimpleNumFieldElem}}}:\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{AbsSimpleNumFieldElem, AbstractAlgebra.Generic.MPoly{AbsSimpleNumFieldElem}}}:\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::FinGroupInvarRing)","category":"page"},{"location":"InvariantTheory/finite_groups/#secondary_invariants-Tuple{Oscar.FinGroupInvarRing}","page":"Invariants of Finite Groups","title":"secondary_invariants","text":"secondary_invariants(IR::FinGroupInvarRing)\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 [DK15], enhanced by ideas from [Kin07]. In the modular case, Algorithm 3.7.5 in [DK15] is used.\n\nExamples\n\njulia> K, a = cyclotomic_field(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{AbsSimpleNumFieldElem, AbstractAlgebra.Generic.MPoly{AbsSimpleNumFieldElem}}}:\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::FinGroupInvarRing)","category":"page"},{"location":"InvariantTheory/finite_groups/#irreducible_secondary_invariants-Tuple{Oscar.FinGroupInvarRing}","page":"Invariants of Finite Groups","title":"irreducible_secondary_invariants","text":"irreducible_secondary_invariants(IR::FinGroupInvarRing)\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/","page":"Invariants of Finite Groups","title":"Invariants of Finite Groups","text":"module_syzygies(RG::FinGroupInvarRing)","category":"page"},{"location":"InvariantTheory/finite_groups/#module_syzygies-Tuple{Oscar.FinGroupInvarRing}","page":"Invariants of Finite Groups","title":"module_syzygies","text":"module_syzygies(RG::FinGroupInvarRing)\n\nGiven an invariant ring RG over a ring R, compute a presentation of RG as a module over the subalgebra generated by a system of primary invariants. Return a module M over a ring S, a map M \\to R which is onto RG by mapping the generators of M to a system of secondary invariants, and a map S \\to R which is onto the subalgebra generated by the primary invariants.\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::FinGroupInvarRing, 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::FinGroupInvarRing, 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 [Kin13] 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 [DH00] and [Sez02].\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 = cyclotomic_field(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\n over cyclotomic field of order 3\n\njulia> IR = invariant_ring(G)\nInvariant ring\n of matrix group of degree 3 over K\n\njulia> fundamental_invariants(IR)\n4-element Vector{MPolyDecRingElem{AbsSimpleNumFieldElem, AbstractAlgebra.Generic.MPoly{AbsSimpleNumFieldElem}}}:\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 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::FinGroupInvarRing)","category":"page"},{"location":"InvariantTheory/finite_groups/#affine_algebra-Tuple{Oscar.FinGroupInvarRing}","page":"Invariants of Finite Groups","title":"affine_algebra","text":"affine_algebra(IR::FinGroupInvarRing;\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 [KS99], 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 = cyclotomic_field(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\n over cyclotomic field of order 3\n\njulia> IR = invariant_ring(G)\nInvariant ring\n of matrix group of degree 3 over K\n\njulia> affine_algebra(IR)\n(Quotient of multivariate polynomial ring by ideal (9*y1^6 + y1^3*y2^3 - 6*y1^3*y2*y3 + 3*y1^3*y4 - y2*y3*y4 + y3^3 + y4^2), Hom: quotient of multivariate polynomial ring -> graded multivariate polynomial ring)\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::FinGroupInvarRing, chi::GAPGroupClassFunction)","category":"page"},{"location":"InvariantTheory/finite_groups/#semi_invariants-Tuple{Oscar.FinGroupInvarRing, Oscar.GAPGroupClassFunction}","page":"Invariants of Finite Groups","title":"semi_invariants","text":"semi_invariants(IR::FinGroupInvarRing, chi::GAPGroupClassFunction)\nrelative_invariants(IR::FinGroupInvarRing, 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 [Gat96] and [Sta79].\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 S2, [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":"A finite field K is represented as simple extension K = k(alpha) = kx(f), where k can be","category":"page"},{"location":"Nemo/finitefield/","page":"Finite fields","title":"Finite fields","text":"a prime field mathbfF_p (K is then an absolute finite field), or\nan arbitrary finite field k (K is then a relative finite field).","category":"page"},{"location":"Nemo/finitefield/","page":"Finite fields","title":"Finite fields","text":"In both cases, we call k the base field of K, alpha a generator and f the defining polynomial of K.","category":"page"},{"location":"Nemo/finitefield/","page":"Finite fields","title":"Finite fields","text":"Note that all field theoretic properties (like basis, degree or trace) are defined with respect to the base field. Methods with prefix absolute_ return ","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":"finite_field\nGF","category":"page"},{"location":"Nemo/finitefield/#finite_field","page":"Finite fields","title":"finite_field","text":"finite_field(p::IntegerUnion, d::Int, s::VarName = :o; cached::Bool = true, check::Bool = true)\nfinite_field(q::IntegerUnion, s::VarName = :o; cached::Bool = true, check::Bool = true)\nfinite_field(f::FqPolyRingElem, s::VarName = :o; cached::Bool = true, check::Bool = true)\n\nReturn a tuple (K x) of a finite field K of order q = p^d, where p is a prime, and a generator x of K (see gen for a definition). The identifier s is used to designate how the finite field generator will be printed.\n\nIf a polynomial f in kX over a finite field k is specified, the finite field K = kX(f) will be constructed as a finite field with base field k.\n\nSee also GF which only returns K.\n\nExamples\n\njulia> K, a = finite_field(3, 2, \"a\")\n(Finite field of degree 2 and characteristic 3, a)\n\njulia> K, a = finite_field(9, \"a\")\n(Finite field of degree 2 and characteristic 3, a)\n\njulia> Kx, x = K[\"x\"];\n\njulia> L, b = finite_field(x^3 + x^2 + x + 2, \"b\")\n(Finite field of degree 3 over GF(3, 2), b)\n\n\n\n\n\n","category":"function"},{"location":"Nemo/finitefield/#GF","page":"Finite fields","title":"GF","text":"GF(p::IntegerUnion, d::Int, s::VarName = :o; cached::Bool = true, check::Bool = true)\nGF(q::IntegerUnion, s::VarName = :o; cached::Bool = true, check::Bool = true)\nGF(f::FqPolyRingElem, s::VarName = :o; cached::Bool = true, check::Bool = true)\n\nReturn a finite field K of order q = p^d, where p is a prime. The identifier s is used to designate how the finite field generator will be printed.\n\nIf a polynomial f in kX over a finite field k is specified, the finite field K = kX(f) will be constructed as a finite field with base field k.\n\nSee also finite_field which additionally returns a finite field generator of K.\n\nExamples\n\njulia> K = GF(3, 2, \"a\")\nFinite field of degree 2 and characteristic 3\n\njulia> K = GF(9, \"a\")\nFinite field of degree 2 and characteristic 3\n\njulia> Kx, x = K[\"x\"];\n\njulia> L = GF(x^3 + x^2 + x + 2, \"b\")\nFinite field of degree 3 over GF(3, 2)\n\n\n\n\n\n","category":"function"},{"location":"Nemo/finitefield/#Field-functionality","page":"Finite fields","title":"Field functionality","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(K::FqField) -> Int\n\nReturn the degree of the given finite field over the base field.\n\nExamples\n\njulia> K, a = finite_field(3, 2, \"a\");\n\njulia> degree(K)\n2\n\njulia> Kx, x = K[\"x\"];\n\njulia> L, b = finite_field(x^3 + x^2 + x + 2, \"b\");\n\njulia> degree(L)\n3\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], K::FqField)\n\nReturn the defining polynomial of K as a polynomial over the base field of K.\n\nIf the polynomial ring R is specified, the polynomial will be an element of R.\n\nExamples\n\njulia> K, a = finite_field(9, \"a\");\n\njulia> defining_polynomial(K)\nx^2 + 2*x + 2\n\njulia> Ky, y = K[\"y\"];\n\njulia> L, b = finite_field(y^3 + y^2 + y + 2, \"b\");\n\njulia> defining_polynomial(L)\ny^3 + y^2 + y + 2\n\n\n\n\n\n","category":"method"},{"location":"Nemo/finitefield/#Element-functionality","page":"Finite fields","title":"Element functionality","text":"","category":"section"},{"location":"Nemo/finitefield/","page":"Finite fields","title":"Finite fields","text":"gen(::FqField)\nis_gen(::FqFieldElem)\ntr(::FqFieldElem)\nabsolute_tr(::FqFieldElem)\nnorm(::FqFieldElem)\nabsolute_norm(::FqFieldElem)\nlift(::FqPolyRing, ::FqFieldElem)\nlift(::ZZRing, ::FqFieldElem)","category":"page"},{"location":"Nemo/finitefield/#gen-Tuple{FqField}","page":"Finite fields","title":"gen","text":"gen(L::FqField)\n\nReturn a K-algebra generator a of the finite field L, where K is the base field of L. The element a satisfies defining_polyomial(a) == 0.\n\nNote that this is in general not a multiplicative generator and can be zero, if LK is an extension of degree one.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/finitefield/#is_gen-Tuple{FqFieldElem}","page":"Finite fields","title":"is_gen","text":"is_gen(a::FqFieldElem)\n\nReturn true if the given finite field element is the generator of the finite field over its base field, otherwise return false.\n\n\n\n\n\n","category":"method"},{"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":"Nemo/finitefield/#lift-Tuple{ZZRing, FqFieldElem}","page":"Finite fields","title":"lift","text":"lift(::ZZRing, x::FqFieldElem) -> ZZRingElem\n\nGiven an element x of a prime field mathbfF_p, return a preimage under the canonical map mathbfZ to mathbfF_p.\n\nExamples\n\njulia> K = GF(19);\n\njulia> lift(ZZ, K(3))\n3\n\n\n\n\n\n","category":"method"},{"location":"DeveloperDocumentation/printing_details/#Printing-in-OSCAR","page":"Printing in OSCAR","title":"Printing in OSCAR","text":"","category":"section"},{"location":"DeveloperDocumentation/printing_details/","page":"Printing in OSCAR","title":"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":"Printing in OSCAR","title":"Implementing show functions","text":"","category":"section"},{"location":"DeveloperDocumentation/printing_details/","page":"Printing in OSCAR","title":"Printing in OSCAR","text":"Here is the translation between :detail, one line and terse, where io is an IO object (such as stdout or an IOBuffer):","category":"page"},{"location":"DeveloperDocumentation/printing_details/","page":"Printing in OSCAR","title":"Printing in OSCAR","text":"show(io, MIME\"text/plain\"(), x) # detailed printing\nprint(io, x) # one line printing\nprint(terse(io), x) # terse printing","category":"page"},{"location":"DeveloperDocumentation/printing_details/","page":"Printing in OSCAR","title":"Printing in OSCAR","text":"For reference, string interpolation \"$(x)\" uses one line printing via print(io, x), while on the REPL detailed printing is used to show top level objects.","category":"page"},{"location":"DeveloperDocumentation/printing_details/","page":"Printing in OSCAR","title":"Printing in OSCAR","text":"warning: display\nPlease do not use display! From the Julia documentation of display: \"In general, you cannot assume that display output goes to stdout [...]\". In particular, the output of display will not work in the jldoctests.","category":"page"},{"location":"DeveloperDocumentation/printing_details/#Mockup","page":"Printing in OSCAR","title":"Mockup","text":"","category":"section"},{"location":"DeveloperDocumentation/printing_details/#Detailed-printing-with-a-new-line","page":"Printing in OSCAR","title":"Detailed printing with a new line","text":"","category":"section"},{"location":"DeveloperDocumentation/printing_details/","page":"Printing in OSCAR","title":"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":"Printing in OSCAR","title":"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":"Printing in OSCAR","title":"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":"Printing in OSCAR","title":"Printing in OSCAR","text":"The following is a template for one line and terse printing.","category":"page"},{"location":"DeveloperDocumentation/printing_details/","page":"Printing in OSCAR","title":"Printing in OSCAR","text":"function Base.show(io::IO, R::NewRing)\n if is_terse(io)\n # no nested printing\n print(io, \"terse printing of newring \")\n else\n # nested printing allowed, preferably terse\n print(io, \"one line printing of newring with \")\n print(terse(io), \"terse \", base_ring(R))\n end\nend","category":"page"},{"location":"DeveloperDocumentation/printing_details/","page":"Printing in OSCAR","title":"Printing in OSCAR","text":"And this is how it looks like:","category":"page"},{"location":"DeveloperDocumentation/printing_details/","page":"Printing in OSCAR","title":"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 terse QQ\n one line printing of newring with terse QQ\n","category":"page"},{"location":"DeveloperDocumentation/printing_details/#Detailed-printing-in-a-single-line","page":"Printing in OSCAR","title":"Detailed printing in a single line","text":"","category":"section"},{"location":"DeveloperDocumentation/printing_details/","page":"Printing in OSCAR","title":"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 terse printing as well.","category":"page"},{"location":"DeveloperDocumentation/printing_details/","page":"Printing in OSCAR","title":"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 is_terse(io)\n # no nested printing\n print(io, \"terse printing of newring\")\n else\n # nested printing allowed, preferably terse\n print(io, \"I am a new ring and always print in one line \" )\n print(terse(io), base_ring(R))\n end\nend","category":"page"},{"location":"DeveloperDocumentation/printing_details/","page":"Printing in OSCAR","title":"Printing in OSCAR","text":"And this is how it looks like:","category":"page"},{"location":"DeveloperDocumentation/printing_details/","page":"Printing in OSCAR","title":"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(terse(Base.stdout) ,R)\nterse printing of newring","category":"page"},{"location":"DeveloperDocumentation/printing_details/","page":"Printing in OSCAR","title":"Printing in OSCAR","text":"The terse printing uses an IOContext (see IOContext from the Julia documentation) to pass information to other show methods invoked recursively (for example in nested printings). The same mechanism can be used to pass other context data. For instance, this is used by the Scheme code in some nested printings which invoke several objects whose printing depends on a given covering: we use IOContext to pass a fix covering to the printing of each sub-object for consistency and readability.","category":"page"},{"location":"DeveloperDocumentation/printing_details/#The-following-is-not-working-as-expected-and-should-not-be-used","page":"Printing in OSCAR","title":"The following is not working as expected and should not be used","text":"","category":"section"},{"location":"DeveloperDocumentation/printing_details/","page":"Printing in OSCAR","title":"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":"Printing in OSCAR","title":"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":"Printing in OSCAR","title":"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":"Printing in OSCAR","title":"Printing in OSCAR","text":"function Base.show(io::IO, R::NewRing)\n if is_terse(io)\n print(io, \"terse printing of newring\")\n else # this is what we call one line\n print(io, \"one line printing of newring with \")\n print(terse(io), \"terse \", R.base_ring)\n end\nend","category":"page"},{"location":"DeveloperDocumentation/printing_details/","page":"Printing in OSCAR","title":"Printing in OSCAR","text":"This example illustrates the unexpected behavior.","category":"page"},{"location":"DeveloperDocumentation/printing_details/","page":"Printing in OSCAR","title":"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 terse QQ","category":"page"},{"location":"DeveloperDocumentation/printing_details/#Advanced-printing-functionality","page":"Printing in OSCAR","title":"Advanced printing functionality","text":"","category":"section"},{"location":"DeveloperDocumentation/printing_details/","page":"Printing in OSCAR","title":"Printing in OSCAR","text":"To facilitate printing of nested mathematical structures, we provide a modified IOCustom object. To create one, we use the following command:","category":"page"},{"location":"DeveloperDocumentation/printing_details/","page":"Printing in OSCAR","title":"Printing in OSCAR","text":"AbstractAlgebra.pretty(::IO)","category":"page"},{"location":"DeveloperDocumentation/printing_details/#pretty-Tuple{IO}","page":"Printing in OSCAR","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":"method"},{"location":"DeveloperDocumentation/printing_details/","page":"Printing in OSCAR","title":"Printing in OSCAR","text":"The IOCustom object allows one to locally control:","category":"page"},{"location":"DeveloperDocumentation/printing_details/","page":"Printing in OSCAR","title":"Printing in OSCAR","text":"indentation using Indent() and Dedent(),\ncapitalization using Lowercase() and LowercaseOff().","category":"page"},{"location":"DeveloperDocumentation/printing_details/#Example","page":"Printing in OSCAR","title":"Example","text":"","category":"section"},{"location":"DeveloperDocumentation/printing_details/","page":"Printing in OSCAR","title":"Printing in OSCAR","text":"We illustrate this with an example","category":"page"},{"location":"DeveloperDocumentation/printing_details/","page":"Printing in OSCAR","title":"Printing in OSCAR","text":"struct A{T}\n x::T\nend\n\nfunction Base.show(io::IO, a::A)\n io = pretty(io)\n println(io, \"Something of type A\")\n print(io, Indent(), \"over \", Lowercase(), a.x)\n print(io, Dedent()) # don't forget to undo the indentation!\nend\n\nstruct B\nend\n\nfunction Base.show(io::IO, b::B)\n io = pretty(io)\n print(io, LowercaseOff(), \"Hilbert thing\")\nend","category":"page"},{"location":"DeveloperDocumentation/printing_details/","page":"Printing in OSCAR","title":"Printing in OSCAR","text":"At the REPL, this will then be printed as follows:","category":"page"},{"location":"DeveloperDocumentation/printing_details/","page":"Printing in OSCAR","title":"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/","page":"Printing in OSCAR","title":"Printing in OSCAR","text":"Moreover, one can control the pluralization of nouns when printing a set of elements with a variable number of objects. For this, one can use ItemQuantity:","category":"page"},{"location":"DeveloperDocumentation/printing_details/#Example-2","page":"Printing in OSCAR","title":"Example","text":"","category":"section"},{"location":"DeveloperDocumentation/printing_details/","page":"Printing in OSCAR","title":"Printing in OSCAR","text":"We illustrate this with an example","category":"page"},{"location":"DeveloperDocumentation/printing_details/","page":"Printing in OSCAR","title":"Printing in OSCAR","text":"julia> struct C{T}\n x::Vector{T}\n end\n\njulia> function Base.show(io::IO, c::C{T}) where T\n x = c.x\n n = length(x)\n print(io, \"Something with \", ItemQuantity(n, \"element\"), \" of type $T\")\n end","category":"page"},{"location":"DeveloperDocumentation/printing_details/","page":"Printing in OSCAR","title":"Printing in OSCAR","text":"At the REPL, this will then be printed as follows:","category":"page"},{"location":"DeveloperDocumentation/printing_details/","page":"Printing in OSCAR","title":"Printing in OSCAR","text":"julia> C(Int[2,3,4])\nSomething with 3 elements of type Int64\n\njulia> C(Int[])\nSomething with 0 elements of type Int64\n\njulia> C(Int[6])\nSomething with 1 element of type Int64","category":"page"},{"location":"DeveloperDocumentation/printing_details/#LaTeX-and-Unicode-printing","page":"Printing in OSCAR","title":"LaTeX and Unicode printing","text":"","category":"section"},{"location":"DeveloperDocumentation/printing_details/#LaTeX-output","page":"Printing in OSCAR","title":"LaTeX output","text":"","category":"section"},{"location":"DeveloperDocumentation/printing_details/","page":"Printing in OSCAR","title":"Printing in OSCAR","text":"Some types support LaTeX output.","category":"page"},{"location":"DeveloperDocumentation/printing_details/","page":"Printing in OSCAR","title":"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":"Printing in OSCAR","title":"Printing in OSCAR","text":"Base.show(io::IOContext, ::MIME\"text/latex\")","category":"page"},{"location":"DeveloperDocumentation/printing_details/#Unicode-printing","page":"Printing in OSCAR","title":"Unicode printing","text":"","category":"section"},{"location":"DeveloperDocumentation/printing_details/","page":"Printing in OSCAR","title":"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":"Printing in OSCAR","title":"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":"Printing in OSCAR","title":"Printing in OSCAR","text":"Objects may follow the value of Oscar.is_unicode_allowed() at the time of their creation for their printing, i.e. ignore later changes of the setting. This is useful for objects storing a string representation of themselves, e.g. generators of a module.","category":"page"},{"location":"DeveloperDocumentation/printing_details/","page":"Printing in OSCAR","title":"Printing in OSCAR","text":"Here is an example with and without output using Unicode:","category":"page"},{"location":"DeveloperDocumentation/printing_details/","page":"Printing in OSCAR","title":"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":"DeveloperDocumentation/printing_details/#On-using-@show_name,-@show_special,-@show_special_elem","page":"Printing in OSCAR","title":"On using @show_name, @show_special, @show_special_elem","text":"","category":"section"},{"location":"DeveloperDocumentation/printing_details/","page":"Printing in OSCAR","title":"Printing in OSCAR","text":"All show methods for parent objects such as rings or modules should use the @show_name macro. This macro ensures that if the object has a name (including one derived from the name of a Julia REPL variable to which the object is currently assigned) then in a compact or terse io context it is printed using that name. Here is an example illustrating this:\njulia> vector_space(GF(2), 2)\nVector space of dimension 2 over prime field of characteristic 2\n\njulia> K = GF(2)\nFinite field F_2\n\njulia> vector_space(K, 2)\nVector space of dimension 2 over K\nThe documentation for AbstractAlgebra.get_name describes how the name is determined.\nAll show methods for parent objects should also use @show_special. This checks if an attribute :show is present. If so, it has to be a function taking IO, optionally a MIME-type, and the object. This is then called instead of the usual show function.\nSimilarly, all show methods for element objects may use @show_special_elem which checks if an attribute :show_elem is present in the object's parent. The semantics are the same as for @show_special.","category":"page"},{"location":"DeveloperDocumentation/printing_details/","page":"Printing in OSCAR","title":"Printing in OSCAR","text":"For details please consult the Advanced printing section of the AbstractAlgebra documentation.","category":"page"},{"location":"Hecke/manual/abelian/elements/","page":"Elements","title":"Elements","text":"CurrentModule = Hecke\nDocTestSetup = quote\n using Hecke\nend","category":"page"},{"location":"Hecke/manual/abelian/elements/#Elements","page":"Elements","title":"Elements","text":"","category":"section"},{"location":"Hecke/manual/abelian/elements/","page":"Elements","title":"Elements","text":"Elements in a finitely generated abelian group are of type FinGenAbGroupElem 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/manual/abelian/elements/#Creation","page":"Elements","title":"Creation","text":"","category":"section"},{"location":"Hecke/manual/abelian/elements/","page":"Elements","title":"Elements","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/manual/abelian/elements/","page":"Elements","title":"Elements","text":"gens(G::FinGenAbGroup)\nFinGenAbGroup(x::Vector{ZZRingElem})\nFinGenAbGroup(x::ZZMatrix)\ngetindex(A::FinGenAbGroup, i::Int)\nrand(G::FinGenAbGroup)\nrand(G::FinGenAbGroup, B::ZZRingElem)\nparent(x::FinGenAbGroupElem)","category":"page"},{"location":"Hecke/manual/abelian/elements/#gens-Tuple{FinGenAbGroup}","page":"Elements","title":"gens","text":"gens(G::FinGenAbGroup) -> Vector{FinGenAbGroupElem}\n\nThe sequence of generators of G.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/abelian/elements/#FinGenAbGroup-Tuple{Vector{ZZRingElem}}","page":"Elements","title":"FinGenAbGroup","text":"(A::FinGenAbGroup)(x::Vector{ZZRingElem}) -> FinGenAbGroupElem\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/manual/abelian/elements/#FinGenAbGroup-Tuple{ZZMatrix}","page":"Elements","title":"FinGenAbGroup","text":"(A::FinGenAbGroup)(x::ZZMatrix) -> FinGenAbGroupElem\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/manual/abelian/elements/#getindex-Tuple{FinGenAbGroup, Int64}","page":"Elements","title":"getindex","text":"getindex(A::FinGenAbGroup, i::Int) -> FinGenAbGroupElem\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/manual/abelian/elements/#rand-Tuple{FinGenAbGroup}","page":"Elements","title":"rand","text":"rand(G::FinGenAbGroup) -> FinGenAbGroupElem\n\nReturns an element of G chosen uniformly at random.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/abelian/elements/#rand-Tuple{FinGenAbGroup, ZZRingElem}","page":"Elements","title":"rand","text":"rand(G::FinGenAbGroup, B::ZZRingElem) -> FinGenAbGroupElem\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/manual/abelian/elements/#parent-Tuple{FinGenAbGroupElem}","page":"Elements","title":"parent","text":"parent(x::FinGenAbGroupElem) -> FinGenAbGroup\n\nReturns the parent of x.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/abelian/elements/#Access","page":"Elements","title":"Access","text":"","category":"section"},{"location":"Hecke/manual/abelian/elements/","page":"Elements","title":"Elements","text":"getindex(x::FinGenAbGroupElem, v::AbstractVector{Int})\ngetindex(x::FinGenAbGroupElem, i::Int)","category":"page"},{"location":"Hecke/manual/abelian/elements/#getindex-Tuple{FinGenAbGroupElem, AbstractVector{Int64}}","page":"Elements","title":"getindex","text":"getindex(x::FinGenAbGroupElem, v::AbstractVector{Int}) -> Vector{ZZRingElem}\n\nReturns the i-th components of the element x where i in v.\n\nnote: Note\nThis function is inefficient since the elements are internally stored using ZZMatrix but this function outputs a vector.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/abelian/elements/#getindex-Tuple{FinGenAbGroupElem, Int64}","page":"Elements","title":"getindex","text":"getindex(x::FinGenAbGroupElem, i::Int) -> ZZRingElem\n\nReturns the i-th component of the element x.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/abelian/elements/#Predicates","page":"Elements","title":"Predicates","text":"","category":"section"},{"location":"Hecke/manual/abelian/elements/","page":"Elements","title":"Elements","text":"We have the standard predicates iszero, isone and is_identity to test an element for being trivial.","category":"page"},{"location":"Hecke/manual/abelian/elements/#Invariants","page":"Elements","title":"Invariants","text":"","category":"section"},{"location":"Hecke/manual/abelian/elements/","page":"Elements","title":"Elements","text":"order(A::FinGenAbGroupElem)","category":"page"},{"location":"Hecke/manual/abelian/elements/#order-Tuple{FinGenAbGroupElem}","page":"Elements","title":"order","text":"order(A::FinGenAbGroupElem) -> 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/manual/abelian/elements/#Iterator","page":"Elements","title":"Iterator","text":"","category":"section"},{"location":"Hecke/manual/abelian/elements/","page":"Elements","title":"Elements","text":"One can iterate over the elements of a finite abelian group.","category":"page"},{"location":"Hecke/manual/abelian/elements/","page":"Elements","title":"Elements","text":"using Hecke # hide\nG = abelian_group(ZZRingElem[1 2; 3 4])\nfor g = G\n println(g)\nend","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::AbsAffineScheme{<: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)\nintersect(::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(intersect(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) -> AbsAffineScheme\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) -> AbsAffineScheme\n\nReturn the underlying reduced scheme defining X.\n\nThis is used to forward the AbsAffineScheme 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 <: AbsAffineScheme\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{<:MPolyRingElem}; check::Bool=true)\nalgebraic_set(f::MPolyRingElem; 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::AffineScheme; check::Bool=true)","category":"page"},{"location":"AlgebraicGeometry/AlgebraicSets/AffineAlgebraicSet/#algebraic_set-Tuple{AffineScheme}","page":"Affine Algebraic Sets","title":"algebraic_set","text":"algebraic_set(X::AffineScheme; 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 x, y\n over rational field\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 = Oscar.doctestsetup()","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 [Lev05]).","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 modeled 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 defined by a julia-function with inverse\n from pBW-algebra over Rational field in x, y, z with relations y*x = -x*y, z*x = -x*z, z*y = -y*z\n 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)\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(::Ring, ::Vector{Symbol})","category":"page"},{"location":"NoncommutativeAlgebra/PBWAlgebras/quotients/#exterior_algebra-Tuple{Ring, Vector{Symbol}}","page":"GR-Algebras: Quotients of PBW-Algebras","title":"exterior_algebra","text":"exterior_algebra(K::Ring, nvars::Int)\nexterior_algebra(K::Ring, varnames::AbstractVector{<:VarName})\n\nGiven a coefficient ring K and variable names, say varnames = [:x1, :x2, ...], return a tuple E, [x1, x2, ...] consisting of the exterior algebra E over the polynomial ring R[x1, x2, ...] and its generators x1, x2, ....\n\nIf K is a field, this function will use a special implementation in Singular.\n\nnote: Note\nCreating an exterior_algebra with many variables will create an object occupying a lot of memory (probably cubic in nvars).\n\nExamples\n\njulia> E, (x1,x2) = exterior_algebra(QQ, 2);\n\njulia> x2*x1\n-x1*x2\n\njulia> (x1+x2)^2 # over fields, result is automatically reduced!\n0\n\njulia> E, (x,y) = exterior_algebra(QQ, [\"x\",\"y\"]);\n\njulia> y*x\n-x*y\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"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,\nnumber_of_generators(Q) / ngens(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> number_of_generators(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 = Oscar.doctestsetup()","category":"page"},{"location":"LinearAlgebra/intro/#linear_algebra","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 types for matrix spaces and their elements:","category":"page"},{"location":"AbstractAlgebra/matrix_interface/","page":"Matrix Interface","title":"Matrix Interface","text":"MatSpace{T} is the concrete 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":"MatRing{T} is the abstract type for matrix algebra parent types\nMatRingElem{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 either making them struct types, or 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":"number_of_rows(M::MyMatSpace{T}) where T <: RingElem\nnumber_of_rows(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":"number_of_columns(M:MyMatSpace{T}) where T <: RingElem\nnumber_of_columns(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":"number_of_rows(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":"number_of_columns(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.MatRingElem 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 = Oscar.doctestsetup()","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(::Oscar.scalar_type_or_field, A::AnyVecOrMat, b::AbstractVector)\npolyhedron(::Oscar.scalar_type_or_field, I::Union{Nothing, AbstractCollection[AffineHalfspace]}, E::Union{Nothing, AbstractCollection[AffineHyperplane]} = nothing)","category":"page"},{"location":"PolyhedralGeometry/Polyhedra/constructions/#polyhedron-Tuple{Union{Field, Type{<:Union{Float64, FieldElem}}}, Union{MatElem, AbstractVecOrMat}, AbstractVector}","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 [JT13]\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","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":"function"},{"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_1 <= 0\nx_1 <= 1\n\n\njulia> affine_hull(P)\n1-element SubObjectIterator{AffineHyperplane{QQFieldElem}} over the hyperplanes of R^2 described by:\nx_2 = 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(::Oscar.scalar_type_or_field, ::AnyVecOrMat; non_redundant::Bool=false)","category":"page"},{"location":"PolyhedralGeometry/Polyhedra/constructions/#convex_hull-Tuple{Union{Field, Type{<:Union{Float64, FieldElem}}}, Union{MatElem, AbstractVecOrMat}}","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 [JT13].\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)\nPolytope in ambient dimension 7\n\njulia> facets(s)\n8-element SubObjectIterator{AffineHalfspace{QQFieldElem}} over the halfspaces of R^7 described by:\n-x_1 <= 0\n-x_2 <= 0\n-x_3 <= 0\n-x_4 <= 0\n-x_5 <= 0\n-x_6 <= 0\n-x_7 <= 0\nx_1 + x_2 + x_3 + x_4 + x_5 + x_6 + x_7 <= 1\n\njulia> t = simplex(7, 5)\nPolytope in ambient dimension 7\n\njulia> facets(t)\n8-element SubObjectIterator{AffineHalfspace{QQFieldElem}} over the halfspaces of R^7 described by:\n-x_1 <= 0\n-x_2 <= 0\n-x_3 <= 0\n-x_4 <= 0\n-x_5 <= 0\n-x_6 <= 0\n-x_7 <= 0\nx_1 + x_2 + x_3 + x_4 + x_5 + x_6 + x_7 <= 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)\nPolytope in ambient dimension 3\n\njulia> facets(C)\n8-element SubObjectIterator{AffineHalfspace{QQFieldElem}} over the halfspaces of R^3 described by:\nx_1 + x_2 + x_3 <= 1\n-x_1 + x_2 + x_3 <= 1\nx_1 - x_2 + x_3 <= 1\n-x_1 - x_2 + x_3 <= 1\nx_1 + x_2 - x_3 <= 1\n-x_1 + x_2 - x_3 <= 1\nx_1 - x_2 - x_3 <= 1\n-x_1 - x_2 - x_3 <= 1\n\njulia> D = cross_polytope(3, 2)\nPolytope in ambient dimension 3\n\njulia> facets(D)\n8-element SubObjectIterator{AffineHalfspace{QQFieldElem}} over the halfspaces of R^3 described by:\nx_1 + x_2 + x_3 <= 2\n-x_1 + x_2 + x_3 <= 2\nx_1 - x_2 + x_3 <= 2\n-x_1 - x_2 + x_3 <= 2\nx_1 + x_2 - x_3 <= 2\n-x_1 + x_2 - x_3 <= 2\nx_1 - x_2 - x_3 <= 2\n-x_1 - x_2 - x_3 <= 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\nSee also is_platonic_solid.\n\nArguments\n\ns::String: The name of the desired Platonic 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\")\nPolytope in ambient dimension 3 with EmbeddedAbsSimpleNumFieldElem type coefficients\n\njulia> n_facets(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.\n\nSee also is_archimedean_solid.\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. 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. This is a chiral polytope.\n\nExamples\n\njulia> T = archimedean_solid(\"cuboctahedron\")\nPolytope in ambient dimension 3\n\njulia> sum([n_vertices(F) for F in faces(T, 2)] .== 3)\n8\n\njulia> sum([n_vertices(F) for F in faces(T, 2)] .== 4)\n6\n\njulia> n_facets(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. See the Polytope Wiki\n\nSee also is_johnson_solid.\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.\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.\n\"pentagonal_hexecontahedron\" : Pentagonal hexecontahedron. Dual polytope to the snub dodecahedron, made of 60 irregular pentagonal facets.\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 -> n_vertices(F) == 3, faces(T, 2))\n12\n\njulia> n_facets(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/","page":"Constructions","title":"Constructions","text":"Like some of the Johnson solids, the following four Archimedean and Catalan solids are constructed using serialized data. In order to properly document the respective sources, they also come as seperate functions. ","category":"page"},{"location":"PolyhedralGeometry/Polyhedra/constructions/","page":"Constructions","title":"Constructions","text":"snub_cube\nsnub_dodecahedron\npentagonal_icositetrahedron\npentagonal_hexecontahedron","category":"page"},{"location":"PolyhedralGeometry/Polyhedra/constructions/#snub_cube","page":"Constructions","title":"snub_cube","text":" snub_cube()\n\nConstruct the snub cube, an Archimedean solid. See the Polytope Wiki\n\nSee also archimedean_solid.\n\n\n\n\n\n","category":"function"},{"location":"PolyhedralGeometry/Polyhedra/constructions/#snub_dodecahedron","page":"Constructions","title":"snub_dodecahedron","text":" snub_dodecahedron()\n\nConstruct the snub dodecahedron, an Archimedean solid. See the Polytope Wiki\n\nSee also archimedean_solid.\n\n\n\n\n\n","category":"function"},{"location":"PolyhedralGeometry/Polyhedra/constructions/#pentagonal_icositetrahedron","page":"Constructions","title":"pentagonal_icositetrahedron","text":" pentagonal_icositetrahedron()\n\nConstruct the pentagonal icositetrahedron, a Catalan solid. See the Wikipedia entry\n\nSee also catalan_solid.\n\n\n\n\n\n","category":"function"},{"location":"PolyhedralGeometry/Polyhedra/constructions/#pentagonal_hexecontahedron","page":"Constructions","title":"pentagonal_hexecontahedron","text":" pentagonal_hexecontahedron()\n\nConstruct the pentagonal hexecontahedron, a Catalan solid. See the Visual Polyhedra entry\n\nSee also catalan_solid.\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":"SIM_body_polytope\nassociahedron\nbillera_lee_polytope\nbinary_markov_graph_polytope\nbirkhoff_polytope\ncyclic_caratheodory_polytope\ncyclic_polytope\ndel_pezzo_polytope\ndwarfed_cube\ndwarfed_product_polygons\nexplicit_zonotope\nfano_simplex\nfractional_cut_polytope\nfractional_knapsack_polytope\nfractional_matching_polytope\ngelfand_tsetlin_polytope\ngoldfarb_cube\ngoldfarb_sit_cube\nhypersimplex\nhypertruncated_cube\nk_cyclic_polytope\nklee_minty_cube\nlecture_hall_simplex\nmax_GC_rank_polytope\nn_gon\nnewton_polytope\norbit_polytope\npermutahedron\npile_polytope\npitman_stanley_polytope\nperles_nonrational_8_polytope\npseudo_del_pezzo_polytope\nrand01_polytope\nrand_box_polytope\nrand_cyclic_polytope\nrand_metric\nrand_metric_int\nrand_normal_polytope\nrand_spherical_polytope\nrand_subpolytope\nrss_associahedron\nsigned_permutahedron\nstable_set_polytope\ntransportation_polytope\nzonotope\nzonotope_vertices_fukuda_matrix","category":"page"},{"location":"PolyhedralGeometry/Polyhedra/constructions/#SIM_body_polytope","page":"Constructions","title":"SIM_body_polytope","text":"SIM_body_polytope(alpha::AbstractVector)\n\nProduce an n-dimensional SIM-body as generalized permutahedron in (n+1)-space. SIM-bodies are defined in [GK14], but the input needs to be descending instead of ascending, as used in [JKS22], i.e. alpha has parameters (a_1dotsa_n) such that a_1 geq dots geq a_n geq 0. \n\nExample\n\nTo produce a 2-dimensional SIM-body, use for example the following code. Note that the polytope lives in 3-space, so we project it down to 2-space by eliminating the last coordinate. \n\njulia> s = SIM_body_polytope([3,1])\nPolyhedron in ambient dimension 3\n\njulia> p = convex_hull(map(x->x[1:dim(s)],vertices(s)))\nPolyhedron in ambient dimension 2\n\njulia> vertices(p) \n5-element SubObjectIterator{PointVector{QQFieldElem}}:\n [0, 0]\n [3, 0]\n [3, 1]\n [0, 3]\n [1, 3]\n\n\n\n\n\n","category":"function"},{"location":"PolyhedralGeometry/Polyhedra/constructions/#associahedron","page":"Constructions","title":"associahedron","text":"associahedron(d::Int)\n\nProduce a d-dimensional associahedron (or Stasheff polytope). We use the facet description given in section 9.2. of [Zie95].\n\nNote that in polymake, this function has an optional Boolean parameter group, to also construct the symmetry group of the polytope. For details, see [CSZ15].\n\nExample\n\nProduce the 2-dimensional associahedron is a polygon in mathbbR⁴ having 5 vertices and 5 facets.\n\njulia> A = associahedron(2)\nPolyhedron in ambient dimension 4\n\njulia> vertices(A)\n5-element SubObjectIterator{PointVector{QQFieldElem}}:\n [9, 4, 1, 10]\n [10, 1, 4, 9]\n [1, 10, 1, 9]\n [1, 4, 9, 6]\n [4, 1, 10, 6]\n\njulia> facets(A)\n5-element SubObjectIterator{AffineHalfspace{QQFieldElem}} over the halfspaces of R^4 described by:\n-x_1 <= -1\n-2*x_1 - 2*x_2 <= -10\n-x_2 <= -1\n-2*x_2 - 2*x_3 <= -10\n-x_3 <= -1\n\n\n\n\n\n","category":"function"},{"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\n[BL81]\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/#binary_markov_graph_polytope","page":"Constructions","title":"binary_markov_graph_polytope","text":"binary_markov_graph_polytope(observation::AbstractVector)\n\nDefines a very simple graph for a polytope propagation related to a Hidden Markov Model. The length of observation is the number of possible oberservations. Its elements are of types Bool or Int. The propagated polytope is always a polygon. For a detailed description see [Jos05].\n\nExamples\n\njulia> P = binary_markov_graph_polytope([1,1,1,1])\nPolyhedron in ambient dimension 2\n\njulia> vertices(P)\n4-element SubObjectIterator{PointVector{QQFieldElem}}:\n [3, 0]\n [1, 1]\n [0, 2]\n [0, 7]\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)\nPolytope 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_caratheodory_polytope","page":"Constructions","title":"cyclic_caratheodory_polytope","text":"cyclic_caratheodory_polytope(d::Int, n::Int)\n\nProduce a d-dimensional cyclic polytope with n points. Clearly ngeq d is required. It is a prototypical example of a neighborly polytope whose combinatorics completely known due to Gale's evenness criterion. The coordinates are chosen on the trigonometric moment curve.\n\nExample\n\njulia> C= cyclic_caratheodory_polytope(4,5)\nPolytope in ambient dimension 4\n\njulia> vertices(C)\n5-element SubObjectIterator{PointVector{QQFieldElem}}:\n [1, 0, 1, 0]\n [347922205179541//1125899906842624, 8566355544790271//9007199254740992, -7286977268806823//9007199254740992, 5294298886396511//9007199254740992]\n [-7286977268806823//9007199254740992, 5294298886396511//9007199254740992, 1391688820718163//4503599627370496, -33462326346837//35184372088832]\n [-7286977268806825//9007199254740992, -5294298886396509//9007199254740992, 5566755282872661//18014398509481984, 8566355544790271//9007199254740992]\n [1391688820718163//4503599627370496, -33462326346837//35184372088832, -3643488634403413//4503599627370496, -5294298886396507//9007199254740992]\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)\nPolytope in ambient dimension 3\n\njulia> n_vertices(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)\nPolytope 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/#dwarfed_cube","page":"Constructions","title":"dwarfed_cube","text":"dwarfed_cube(d::Int)\n\nProduce the d-dimensional dwarfed cube as defined in [ABS97]. \n\nExample\n\nThe 3-dimensional dwarfed cube is illustrated in [Jos03].\n\njulia> c = dwarfed_cube(3)\nPolytope in ambient dimension 3\n\njulia> vertices(c)\n10-element SubObjectIterator{PointVector{QQFieldElem}}:\n [1//2, 0, 1]\n [1//2, 1, 0]\n [1, 0, 1//2]\n [1, 1//2, 0]\n [1, 0, 0]\n [0, 0, 0]\n [0, 1, 0]\n [0, 1//2, 1]\n [0, 0, 1]\n [0, 1, 1//2]\n\n\n\n\n\n","category":"function"},{"location":"PolyhedralGeometry/Polyhedra/constructions/#dwarfed_product_polygons","page":"Constructions","title":"dwarfed_product_polygons","text":"dwarfed_product_polygons(d::Int, s::Int)\n\nProduce a d-dimensional dwarfed product of polygons of size s as defined in [ABS97]. It must be dgeq4 and even as well as sgeq 3.\n\nExample\n\njulia> p = dwarfed_product_polygons(4,3)\nPolytope in ambient dimension 4\n\njulia> vertices(p)\n11-element SubObjectIterator{PointVector{QQFieldElem}}:\n [5, 3, 0, 0]\n [5, 0, 0, 0]\n [2, 0, 3, 9]\n [0, 0, 5, 3]\n [0, 0, 3, 9]\n [2, 6, 3, 9]\n [0, 0, 5, 0]\n [0, 0, 0, 0]\n [3, 9, 2, 6]\n [3, 9, 2, 0]\n [3, 9, 0, 0]\n\n\n\n\n\n","category":"function"},{"location":"PolyhedralGeometry/Polyhedra/constructions/#explicit_zonotope","page":"Constructions","title":"explicit_zonotope","text":"explicit_zonotope(zones::Matrix; rows_are_points::Bool=true)\n\nProduce the points of a zonotope as the iterated Minkowski sum of all intervals -xx, where x ranges over the rows of the input matrix zones. If rows_are_points is true (default), the rows of the input matrix represent affine points, otherwise they represent linear vectors.\n\nExamples\n\njulia> Z = explicit_zonotope([1 1; 1 -1], rows_are_points=false)\nPolyhedron in ambient dimension 2\n\njulia> vertices(Z)\n4-element SubObjectIterator{PointVector{QQFieldElem}}:\n [2, 0]\n [0, -2]\n [0, 2]\n [-2, 0]\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\nKeywords\n\nd::Int: the dimension.\n\nExamples\n\njulia> S = fano_simplex(3)\nPolytope 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)\nPolytope in ambient dimension 6\n\n\n\n\n\n","category":"function"},{"location":"PolyhedralGeometry/Polyhedra/constructions/#fractional_knapsack_polytope","page":"Constructions","title":"fractional_knapsack_polytope","text":"fractional_knapsack_polytope(b::AbstractVector{<:Base.Number})\n\nProduce a knapsack polytope defined by one linear inequality (and non-negativity constraints).\n\nExample\n\njulia> f = fractional_knapsack_polytope([10,-2,-3,-5])\nPolytope in ambient dimension 3\n\njulia> print_constraints(f)\n2*x_1 + 3*x_2 + 5*x_3 <= 10\n-x_1 <= 0\n-x_2 <= 0\n-x_3 <= 0\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)\nPolytope 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\n[PS09]\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/#goldfarb_cube","page":"Constructions","title":"goldfarb_cube","text":"goldfarb_cube(d::Int, e::Number, g::Number)\n\nProduce a d-dimensional Goldfarb cube. The first parameter of deformation e must be frac12, the second parameter of deformation d must be geq fractexttte4. \n\nThe Goldfarb cube is a combinatorial cube and yields a bad example for the Simplex Algorithm using the Shadow Vertex Pivoting Strategy. Here we use the description as a deformed product due to [AZ99]. For g=0 we obtain a Klee-Minty cube, in particular for e=g=0 we obtain the standard cube. \n\nExample\n\nThe following produces a 3-dimensional Klee-Minty cube for e=frac13.\n\njulia> c = goldfarb_cube(3,1//3,0)\nPolytope in ambient dimension 3\n\njulia> vertices(c)\n8-element SubObjectIterator{PointVector{QQFieldElem}}:\n [1, 1//3, 8//9]\n [1, 2//3, 7//9]\n [1, 2//3, 2//9]\n [1, 1//3, 1//9]\n [0, 0, 0]\n [0, 1, 1//3]\n [0, 1, 2//3]\n [0, 0, 1]\n\n\n\n\n\n","category":"function"},{"location":"PolyhedralGeometry/Polyhedra/constructions/#goldfarb_sit_cube","page":"Constructions","title":"goldfarb_sit_cube","text":"goldfarb_sit_cube(d::Int, eps::Number, delta::Number)\n\nProduces a d-dimensional variation of the Klee-Minty cube, which is scaled in direction x_d-i by eps*delta^i. The first parameter of deformation eps must be frac12, the second parameter of deformation delta must be geq frac12. This cube is a combinatorial cube and yields a bad example for the Simplex Algorithm using the Steepest Edge Pivoting Strategy. Here we use a scaled description of the construction of Goldfarb and Sit, see [GS79].\n\nExamples\n\njulia> c = goldfarb_sit_cube(3,1//3,1//2)\nPolytope in ambient dimension 3\n\njulia> vertices(c) \n8-element SubObjectIterator{PointVector{QQFieldElem}}:\n [1//36, 1//18, 8//9]\n [1//36, 1//9, 7//9]\n [1//36, 1//9, 2//9]\n [1//36, 1//18, 1//9]\n [0, 0, 0]\n [0, 1//6, 1//3]\n [0, 1//6, 2//3]\n [0, 0, 1]\n\n\n\n\n\n","category":"function"},{"location":"PolyhedralGeometry/Polyhedra/constructions/#hypersimplex","page":"Constructions","title":"hypersimplex","text":"hypersimplex(k::Int, d::Int; no_vertices::Bool=false, no_facets::Bool=false, no_vif::Bool=false)\n\nProduce the hypersimplex Delta(kd), that is the the convex hull of all 01-vector in mathbbR^d with exactly k ones. Note that the output is never full-dimensional.\n\nOptional Arguments\n\nno_vertices::Bool: If set equal to true, vertices of the underlying polymake object are not computed.\nno_facets::Bool: If set equal to true, facets of the underlying polymake object are not computed.\nno_vif::Bool: If set equal to true, vertices in facets of the underlying polymake object are not computed.\n\nExample\n\njulia> H = hypersimplex(3,4)\nPolytope in ambient dimension 4\n\njulia> G = hypersimplex(3,4,no_facets=true)\nPolytope in ambient dimension 4\n\njulia> facets(G)\n4-element SubObjectIterator{AffineHalfspace{QQFieldElem}} over the halfspaces of R^4 described by:\nx_4 <= 1\nx_3 <= 1\n-x_1 - x_3 - x_4 <= -2\nx_1 <= 1\n\njulia> facets(H)\n4-element SubObjectIterator{AffineHalfspace{QQFieldElem}} over the halfspaces of R^4 described by:\nx_4 <= 1\nx_3 <= 1\n-x_1 - x_3 - x_4 <= -2\nx_1 <= 1\n\n\n\n\n\n","category":"function"},{"location":"PolyhedralGeometry/Polyhedra/constructions/#hypertruncated_cube","page":"Constructions","title":"hypertruncated_cube","text":"hypertruncated_cube(d::Int, k::Number, lambda::Number)\n\nProduce a d-dimensional hypertruncated cube with symmetric linear objective function (111).\n\nArguments\n\nk: cutoff parameter\nlambda: scaling of extra vertex\n\nExample\n\njulia> H = hypertruncated_cube(3,2,3)\nPolytope in ambient dimension 3\n\njulia> print_constraints(H)\n-x_1 <= 0\n-x_2 <= 0\n-x_3 <= 0\nx_1 <= 1\nx_2 <= 1\nx_3 <= 1\n5*x_1 - 2*x_2 - 2*x_3 <= 3\n-2*x_1 + 5*x_2 - 2*x_3 <= 3\n-2*x_1 - 2*x_2 + 5*x_3 <= 3\n\n\n\n\n\n","category":"function"},{"location":"PolyhedralGeometry/Polyhedra/constructions/#k_cyclic_polytope","page":"Constructions","title":"k_cyclic_polytope","text":"k_cyclic_polytope(n::Int, s::Vector)\n\nProduce a (rounded) 2*k-dimensional k-cyclic polytope with n points, where k is the length of the input vector s. Special cases are the bicyclic (k=2) and tricyclic (k=3) polytopes. Only possible in even dimensions. \n\nThe parameters texttts_i can be integers, floating-points or rational numbers. The i-th vertex then is: (cos(texttts_1 * 2pi itextttn) sin(texttts_1 * 2pi itextttn) cos(texttts_k * 2pi itextttn) sin(texttts_k * 2pi itextttn)).\n\nWarning: Some of the k-cyclic polytopes are not simplicial. Since the components are rounded, this function might output a polytope which is not a k-cyclic polytope! More information see [Sch95].\n\nExample\n\nTo produce a (not exactly) regular pentagon, type this:\n\njulia> p = k_cyclic_polytope(5,[1])\nPolytope in ambient dimension 2\n\njulia> dim(p) \n2\n\njulia> n_vertices(p)\n5\n\n\n\n\n\n","category":"function"},{"location":"PolyhedralGeometry/Polyhedra/constructions/#klee_minty_cube","page":"Constructions","title":"klee_minty_cube","text":"klee_minty_cube(d::Int, e::Number)\n\nProduces a d-dimensional Klee-Minty-cube if texttte 12. Uses the goldfarb_cube method with the argument textttg = 0.\n\n#Example\n\njulia> k = klee_minty_cube(3,1//8)\nPolytope in ambient dimension 3\n\njulia> print_constraints(k)\n-x_1 <= 0\nx_1 <= 1\n1//8*x_1 - x_2 <= 0\n1//8*x_1 + x_2 <= 1\n1//8*x_2 - x_3 <= 0\n1//8*x_2 + x_3 <= 1\n\n\n\n\n\n","category":"function"},{"location":"PolyhedralGeometry/Polyhedra/constructions/#lecture_hall_simplex","page":"Constructions","title":"lecture_hall_simplex","text":"lecture_hall_simplex(d::Int)\n\nProduce the d-dimensional lecture hall simplex for the sequence (s_i)=i for 1geq i geq d as defined in [SS12].\n\nNote that in polymake, this function has an optional Boolean parameter group, to also construct the symmetry group of the simplex. \n\nExample\n\nThe 3-dimensional lecture hall simplex:\n\njulia> S = lecture_hall_simplex(3) \nPolytope in ambient dimension 3\n\njulia> vertices(S)\n4-element SubObjectIterator{PointVector{QQFieldElem}}:\n [0, 0, 0]\n [0, 0, 3]\n [0, 2, 3]\n [1, 2, 3]\n\n\n\n\n\n","category":"function"},{"location":"PolyhedralGeometry/Polyhedra/constructions/#max_GC_rank_polytope","page":"Constructions","title":"max_GC_rank_polytope","text":"max_GC_rank_polytope(d::Int)\n\nProduce a d-dimensional polytope of maximal Gomory-Chvatal rank Omega(dlog(d)), integrally infeasible. With symmetric linear objective function (111). Construction due to Pokutta and Schulz, see [PS11].\n\nExample\n\njulia> c = max_GC_rank_polytope(3)\nPolytope in ambient dimension 3\n\njulia> vertices(c)\n6-element SubObjectIterator{PointVector{QQFieldElem}}:\n [0, 1//2, 1//2]\n [1//2, 0, 1//2]\n [1//2, 1//2, 0]\n [1//2, 1, 1//2]\n [1//2, 1//2, 1]\n [1, 1//2, 1//2]\n\n\n\n\n\n","category":"function"},{"location":"PolyhedralGeometry/Polyhedra/constructions/#n_gon","page":"Constructions","title":"n_gon","text":"n_gon(n::Int; r::RationalUnion=1, alpha_0::RationalUnion=0)\n\nProduce a regular n-gon. All vertices lie on a circle of radius r (defaults to 1) and initial angle divided by pi alpha_0 (defaults to 0).\n\nExamples\n\nTo store the regular pentagon in the variable p, do this:\n\njulia> p = n_gon(3)\nPolytope in ambient dimension 2 with QQBarFieldElem type coefficients\n\njulia> volume(n_gon(4, r=2, alpha_0=1//4))\nRoot 8.00000 of x - 8\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/#permutahedron","page":"Constructions","title":"permutahedron","text":"permutahedron(d::Int)\n\nProduce a d-dimensional permutahedron. The vertices correspond to the elements of the symmetric group of degree d+1.\n\n#Example\n\njulia> p = permutahedron(2)\nPolytope 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/#pile_polytope","page":"Constructions","title":"pile_polytope","text":"pile_polytope(sizes::Vector{Int})\n\nProduce a (d+1)-dimensional polytope from a pile of cubes. Start with a d-dimensional pile of cubes. Take a generic convex function to lift this polytopal complex to the boundary of a (d+1)–polytope. The argument sizes is a vector (s_1s_d) where s_i specifies the number of boxes in the i-th dimension.\n\n\n\n\n\n","category":"function"},{"location":"PolyhedralGeometry/Polyhedra/constructions/#pitman_stanley_polytope","page":"Constructions","title":"pitman_stanley_polytope","text":"pitman_stanley_polytope(y::AbstractVector)\n\nProduce a Pitman-Stanley polytope of dimension n-1, where y is a Vector of n positive parameters. Does not check if the parameters are actually positive; negative values are legal but that do not yield a Pitman-Stanley polytope. Zeros just reduce the dimension; negative numbers may produce unbounded polyhedra. \n\nExample:\n\nPitman-Stanley polytopes are combinatorial cubes:\n\njulia> p = pitman_stanley_polytope([1,2,3])\nPolyhedron in ambient dimension 3\n\njulia> f_vector(p) \n2-element Vector{ZZRingElem}:\n 4\n 4\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\nCreate an 8-dimensional polytope without rational realizations due to Perles. See [Gru03].\n\nExample\n\njulia> perles_nonrational_8_polytope()\nPolytope in ambient dimension 8 with EmbeddedAbsSimpleNumFieldElem type coefficients\n\n\n\n\n\n","category":"function"},{"location":"PolyhedralGeometry/Polyhedra/constructions/#pseudo_del_pezzo_polytope","page":"Constructions","title":"pseudo_del_pezzo_polytope","text":"pseudo_del_pezzo_polytope(d::Int)\n\nProduce a d-dimensional del-Pezzo polytope, which is the convex hull of the cross polytope together with the all-ones vector. All coordinates are plus or minus one.\n\nExample\n\njulia> DP = pseudo_del_pezzo_polytope(4)\nPolytope in ambient dimension 4\n\njulia> f_vector(DP)\n4-element Vector{ZZRingElem}:\n 9\n 32\n 46\n 23\n\n\n\n\n\n","category":"function"},{"location":"PolyhedralGeometry/Polyhedra/constructions/#rand01_polytope","page":"Constructions","title":"rand01_polytope","text":"rand01_polytope(d::Int, n::Int; seed=nothing)\n\nProduce a d-dimensional 01-polytope with n random vertices. Uniform distribution.\n\nOptional Argument\n\n-seed::Int: Seed for random number generation\n\nExample\n\njulia> s = rand01_polytope(2, 4; seed=3)\nPolytope in ambient dimension 2\n\njulia> vertices(s)\n4-element SubObjectIterator{PointVector{QQFieldElem}}:\n [1, 1]\n [1, 0]\n [0, 0]\n [0, 1]\n\n\n\n\n\n","category":"function"},{"location":"PolyhedralGeometry/Polyhedra/constructions/#rand_box_polytope","page":"Constructions","title":"rand_box_polytope","text":"rand_box_polytope(d::Int, n::Int, b::Int; seed::Int=nothing)\n\nComputes the convex hull of n points sampled uniformly at random from the integer points in the cube 0textttb^textttd.\n\nOptional Argument\n\n-seed: Seed for random number generation.\n\nExample\n\njulia> r = rand_box_polytope(3, 10, 3, seed=1)\nPolyhedron in ambient dimension 3\n\njulia> vertices(r) \n8-element SubObjectIterator{PointVector{QQFieldElem}}:\n [3, 2, 3]\n [0, 3, 0]\n [3, 3, 0]\n [3, 0, 1]\n [1, 1, 0]\n [2, 0, 3]\n [0, 3, 3]\n [0, 1, 2]\n\n\n\n\n\n","category":"function"},{"location":"PolyhedralGeometry/Polyhedra/constructions/#rand_cyclic_polytope","page":"Constructions","title":"rand_cyclic_polytope","text":"rand_cyclic_polytope(d::Int, n::Int; seed::Int=nothing)\n\nComputes a random instance of a cyclic polytope of dimension d on n vertices by randomly generating a Gale diagram whose cocircuits have alternating signs.\n\nOptional Argument\n\n-seed: Seed for random number generation\n\nExamples\n\njulia> r = rand_cyclic_polytope(3, 5)\nPolytope in ambient dimension 3\n\njulia> f_vector(r)\n3-element Vector{ZZRingElem}:\n 5\n 9\n 6\n\n\n\n\n\n","category":"function"},{"location":"PolyhedralGeometry/Polyhedra/constructions/#rand_metric","page":"Constructions","title":"rand_metric","text":"rand_metric(n::Int; seed=nothing)\n\nProduce a rational n-point metric with random distances. The values are uniformily distributed in 1 2.\n\nExamples\n\njulia> rand_metric(3, seed=132)\n[ 0 260222460282405//140737488355328 371474612593257//281474976710656]\n[260222460282405//140737488355328 0 388326899436839//281474976710656]\n[371474612593257//281474976710656 388326899436839//281474976710656 0]\n\n\n\n\n\n\n","category":"function"},{"location":"PolyhedralGeometry/Polyhedra/constructions/#rand_metric_int","page":"Constructions","title":"rand_metric_int","text":"rand_metric_int(n::Int, digits::Int; seed=nothing)\n\nProduce a n-point metric with random integral distances. The values are uniformily distributed in 1 2. The distances are integers and lie in 10^digits 10^(digits+1).\n\n\n\n\n\n","category":"function"},{"location":"PolyhedralGeometry/Polyhedra/constructions/#rand_normal_polytope","page":"Constructions","title":"rand_normal_polytope","text":"rand_normal_polytope(d::Int, n::Int; seed=nothing, precision=nothing)\n\nProduce a rational d-dimensional polytope from n random points approximately normally distributed in the unit ball.\n\nOptional Arguments\n\n-seed: controls the outcome of the random number generator; fixing a seed number guarantees the same outcome -precision: number of bits for MPFR sphere approximation\n\nExample\n\njulia> rnp = rand_normal_polytope(2,4; seed=42, precision=4)\nPolytope in ambient dimension 2\n\njulia> is_simplicial(rnp)\ntrue\n\njulia> sort(map(x->dot(x,x), vertices(rnp)))\n4-element Vector{QQFieldElem}:\n 1417//4096\n 481//1024\n 225//256\n 101//32\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)\nPolytope in ambient dimension 3\n\njulia> is_simplicial(rsph)\ntrue\n\njulia> rsph = rand_spherical_polytope(3, 4; precision=5, seed=132)\nPolytope 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)\nPolytope 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> n_vertices(rand_subpolytope(cube(3), 5))\n5\n\n\n\n\n\n\n","category":"function"},{"location":"PolyhedralGeometry/Polyhedra/constructions/#rss_associahedron","page":"Constructions","title":"rss_associahedron","text":"rss_associahedron(n::Int)\n\nProduce a polytope of constrained expansions in ambient dimension n according to [RSS03].\n\nExamples:\n\nTo produce a 3-dimensional associahedron in 5-space, do: \n\njulia> a= rss_associahedron(5)\nPolyhedron in ambient dimension 5\n\njulia> vertices(a)\n14-element SubObjectIterator{PointVector{QQFieldElem}}:\n [0, 1, 12, 13, 16]\n [0, 7, 8, 11, 16]\n [0, 1, 4, 9, 16]\n [0, 3, 4, 9, 16]\n [0, 5, 6, 9, 16]\n [0, 5, 8, 9, 16]\n [0, 1, 8, 9, 16]\n [0, 7, 10, 11, 16]\n [0, 7, 12, 13, 16]\n [0, 7, 12, 15, 16]\n [0, 1, 12, 15, 16]\n [0, 7, 8, 15, 16]\n [0, 1, 4, 15, 16]\n [0, 3, 4, 15, 16]\n\njulia> facets(a) \n9-element SubObjectIterator{AffineHalfspace{QQFieldElem}} over the halfspaces of R^5 described by:\nx_1 - x_2 <= -1\nx_1 - x_3 <= -4\nx_1 - x_4 <= -9\nx_2 - x_3 <= -1\nx_2 - x_4 <= -4\nx_2 - x_5 <= -9\nx_3 - x_4 <= -1\nx_3 - x_5 <= -4\nx_4 - x_5 <= -1\n\n\n\n\n\n","category":"function"},{"location":"PolyhedralGeometry/Polyhedra/constructions/#signed_permutahedron","page":"Constructions","title":"signed_permutahedron","text":"signed_permutahedron(d::Int)\n\nProduce the d-dimensional signed permutahedron. I.e. for all possible permutations of the vector (1dotsd), all possible sign patterns define vertices of this polytope. Contrary to the classical permutahedron, the signed permutahedron is full-dimensional. \n\nExamples:\n\nTo produce the 2-dimensional signed permutahedron, do: \n\njulia> P = signed_permutahedron(2)\nPolytope in ambient dimension 2\n\njulia> vertices(P)\n8-element SubObjectIterator{PointVector{QQFieldElem}}:\n [1, 2]\n [-1, 2]\n [1, -2]\n [-1, -2]\n [2, 1]\n [-2, 1]\n [2, -1]\n [-2, -1]\n\n\n\n\n\n","category":"function"},{"location":"PolyhedralGeometry/Polyhedra/constructions/#stable_set_polytope","page":"Constructions","title":"stable_set_polytope","text":"stable_set_polytope(G::Graph{Undirected})\n\nProduces the stable set polytope from an undirected graph G=(VE). The stable set Polytope has the following inequalities: x_i + x_j leq 1 forall ij in E, x_i geq 0 forall i in V and x_i leq 1 forall i in V text with mathrmdeg(i)=0 \n\nExample:\n\nThe following produces first the standard cube in 3 dimensions, and then a bipyramid over the convex hull of the unit vectors. \n\njulia> G = Graph{Undirected}(3)\nUndirected graph with 3 nodes and no edges\n\njulia> S = stable_set_polytope(G)\nPolytope in ambient dimension 3\n\njulia> vertices(S)\n8-element SubObjectIterator{PointVector{QQFieldElem}}:\n [1, 0, 0]\n [1, 1, 0]\n [1, 1, 1]\n [1, 0, 1]\n [0, 0, 1]\n [0, 0, 0]\n [0, 1, 0]\n [0, 1, 1]\n\njulia> add_edge!(G, 1, 2);\n\njulia> add_edge!(G, 1, 3);\n\njulia> add_edge!(G, 2, 3);\n\njulia> S = stable_set_polytope(G)\nPolytope in ambient dimension 3\n\njulia> vertices(S)\n5-element SubObjectIterator{PointVector{QQFieldElem}}:\n [0, 0, 1]\n [0, 1, 0]\n [1, 0, 0]\n [1//2, 1//2, 1//2]\n [0, 0, 0]\n\n\n\n\n\n","category":"function"},{"location":"PolyhedralGeometry/Polyhedra/constructions/#transportation_polytope","page":"Constructions","title":"transportation_polytope","text":"transportation_polytope(r::AbstractVector, c::AbstractVector)\n\nProduce the transportation polytope from two vectors r of length m and c of length n, i.e. all positive mtimes n Matrizes with row sums equal to r and column sums equal to c. \n\nExample:\n\nWe can see that the set of 3times 3 magic squares with magic constant 15 is a 4-dimensional polytope. \n\njulia> r = c = [15,15,15]\n3-element Vector{Int64}:\n 15\n 15\n 15\n\njulia> t = transportation_polytope(r,c) \nPolytope in ambient dimension 9\n\njulia> dim(t) \n4\n\njulia> is_bounded(t) \ntrue\n\n\n\n\n\n","category":"function"},{"location":"PolyhedralGeometry/Polyhedra/constructions/#zonotope","page":"Constructions","title":"zonotope","text":"zonotope(M::Matrix{<:Number}; centered::Bool=true)\n\nCreate a zonotope from a matrix whose rows are input points.\n\nOptional Arguments\n\ncentered::Bool: This is true if the output should be centered; the default is true.\n\nExamples\n\nThe following produces a parallelogram with the origin as its vertex barycenter: \n\njulia> Z = zonotope([1 0; 1 1])\nPolyhedron in ambient dimension 2\n\njulia> vertices(Z)\n4-element SubObjectIterator{PointVector{QQFieldElem}}:\n [-1, -1//2]\n [0, -1//2]\n [0, 1//2]\n [1, 1//2]\n\nThe following produces a parallelogram with the origin being a vertex (not centered case): \n\njulia> Z = zonotope([1 0; 1 1], centered = false)\nPolyhedron in ambient dimension 2\n\njulia> vertices(Z)\n4-element SubObjectIterator{PointVector{QQFieldElem}}:\n [0, 0]\n [1, 0]\n [1, 1]\n [2, 1]\n\n\n\n\n\n","category":"function"},{"location":"PolyhedralGeometry/Polyhedra/constructions/#zonotope_vertices_fukuda_matrix","page":"Constructions","title":"zonotope_vertices_fukuda_matrix","text":"zonotope_vertices_fukuda(M::Matrix)\n\nCreate the vertices of a zonotope from a matrix whose rows are input points or vectors. \n\nExamples\n\nThe following creates the vertices of a parallelogram with the origin as its vertex barycenter.\n\njulia> zonotope_vertices_fukuda_matrix([1 1 0; 1 1 1])\npm::Matrix\n-1 -1 -1/2\n0 0 -1/2\n0 0 1/2\n1 1 1/2\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\nvertex_figure","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> n_vertices(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)\nPolytope in ambient dimension 2\n\njulia> S=cube(1)\nPolytope 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)\nPolytope 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)\nPolytope 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/#vertex_figure","page":"Constructions","title":"vertex_figure","text":"vertex_figure(P::Polyhedron, n::Int; cutoff=1//2)\n\nConstruct the vertex figure of the vertex n of a bounded polytope. The vertex figure is dual to a facet of the dual polytope. \n\nOptional Arguments\n\ncutoff::Number: controls the exact location of the cutting hyperplane. It should lie in the open Interval (01). Value 0 would let the hyperplane go through the chosen vertex, thus degenerating the vertex figure to a single point. Value 1 would let the hyperplane touch the nearest neighbor vertex of a polyhedron. Default value is frac12. \n\nExample\n\nTo produce a triangular vertex figure of a 3-dimensional cube in the positive orthant, do: \n\njulia> T = vertex_figure(cube(3), 8) \nPolyhedron in ambient dimension 3\n\njulia> vertices(T)\n3-element SubObjectIterator{PointVector{QQFieldElem}}:\n [1, 1, 0]\n [1, 0, 1]\n [0, 1, 1]\n\njulia> T = vertex_figure(cube(3), 8, cutoff = 1/4)\nPolyhedron in ambient dimension 3\n\njulia> vertices(T)\n3-element SubObjectIterator{PointVector{QQFieldElem}}:\n [1, 1, 1//2]\n [1, 1//2, 1]\n [1//2, 1, 1]\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":"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/#map_from_func-Tuple{Function, Any, Any}","page":"Functional maps","title":"map_from_func","text":"map_from_func(image_fn::Function, domain, codomain)\n\nConstruct the generic functional map with domain and codomain given by the parent objects R and S corresponding to the Julia function f.\n\nExamples\n\njulia> f = map_from_func(x -> x + 1, ZZ, ZZ)\nMap defined by a Julia function\n from integers\n to integers\n\njulia> f(ZZ(2))\n3\n\n\n\n\n\n","category":"method"},{"location":"TropicalGeometry/intro/","page":"Introduction","title":"Introduction","text":"CurrentModule = Oscar","category":"page"},{"location":"TropicalGeometry/intro/#Introduction","page":"Introduction","title":"Introduction","text":"","category":"section"},{"location":"TropicalGeometry/intro/","page":"Introduction","title":"Introduction","text":"The tropical geometry part of OSCAR provides functionality for","category":"page"},{"location":"TropicalGeometry/intro/","page":"Introduction","title":"Introduction","text":"tropical min-plus and max-plus semirings,\nmatrices and polynomials thereover,\ntropical varieties, hypersurfaces, curves, and linear spaces.","category":"page"},{"location":"TropicalGeometry/intro/","page":"Introduction","title":"Introduction","text":"General textbooks offering details on theory and algorithms include:","category":"page"},{"location":"TropicalGeometry/intro/","page":"Introduction","title":"Introduction","text":"Maclagan, Sturmfels: Introduction to Tropical Geometry [MS15]\nJoswig: Essentials of Tropical Combinatorics [Jos21]","category":"page"},{"location":"TropicalGeometry/intro/","page":"Introduction","title":"Introduction","text":"Like [MS15], OSCAR follows the min-convention by default and unless specified otherwise.","category":"page"},{"location":"TropicalGeometry/intro/#Contact","page":"Introduction","title":"Contact","text":"","category":"section"},{"location":"TropicalGeometry/intro/","page":"Introduction","title":"Introduction","text":"Please direct questions about this part of OSCAR to:","category":"page"},{"location":"TropicalGeometry/intro/","page":"Introduction","title":"Introduction","text":"Yue Ren.","category":"page"},{"location":"TropicalGeometry/intro/","page":"Introduction","title":"Introduction","text":"You can also ask questions in the OSCAR Slack or raise an issue on github.","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":"rowlength\ncollength\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":"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":"Experimental/DoubleAndHyperComplexes/advice_for_the_programmer/#Advice-for-the-programmer","page":"Advice for the programmer","title":"Advice for the programmer","text":"","category":"section"},{"location":"Experimental/DoubleAndHyperComplexes/advice_for_the_programmer/#How-to-implement-my-custom-double-complex?","page":"Advice for the programmer","title":"How to implement my custom double complex?","text":"","category":"section"},{"location":"Experimental/DoubleAndHyperComplexes/advice_for_the_programmer/","page":"Advice for the programmer","title":"Advice for the programmer","text":"The implementation for Double complexes is generically lazy. We provide a concrete type which takes care of handling the user's requests to entries and morphisms and their caching: DoubleComplexOfMorphisms. ","category":"page"},{"location":"Experimental/DoubleAndHyperComplexes/advice_for_the_programmer/","page":"Advice for the programmer","title":"Advice for the programmer","text":"In order to work properly, any DoubleComplexOfMorphisms D needs to be able to produce entries D[i, j] for legitimate indices (i, j) and the morphisms between these on request. To this end, the internal constructor of DoubleComplexOfMorphisms requires the programmer to pass on certain \"factories\". For the production of the entries D[i, j], these must be concrete instances of ","category":"page"},{"location":"Experimental/DoubleAndHyperComplexes/advice_for_the_programmer/","page":"Advice for the programmer","title":"Advice for the programmer","text":" abstract type ChainFactory{ChainType} end","category":"page"},{"location":"Experimental/DoubleAndHyperComplexes/advice_for_the_programmer/","page":"Advice for the programmer","title":"Advice for the programmer","text":"For this type the call syntax must be overwritten as follows:","category":"page"},{"location":"Experimental/DoubleAndHyperComplexes/advice_for_the_programmer/","page":"Advice for the programmer","title":"Advice for the programmer","text":" function (fac::ChainFactory{ChainType})(D::AbsDoubleComplexOfMorphisms, i::Int, j::Int)::ChainType where {ChainType}","category":"page"},{"location":"Experimental/DoubleAndHyperComplexes/advice_for_the_programmer/","page":"Advice for the programmer","title":"Advice for the programmer","text":"This will be called by the internals of DoubleComplex whenever production of the (i, j)-th entry is requested. The first argument will then always be the concrete double complex D itself, so that the factory has access to all information that has already been computed when trying to compute the entry for (i, j). Beware not to produce infinite feedback loops when implementing this!","category":"page"},{"location":"Experimental/DoubleAndHyperComplexes/advice_for_the_programmer/","page":"Advice for the programmer","title":"Advice for the programmer","text":"Moreover, any factory is supposed to be able to communicate whether or not a specific entry is computable. To this end one also needs to overwrite","category":"page"},{"location":"Experimental/DoubleAndHyperComplexes/advice_for_the_programmer/","page":"Advice for the programmer","title":"Advice for the programmer","text":" function can_compute(fac::ChainFactory{ChainType}, D::AbsDoubleComplexOfMorphisms, i::Int, j::Int)::Bool where {ChainType}","category":"page"},{"location":"Experimental/DoubleAndHyperComplexes/advice_for_the_programmer/","page":"Advice for the programmer","title":"Advice for the programmer","text":"Let's see this in an example. Suppose we want to implement the \"zero double complex of modules\" over a multivariate polynomial ring R, i.e. the unbounded double complex which consists entirely of zero modules and the trivial homomorphisms between them. Then the factory would be ","category":"page"},{"location":"Experimental/DoubleAndHyperComplexes/advice_for_the_programmer/","page":"Advice for the programmer","title":"Advice for the programmer","text":"mutable struct ZeroModuleFactory{ChainType} <: ChainFactory{ChainType}\n R::MPolyRing\n \n function ZeroModuleFactory(R::MPolyRing)\n return new{ModuleFP{elem_type(R)}}(R)\n end\nend\n\nfunction (fac::ZeroModuleFactory)(D::AbsDoubleComplexOfMorphisms, i::Int, j::Int)\n return FreeMod(fac.R, 0)\nend\n\nfunction can_compute(fac::ZeroModuleFactory, D::AbsDoubleComplexOfMorphisms, i::Int, j::Int)\n return true\nend","category":"page"},{"location":"Experimental/DoubleAndHyperComplexes/advice_for_the_programmer/","page":"Advice for the programmer","title":"Advice for the programmer","text":"The horizontal and vertical morphisms also need their factories. Similar to the above, these need to be concrete instances of ","category":"page"},{"location":"Experimental/DoubleAndHyperComplexes/advice_for_the_programmer/","page":"Advice for the programmer","title":"Advice for the programmer","text":" abstract type ChainMorphismFactory{MorphismType} end","category":"page"},{"location":"Experimental/DoubleAndHyperComplexes/advice_for_the_programmer/","page":"Advice for the programmer","title":"Advice for the programmer","text":"and the programmer must overwrite the functions ","category":"page"},{"location":"Experimental/DoubleAndHyperComplexes/advice_for_the_programmer/","page":"Advice for the programmer","title":"Advice for the programmer","text":" function (fac::ChainMorphismFactory{MorphismType})(dc::AbsDoubleComplexOfMorphisms, i::Int, j::Int)::MorphismType where {MorphismType}\n function can_compute(fac::ChainMorphismFactory{MorphismType}, dc::AbsDoubleComplexOfMorphisms, i::Int, j::Int)::Bool where {MorphismType}","category":"page"},{"location":"Experimental/DoubleAndHyperComplexes/advice_for_the_programmer/","page":"Advice for the programmer","title":"Advice for the programmer","text":"In the above example we would implement","category":"page"},{"location":"Experimental/DoubleAndHyperComplexes/advice_for_the_programmer/","page":"Advice for the programmer","title":"Advice for the programmer","text":"mutable struct VerticalZeroMaps{MorphismType} <: ChainMorphismFactory{MorphismType}\n R::MPolyRing\n\n function VerticalZeroMaps(R::MPolyRing)\n return new{ModuleFPHom}(R)\n end\nend\n\nmutable struct HorizontalZeroMaps{MorphismType} <: ChainMorphismFactory{MorphismType}\n R::MPolyRing\n\n function HorizontalZeroMaps(R::MPolyRing)\n return new{ModuleFPHom}(R)\n end\nend","category":"page"},{"location":"Experimental/DoubleAndHyperComplexes/advice_for_the_programmer/","page":"Advice for the programmer","title":"Advice for the programmer","text":"Then we would overwrite the call syntax as follows.","category":"page"},{"location":"Experimental/DoubleAndHyperComplexes/advice_for_the_programmer/","page":"Advice for the programmer","title":"Advice for the programmer","text":"function (fac::VerticalZeroMaps)(D::AbsDoubleComplexOfMorphisms, i::Int, j::Int)\n dom = D[i, j]\n inc = (vertical_direction(D) == :chain ? -1 : 1)\n cod = D[i, j + inc]\n return hom(dom, cod, elem_type(cod)[])\nend\n\nfunction (fac::HorizontalZeroMaps)(D::AbsDoubleComplexOfMorphisms, i::Int, j::Int)\n dom = D[i, j]\n inc = (horizontal_direction(D) == :chain ? -1 : 1)\n cod = D[i + inc, j]\n return hom(dom, cod, elem_type(cod)[])\nend\n \nfunction can_compute(fac::HorizontalZeroMaps, D::AbsDoubleComplexOfMorphisms, i::Int, j::Int)\n return true\nend\n\nfunction can_compute(fac::VerticalZeroMaps, D::AbsDoubleComplexOfMorphisms, i::Int, j::Int)\n return true\nend","category":"page"},{"location":"Experimental/DoubleAndHyperComplexes/advice_for_the_programmer/","page":"Advice for the programmer","title":"Advice for the programmer","text":"In order to finally create our zero double complex we implement the constructor as follows.","category":"page"},{"location":"Experimental/DoubleAndHyperComplexes/advice_for_the_programmer/","page":"Advice for the programmer","title":"Advice for the programmer","text":"function zero_double_complex(R::MPolyRing)\n entry_fac = ZeroModuleFactory(R)\n vert_map_fac = VerticalZeroMaps(R)\n horz_map_fac = HorizontalZeroMaps(R)\n \n result = DoubleComplexOfMorphisms(entry_fac, horz_map_fac, vert_map_fac, horizontal_direction=:chain, vertical_direction=:chain)\n return result\nend","category":"page"},{"location":"Experimental/DoubleAndHyperComplexes/advice_for_the_programmer/","page":"Advice for the programmer","title":"Advice for the programmer","text":"Note that any concrete complex Z created by zero_double_complex is unbounded in every direction. In particular, has_upper_bound(Z) etc. will return false and upper_bound(Z) will throw an error. At the same time can_compute_index(Z, i, j) will always return true and calling Z[i, j] will produce a reasonable and cached result. See the source code of the internal constructor of DoubleComplexOfMorphisms for how to alter these settings.","category":"page"},{"location":"Experimental/DoubleAndHyperComplexes/advice_for_the_programmer/","page":"Advice for the programmer","title":"Advice for the programmer","text":"Another example for an implementation of a double complex can be found in experimental/DoubleComplexes/test/double_complex_interface.jl. There we write an implementation to turn a bounded simple ComplexOfMorphisms for modules over polynomial rings C into a bounded DoubleComplexOfMorphisms D which knows how to extend itself with zeroes to the left and to the right, but is concentrated in the zeroeth row.","category":"page"},{"location":"Experimental/DoubleAndHyperComplexes/advice_for_the_programmer/#How-to-make-use-of-the-generic-functionality?","page":"Advice for the programmer","title":"How to make use of the generic functionality?","text":"","category":"section"},{"location":"Experimental/DoubleAndHyperComplexes/advice_for_the_programmer/","page":"Advice for the programmer","title":"Advice for the programmer","text":"For double complexes we have some generic functionality available, e.g. total_complex(D::AbsDoubleComplexOfMorphisms{ChainType, MorphismType}). Such generic functionality assumes certain methods to be implemented for the ChainType and the MorphismType of the double complex D. For instance, it must be possible to compose two morphisms of type <:MorphismType and get a new object of type <:MorphismType. Sometimes, the required functionality is not streamlined throughout OSCAR (and there is little hope to achieve this). One example for this are direct sums: For finitely generated modules, the function takes a special keyword argument task to indicate whether the inclusion and projection maps should also be returned, while for TorQuadModules, this keyword argument is not even available. To potentially accomodate all these different types in our double complexes, the generic code uses an internal method","category":"page"},{"location":"Experimental/DoubleAndHyperComplexes/advice_for_the_programmer/","page":"Advice for the programmer","title":"Advice for the programmer","text":" _direct_sum(u::Vector{T}) where {T}","category":"page"},{"location":"Experimental/DoubleAndHyperComplexes/advice_for_the_programmer/","page":"Advice for the programmer","title":"Advice for the programmer","text":"to make sure that the output has the correct format (s, inc, pr) consisting of the direct sum s itself, together with the vectors of inclusion- and projection maps inc and pr.","category":"page"},{"location":"Experimental/DoubleAndHyperComplexes/advice_for_the_programmer/","page":"Advice for the programmer","title":"Advice for the programmer","text":"If any generic functionality, such as forming a total complex, does not work for your custom implementation of a double complex, check whether this might be due to a missing implementation of this method or others.","category":"page"},{"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.FracFieldElem{T} (Generic.FracField{T})\nGeneric.Mat{T} (MatSpace{T})","category":"page"},{"location":"Experimental/LieAlgebras/module_homs/","page":"Lie algebra module homomorphisms","title":"Lie algebra module homomorphisms","text":"CurrentModule = Oscar\nDocTestSetup = Oscar.doctestsetup()","category":"page"},{"location":"Experimental/LieAlgebras/module_homs/#Lie-algebra-module-homomorphisms","page":"Lie algebra module homomorphisms","title":"Lie algebra module homomorphisms","text":"","category":"section"},{"location":"Experimental/LieAlgebras/module_homs/","page":"Lie algebra module homomorphisms","title":"Lie algebra module homomorphisms","text":"Homomorphisms of Lie algebra modules in Oscar are represented by the type LieAlgebraModuleHom.","category":"page"},{"location":"Experimental/LieAlgebras/module_homs/#Constructors","page":"Lie algebra module homomorphisms","title":"Constructors","text":"","category":"section"},{"location":"Experimental/LieAlgebras/module_homs/","page":"Lie algebra module homomorphisms","title":"Lie algebra module homomorphisms","text":"Homomorphisms of modules over the same Lie algebra h V_1 to V_2 are constructed by providing either the images of the basis elements of V_1 or a dim V_1 times dim V_2 matrix.","category":"page"},{"location":"Experimental/LieAlgebras/module_homs/","page":"Lie algebra module homomorphisms","title":"Lie algebra module homomorphisms","text":"hom(::LieAlgebraModule{C}, ::LieAlgebraModule{C}, ::Vector{<:LieAlgebraModuleElem{C}}; check::Bool=true) where {C<:FieldElem}\nhom(::LieAlgebraModule{C}, ::LieAlgebraModule{C}, ::MatElem{C}; check::Bool=true) where {C<:FieldElem}\nidentity_map(::LieAlgebraModule)\nzero_map(::LieAlgebraModule{C}, ::LieAlgebraModule{C}) where {C<:FieldElem}","category":"page"},{"location":"Experimental/LieAlgebras/module_homs/#hom-Union{Tuple{C}, Tuple{LieAlgebraModule{C, LieT} where LieT<:LieAlgebraElem{C}, LieAlgebraModule{C, LieT} where LieT<:LieAlgebraElem{C}, Vector{<:LieAlgebraModuleElem{C, LieT} where LieT<:LieAlgebraElem{C}}}} where C<:FieldElem","page":"Lie algebra module homomorphisms","title":"hom","text":"hom(V1::LieAlgebraModule, V2::LieAlgebraModule, imgs::Vector{<:LieAlgebraModuleElem}; check::Bool=true) -> LieAlgebraModuleHom\n\nConstruct the homomorphism from V1 to V2 by sending the i-th basis element of V1 to imgs[i] and extending linearly. All elements of imgs must lie in V2. Currently, V1 and V2 must be modules over the same Lie algebra.\n\nBy setting check=false, the linear map is not checked to be compatible with the module action.\n\nExamples\n\njulia> L = special_linear_lie_algebra(QQ, 2);\n\njulia> V1 = standard_module(L);\n\njulia> V3 = trivial_module(L, 3);\n\njulia> V2 = direct_sum(V1, V3);\n\njulia> h = hom(V1, V2, [V2([v, zero(V3)]) for v in basis(V1)])\nLie algebra module morphism\n from standard module of dimension 2 over L\n to direct sum module of dimension 5 over L\n\njulia> [(v, h(v)) for v in basis(V1)]\n2-element Vector{Tuple{LieAlgebraModuleElem{QQFieldElem, LinearLieAlgebraElem{QQFieldElem}}, LieAlgebraModuleElem{QQFieldElem, LinearLieAlgebraElem{QQFieldElem}}}}:\n (v_1, v_1^(1))\n (v_2, v_2^(1))\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/module_homs/#hom-Union{Tuple{C}, Tuple{LieAlgebraModule{C, LieT} where LieT<:LieAlgebraElem{C}, LieAlgebraModule{C, LieT} where LieT<:LieAlgebraElem{C}, MatElem{C}}} where C<:FieldElem","page":"Lie algebra module homomorphisms","title":"hom","text":"hom(V1::LieAlgebraModule, V2::LieAlgebraModule, mat::MatElem; check::Bool=true) -> LieAlgebraModuleHom\n\nConstruct the homomorphism from V1 to V2 by acting with the matrix mat from the right on the coefficient vector w.r.t. the basis of V1. mat must be a matrix of size dim(V1) \\times dim(V2) over coefficient_ring(V2). Currently, V1 and V2 must be modules over the same Lie algebra.\n\nBy setting check=false, the linear map is not checked to be compatible with the module action.\n\nExamples\n\njulia> L = general_linear_lie_algebra(QQ, 3);\n\njulia> V1 = standard_module(L);\n\njulia> V2 = trivial_module(L);\n\njulia> h = hom(V1, V2, matrix(QQ, 3, 1, [0, 0, 0]))\nLie algebra module morphism\n from standard module of dimension 3 over L\n to abstract Lie algebra module of dimension 1 over L\n\njulia> [(v, h(v)) for v in basis(V1)]\n3-element Vector{Tuple{LieAlgebraModuleElem{QQFieldElem, LinearLieAlgebraElem{QQFieldElem}}, LieAlgebraModuleElem{QQFieldElem, LinearLieAlgebraElem{QQFieldElem}}}}:\n (v_1, 0)\n (v_2, 0)\n (v_3, 0)\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/module_homs/#identity_map-Tuple{LieAlgebraModule}","page":"Lie algebra module homomorphisms","title":"identity_map","text":"identity_map(V::LieAlgebraModule) -> LieAlgebraModuleHom\n\nConstruct the identity map on V.\n\nExamples\n\njulia> L = special_linear_lie_algebra(QQ, 3);\n\njulia> V = standard_module(L)\nStandard module\n of dimension 3\nover special linear Lie algebra of degree 3 over QQ\n\njulia> identity_map(V)\nLie algebra module morphism\n from standard module of dimension 3 over L\n to standard module of dimension 3 over L\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/module_homs/#zero_map-Union{Tuple{C}, Tuple{LieAlgebraModule{C, LieT} where LieT<:LieAlgebraElem{C}, LieAlgebraModule{C, LieT} where LieT<:LieAlgebraElem{C}}} where C<:FieldElem","page":"Lie algebra module homomorphisms","title":"zero_map","text":"zero_map(V1::LieAlgebraModule, V2::LieAlgebraModule) -> LieAlgebraModuleHom\nzero_map(V::LieAlgebraModule) -> LieAlgebraModuleHom\n\nConstruct the zero map from V1 to V2 or from V to V.\n\nExamples\n\njulia> L = special_linear_lie_algebra(QQ, 3);\n\njulia> V = standard_module(L)\nStandard module\n of dimension 3\nover special linear Lie algebra of degree 3 over QQ\n\njulia> zero_map(V)\nLie algebra module morphism\n from standard module of dimension 3 over L\n to standard module of dimension 3 over L\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/module_homs/#Functions","page":"Lie algebra module homomorphisms","title":"Functions","text":"","category":"section"},{"location":"Experimental/LieAlgebras/module_homs/","page":"Lie algebra module homomorphisms","title":"Lie algebra module homomorphisms","text":"The following functions are available for LieAlgebraModuleHoms:","category":"page"},{"location":"Experimental/LieAlgebras/module_homs/#Basic-properties","page":"Lie algebra module homomorphisms","title":"Basic properties","text":"","category":"section"},{"location":"Experimental/LieAlgebras/module_homs/","page":"Lie algebra module homomorphisms","title":"Lie algebra module homomorphisms","text":"For a homomorphism h V_1 to V_2, domain(h) and codomain(h) return V_1 and V_2 respectively.","category":"page"},{"location":"Experimental/LieAlgebras/module_homs/","page":"Lie algebra module homomorphisms","title":"Lie algebra module homomorphisms","text":"matrix(::LieAlgebraModuleHom{<:LieAlgebraModule,<:LieAlgebraModule{C2}}) where {C2<:FieldElem}","category":"page"},{"location":"Experimental/LieAlgebras/module_homs/#matrix-Union{Tuple{LieAlgebraModuleHom{<:LieAlgebraModule, <:LieAlgebraModule{C2, LieT} where LieT<:LieAlgebraElem{C2}}}, Tuple{C2}} where C2<:FieldElem","page":"Lie algebra module homomorphisms","title":"matrix","text":"matrix(h::LieAlgebraModuleHom) -> MatElem\n\nReturn the transformation matrix of h w.r.t. the bases of the domain and codomain.\n\nNote: The matrix operates on the coefficient vectors from the right.\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/module_homs/#Image","page":"Lie algebra module homomorphisms","title":"Image","text":"","category":"section"},{"location":"Experimental/LieAlgebras/module_homs/","page":"Lie algebra module homomorphisms","title":"Lie algebra module homomorphisms","text":"image(::LieAlgebraModuleHom, ::LieAlgebraModuleElem)","category":"page"},{"location":"Experimental/LieAlgebras/module_homs/#image-Tuple{LieAlgebraModuleHom, LieAlgebraModuleElem}","page":"Lie algebra module homomorphisms","title":"image","text":"image(h::LieAlgebraModuleHom, v::LieAlgebraModuleElem) -> LieAlgebraModuleElem\n\nReturn the image of v under h.\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/module_homs/#Composition","page":"Lie algebra module homomorphisms","title":"Composition","text":"","category":"section"},{"location":"Experimental/LieAlgebras/module_homs/","page":"Lie algebra module homomorphisms","title":"Lie algebra module homomorphisms","text":"compose(::LieAlgebraModuleHom{T1,T2}, ::LieAlgebraModuleHom{T2,T3}) where {T1<:LieAlgebraModule,T2<:LieAlgebraModule,T3<:LieAlgebraModule}","category":"page"},{"location":"Experimental/LieAlgebras/module_homs/#compose-Union{Tuple{T3}, Tuple{T2}, Tuple{T1}, Tuple{LieAlgebraModuleHom{T1, T2}, LieAlgebraModuleHom{T2, T3}}} where {T1<:LieAlgebraModule, T2<:LieAlgebraModule, T3<:LieAlgebraModule}","page":"Lie algebra module homomorphisms","title":"compose","text":"compose(f::LieAlgebraModuleHom, g::LieAlgebraModuleHom) -> LieAlgebraModuleHom\n\nReturn the composition of f and g, i.e. the homomorphism h such that h(x) = g(f(x)) for all x in the domain of f. The codomain of f must be identical to the domain of g.\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/module_homs/#Inverses","page":"Lie algebra module homomorphisms","title":"Inverses","text":"","category":"section"},{"location":"Experimental/LieAlgebras/module_homs/","page":"Lie algebra module homomorphisms","title":"Lie algebra module homomorphisms","text":"is_isomorphism(::LieAlgebraModuleHom)\ninv(::LieAlgebraModuleHom)","category":"page"},{"location":"Experimental/LieAlgebras/module_homs/#is_isomorphism-Tuple{LieAlgebraModuleHom}","page":"Lie algebra module homomorphisms","title":"is_isomorphism","text":"is_isomorphism(h::LieAlgebraModuleHom) -> Bool\n\nReturn true if h is an isomorphism. This function tries to invert the transformation matrix of h and caches the result. The inverse isomorphism can be cheaply accessed via inv(h) after calling this function.\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/module_homs/#inv-Tuple{LieAlgebraModuleHom}","page":"Lie algebra module homomorphisms","title":"inv","text":"inv(h::LieAlgebraModuleHom) -> LieAlgebraModuleHom\n\nReturn the inverse of h. Requires h to be an isomorphism.\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/module_homs/#Hom-constructions","page":"Lie algebra module homomorphisms","title":"Hom constructions","text":"","category":"section"},{"location":"Experimental/LieAlgebras/module_homs/","page":"Lie algebra module homomorphisms","title":"Lie algebra module homomorphisms","text":"Lie algebra module homomorphisms support + and - if they have the same domain and codomain.","category":"page"},{"location":"Experimental/LieAlgebras/module_homs/","page":"Lie algebra module homomorphisms","title":"Lie algebra module homomorphisms","text":"canonical_injections(::LieAlgebraModule)\ncanonical_injection(::LieAlgebraModule, ::Int)\ncanonical_projections(::LieAlgebraModule)\ncanonical_projection(::LieAlgebraModule, ::Int)\nhom_direct_sum(::LieAlgebraModule{C}, ::LieAlgebraModule{C}, ::Matrix{<:LieAlgebraModuleHom}) where {C<:FieldElem}\nhom_tensor(::LieAlgebraModule{C}, ::LieAlgebraModule{C}, ::Vector{<:LieAlgebraModuleHom}) where {C<:FieldElem}\nhom(::LieAlgebraModule{C}, ::LieAlgebraModule{C}, ::LieAlgebraModuleHom) where {C<:FieldElem}","category":"page"},{"location":"Experimental/LieAlgebras/module_homs/#canonical_injections-Tuple{LieAlgebraModule}","page":"Lie algebra module homomorphisms","title":"canonical_injections","text":"canonical_injections(V::LieAlgebraModule) -> Vector{LieAlgebraModuleHom}\n\nReturn the canonical injections from all components into V where V has been constructed as V_1 oplus cdot oplus V_n.\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/module_homs/#canonical_injection-Tuple{LieAlgebraModule, Int64}","page":"Lie algebra module homomorphisms","title":"canonical_injection","text":"canonical_injection(V::LieAlgebraModule, i::Int) -> LieAlgebraModuleHom\n\nReturn the canonical injection V_i to V where V has been constructed as V_1 oplus cdot oplus V_n.\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/module_homs/#canonical_projections-Tuple{LieAlgebraModule}","page":"Lie algebra module homomorphisms","title":"canonical_projections","text":"canonical_projections(V::LieAlgebraModule) -> Vector{LieAlgebraModuleHom}\n\nReturn the canonical projections from V to all components where V has been constructed as V_1 oplus cdot oplus V_n.\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/module_homs/#canonical_projection-Tuple{LieAlgebraModule, Int64}","page":"Lie algebra module homomorphisms","title":"canonical_projection","text":"canonical_projection(V::LieAlgebraModule, i::Int) -> LieAlgebraModuleHom\n\nReturn the canonical projection V to V_i where V has been constructed as V_1 oplus cdot oplus V_n.\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/module_homs/#hom_direct_sum-Union{Tuple{C}, Tuple{LieAlgebraModule{C, LieT} where LieT<:LieAlgebraElem{C}, LieAlgebraModule{C, LieT} where LieT<:LieAlgebraElem{C}, Matrix{<:LieAlgebraModuleHom}}} where C<:FieldElem","page":"Lie algebra module homomorphisms","title":"hom_direct_sum","text":"hom_direct_sum(V::LieAlgebraModule{C}, W::LieAlgebraModule{C}, hs::Matrix{<:LieAlgebraModuleHom}) -> LieAlgebraModuleHom\nhom_direct_sum(V::LieAlgebraModule{C}, W::LieAlgebraModule{C}, hs::Vector{<:LieAlgebraModuleHom}) -> LieAlgebraModuleHom\n\nGiven modules V and W which are direct sums with r respective s summands, say M = M_1 oplus cdots oplus M_r, N = N_1 oplus cdots oplus N_s, and given a r times s matrix hs of homomorphisms h_ij V_i to W_j, return the homomorphism V to W with ij-components h_ij.\n\nIf hs is a vector, then it is interpreted as a diagonal matrix.\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/module_homs/#hom_tensor-Union{Tuple{C}, Tuple{LieAlgebraModule{C, LieT} where LieT<:LieAlgebraElem{C}, LieAlgebraModule{C, LieT} where LieT<:LieAlgebraElem{C}, Vector{<:LieAlgebraModuleHom}}} where C<:FieldElem","page":"Lie algebra module homomorphisms","title":"hom_tensor","text":"hom_tensor(V::LieAlgebraModule{C}, W::LieAlgebraModule{C}, hs::Vector{<:LieAlgebraModuleHom}) -> LieAlgebraModuleHom\n\nGiven modules V and W which are tensor products with the same number of factors, say V = V_1 otimes cdots otimes V_r, W = W_1 otimes cdots otimes W_r, and given a vector hs of homomorphisms a_i V_i to W_i, return a_1 otimes cdots otimes a_r.\n\nThis works for rth tensor powers as well.\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/LieAlgebras/module_homs/#hom-Union{Tuple{C}, Tuple{LieAlgebraModule{C, LieT} where LieT<:LieAlgebraElem{C}, LieAlgebraModule{C, LieT} where LieT<:LieAlgebraElem{C}, LieAlgebraModuleHom}} where C<:FieldElem","page":"Lie algebra module homomorphisms","title":"hom","text":"hom(V::LieAlgebraModule{C}, W::LieAlgebraModule{C}, h::LieAlgebraModuleHom) -> LieAlgebraModuleHom\n\nGiven modules V and W which are exterior/symmetric/tensor powers of the same kind with the same exponent, say, e.g., V = S^k V, W = S^k W, and given a homomorphism h V to W, return S^k h V to W (analogous for other types of powers).\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/intro/","page":"Introduction","title":"Introduction","text":"CurrentModule = Oscar","category":"page"},{"location":"CommutativeAlgebra/intro/#commutative_algebra","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 related to multivariate polynomial rings discussed in this chapter apply to both the ungraded and graded case. 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":"[GP08]\n[DL06]\n[DP13]","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{<:ModuleFP, <:ModuleFP, Nothing}})","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/hom_operations/#hom_product-Tuple{ModuleFP, ModuleFP, Matrix{<:ModuleFPHom{<:ModuleFP, <:ModuleFP, Nothing}}}","page":"Operations on Module Maps","title":"hom_product","text":"hom_product(M::ModuleFP, N::ModuleFP, A::Matrix{<:ModuleFPHom{<:ModuleFP, <:ModuleFP, Nothing}})\n\nGiven modules M and N which are products with r respective s factors, say M = prod_i=1^r M_i, N = prod_j=1^s N_j, and given a r times s 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":"AbstractAlgebra/map_interface/","page":"Map Interface","title":"Map Interface","text":"CurrentModule = AbstractAlgebra\nDocTestSetup = quote\n using AbstractAlgebra\nend","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/#identity_map-Tuple{AbstractAlgebra.Set}","page":"Map Interface","title":"identity_map","text":"identity_map(R::D) where D <: AbstractAlgebra.Set\n\nReturn an identity map on the domain R.\n\nExamples\n\njulia> R, t = ZZ[:t]\n(Univariate polynomial ring in t over integers, t)\n\njulia> f = identity_map(R)\nIdentity map\n of univariate polynomial ring in t over integers\n\njulia> f(t)\nt\n\n\n\n\n\n","category":"method"},{"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, g::Map)","category":"page"},{"location":"AbstractAlgebra/map_interface/#compose-Tuple{Map, Map}","page":"Map Interface","title":"compose","text":"compose(f::Map, g::Map)\n\nCompose the two maps f and g, i.e. return the map h such that h(x) = g(f(x)).\n\nExamples\n\njulia> f = map_from_func(x -> x + 1, ZZ, ZZ);\n\njulia> g = map_from_func(x -> QQ(x), ZZ, QQ);\n\njulia> h = compose(f, g)\nFunctional composite map\n from integers\n to rationals\nwhich is the composite of\n Map: integers -> integers\n Map: integers -> rationals\n\n\n\n\n\n","category":"method"},{"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/IntersectionTheory/schubert/","page":"Schubert Calculus","title":"Schubert Calculus","text":"CurrentModule = Oscar","category":"page"},{"location":"Experimental/IntersectionTheory/schubert/#Schubert-Calculus","page":"Schubert Calculus","title":"Schubert Calculus","text":"","category":"section"},{"location":"Experimental/IntersectionTheory/schubert/","page":"Schubert Calculus","title":"Schubert Calculus","text":"To recall the definition of Schubert cycles on a Grassmannian mathrmG(kn), we think of mathrmG(k n) as the Grassmannian mathrmG(k W) of k-dimensional subspaces of an n-dimensional K-vector space W.","category":"page"},{"location":"Experimental/IntersectionTheory/schubert/","page":"Schubert Calculus","title":"Schubert Calculus","text":"A flag in W is a strictly increasing sequence of linear subspaces","category":"page"},{"location":"Experimental/IntersectionTheory/schubert/","page":"Schubert Calculus","title":"Schubert Calculus","text":"0 subset W_1 subset dots subset W_n-1 subset W_n = W text with dim(W_i) = i","category":"page"},{"location":"Experimental/IntersectionTheory/schubert/","page":"Schubert Calculus","title":"Schubert Calculus","text":"Let such a flag mathcalW be given. For any sequence a = (a_1 ldots a_k) of integers with n-k geq a_1 geq ldots geq a_k geq 0, we define the Schubert cycle Sigma_a(mathcalW) by setting","category":"page"},{"location":"Experimental/IntersectionTheory/schubert/","page":"Schubert Calculus","title":"Schubert Calculus","text":"Sigma_a(mathcalW)= V in mathrmG(k W)mid dim(W_n-k+i-a_i cap V) geq i i = 1 ldots k ","category":"page"},{"location":"Experimental/IntersectionTheory/schubert/","page":"Schubert Calculus","title":"Schubert Calculus","text":"Then we have:","category":"page"},{"location":"Experimental/IntersectionTheory/schubert/","page":"Schubert Calculus","title":"Schubert Calculus","text":"The Schubert cycle Sigma_a(mathcalW) is an irreducible subvariety of mathrmG(k W) of codimension a = sum a_i.\nIts cycle class Sigma_a(mathcalW) does not depend on the choice of the flag.","category":"page"},{"location":"Experimental/IntersectionTheory/schubert/","page":"Schubert Calculus","title":"Schubert Calculus","text":"We define the Schubert class of a = (a_1 ldots a_k) to be the cycle class","category":"page"},{"location":"Experimental/IntersectionTheory/schubert/","page":"Schubert Calculus","title":"Schubert Calculus","text":"sigma_a = Sigma_a(mathcalW) ","category":"page"},{"location":"Experimental/IntersectionTheory/schubert/","page":"Schubert Calculus","title":"Schubert Calculus","text":"The number of Schubert classes on the Grassmannian mathrmG(k n) is equal to binomnk.","category":"page"},{"location":"Experimental/IntersectionTheory/schubert/","page":"Schubert Calculus","title":"Schubert Calculus","text":"Instead of sigma_a, we write sigma_a_1ldotsa_s whenever a = (a_1 ldots a_s 0 ldots 0), and sigma_p^i whenever a = (p ldots p 0 ldots 0) in mathbb Z^i times 0^k-i.","category":"page"},{"location":"Experimental/IntersectionTheory/schubert/","page":"Schubert Calculus","title":"Schubert Calculus","text":"The classes sigma_1^i, i = 1 ldots k, and sigma_i, i = 1 ldots n-k, are called special Schubert classes. They are closely related to the Chern classes of the tautological vector bundles on mathrmG(k W). Recall:","category":"page"},{"location":"Experimental/IntersectionTheory/schubert/","page":"Schubert Calculus","title":"Schubert Calculus","text":"The tautological subbundle on mathrmG(k W) is the vector bundle of rank k whose fiber at V in mathrmG(k W) is the subspace V subset W.\nThe tautological quotient bundle on mathrmG(k W) is the vector bundle of rank (n-k) whose fiber at V in mathrmG(k W) is the quotient vector space WV.","category":"page"},{"location":"Experimental/IntersectionTheory/schubert/","page":"Schubert Calculus","title":"Schubert Calculus","text":"We denote these vector bundles by S and Q, respectively.","category":"page"},{"location":"Experimental/IntersectionTheory/schubert/","page":"Schubert Calculus","title":"Schubert Calculus","text":"The Chern classes of S and Q are","category":"page"},{"location":"Experimental/IntersectionTheory/schubert/","page":"Schubert Calculus","title":"Schubert Calculus","text":"c_i(S) = (-1)^i sigma_1^i text for i = 1 ldots k","category":"page"},{"location":"Experimental/IntersectionTheory/schubert/","page":"Schubert Calculus","title":"Schubert Calculus","text":"and","category":"page"},{"location":"Experimental/IntersectionTheory/schubert/","page":"Schubert Calculus","title":"Schubert Calculus","text":"c_i(Q) = sigma_i text for i = 1 ldots n-k","category":"page"},{"location":"Experimental/IntersectionTheory/schubert/","page":"Schubert Calculus","title":"Schubert Calculus","text":"respectively.","category":"page"},{"location":"Experimental/IntersectionTheory/schubert/","page":"Schubert Calculus","title":"Schubert Calculus","text":"All Schubert classes form a K-vector space basis of the Chow ring of mathrmG(kn). The Chern classes of S (the special Schubert classes sigma_1^i, i=1 ldots k) form a minimal set of generators for the Chow ring of mathrmG(kn) as a K-algebra. See [EH16] for the relations on these generators.","category":"page"},{"location":"Experimental/IntersectionTheory/schubert/","page":"Schubert Calculus","title":"Schubert Calculus","text":"schubert_class(G::AbstractVariety, λ::Int...)","category":"page"},{"location":"Experimental/IntersectionTheory/schubert/#schubert_class-Tuple{AbstractVariety, Vararg{Int64}}","page":"Schubert Calculus","title":"schubert_class","text":"schubert_class(G::AbstractVariety, λ::Int...)\nschubert_class(G::AbstractVariety, λ::Vector{Int})\nschubert_class(G::AbstractVariety, λ::Partition)\n\nReturn the Schubert class sigma_lambda on a (relative) Grassmannian G.\n\nExamples\n\njulia> G = abstract_grassmannian(2,4)\nAbstractVariety of dim 4\n\njulia> s0 = schubert_class(G, 0)\n1\n\njulia> s1 = schubert_class(G, 1)\n-c[1]\n\njulia> s2 = schubert_class(G, 2)\nc[1]^2 - c[2]\n\njulia> s11 = schubert_class(G, [1, 1])\nc[2]\n\njulia> s21 = schubert_class(G, [2, 1])\n-c[1]*c[2]\n\njulia> s22 = schubert_class(G, [2, 2])\nc[2]^2\n\njulia> s1*s1 == s2+s11\ntrue\n\njulia> s1*s2 == s1*s11 == s21\ntrue\n\njulia> s1*s21 == s2*s2 == s22\ntrue\n\n\njulia> G = abstract_grassmannian(2,5)\nAbstractVariety of dim 6\n\njulia> s3 = schubert_class(G, 5-2)\n-c[1]^3 + 2*c[1]*c[2]\n\njulia> s3^2 == point_class(G)\ntrue\n\njulia> Q = tautological_bundles(G)[2]\nAbstractBundle of rank 3 on AbstractVariety of dim 6\n\njulia> chern_class(Q, 3)\n-c[1]^3 + 2*c[1]*c[2]\n\n\njulia> G = abstract_grassmannian(2,4)\nAbstractVariety of dim 4\n\njulia> s1 = schubert_class(G, 1)\n-c[1]\n\njulia> s1 == schubert_class(G, [1, 0])\ntrue\n\njulia> integral(s1^4)\n2\n\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/IntersectionTheory/schubert/","page":"Schubert Calculus","title":"Schubert Calculus","text":"schubert_classes(G::AbstractVariety, m::Int)","category":"page"},{"location":"Experimental/IntersectionTheory/schubert/#schubert_classes-Tuple{AbstractVariety, Int64}","page":"Schubert Calculus","title":"schubert_classes","text":"schubert_classes(G::AbstractVariety, m::Int)\n\nReturn all Schubert classes in codimension m on a (relative) Grassmannian G.\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/IntersectionTheory/schubert/","page":"Schubert Calculus","title":"Schubert Calculus","text":"schubert_classes(G::AbstractVariety)","category":"page"},{"location":"Experimental/IntersectionTheory/schubert/#schubert_classes-Tuple{AbstractVariety}","page":"Schubert Calculus","title":"schubert_classes","text":"schubert_classes(G::AbstractVariety)\n\nReturn all Schubert classes on a (relative) Grassmannian G.\n\nExamples\n\njulia> G = abstract_grassmannian(2,4)\nAbstractVariety of dim 4\n\njulia> schubert_classes(G)\n5-element Vector{Vector{MPolyQuoRingElem{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}}}:\n [1]\n [-c[1]]\n [c[1]^2 - c[2], c[2]]\n [-c[1]*c[2]]\n [c[2]^2]\n\njulia> basis(G)\n5-element Vector{Vector{MPolyQuoRingElem}}:\n [1]\n [c[1]]\n [c[2], c[1]^2]\n [c[1]*c[2]]\n [c[2]^2]\n \n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"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/linear_solving/","page":"Linear solving","title":"Linear solving","text":"CurrentModule = AbstractAlgebra.Solve","category":"page"},{"location":"AbstractAlgebra/linear_solving/#solving_chapter","page":"Linear solving","title":"Linear solving","text":"","category":"section"},{"location":"AbstractAlgebra/linear_solving/#Overview-of-the-functionality","page":"Linear solving","title":"Overview of the functionality","text":"","category":"section"},{"location":"AbstractAlgebra/linear_solving/","page":"Linear solving","title":"Linear solving","text":"The module AbstractAlgebra.Solve provides the following four functions for solving linear systems:","category":"page"},{"location":"AbstractAlgebra/linear_solving/","page":"Linear solving","title":"Linear solving","text":"solve\ncan_solve\ncan_solve_with_solution\ncan_solve_with_solution_and_kernel","category":"page"},{"location":"AbstractAlgebra/linear_solving/","page":"Linear solving","title":"Linear solving","text":"All of these take the same set of arguments, namely:","category":"page"},{"location":"AbstractAlgebra/linear_solving/","page":"Linear solving","title":"Linear solving","text":"a matrix A of type MatElem;\na vector or matrix B of type Vector or MatElem;\na keyword argument side which can be either :left (default) or :right.","category":"page"},{"location":"AbstractAlgebra/linear_solving/","page":"Linear solving","title":"Linear solving","text":"If side is :left, the system xA = B is solved, otherwise the system Ax = B is solved.","category":"page"},{"location":"AbstractAlgebra/linear_solving/","page":"Linear solving","title":"Linear solving","text":"The functionality of the functions can be summarized as follows.","category":"page"},{"location":"AbstractAlgebra/linear_solving/","page":"Linear solving","title":"Linear solving","text":"solve: return a solution, if it exists, otherwise throw an error.\ncan_solve: return true, if a solution exists, false otherwise.\ncan_solve_with_solution: return true and a solution, if this exists, and false and an empty vector or matrix otherwise.\ncan_solve_with_solution_and_kernel: like can_solve_with_solution and additionally return a matrix whose rows (respectively columns) give a basis of the kernel of A.","category":"page"},{"location":"AbstractAlgebra/linear_solving/#Solving-with-several-right-hand-sides","page":"Linear solving","title":"Solving with several right hand sides","text":"","category":"section"},{"location":"AbstractAlgebra/linear_solving/","page":"Linear solving","title":"Linear solving","text":"Systems xA = b_1dots xA = b_k with the same matrix A, but several right hand sides b_i can be solved more efficiently, by first initializing a \"context object\" C.","category":"page"},{"location":"AbstractAlgebra/linear_solving/","page":"Linear solving","title":"Linear solving","text":"solve_init","category":"page"},{"location":"AbstractAlgebra/linear_solving/#solve_init","page":"Linear solving","title":"solve_init","text":"solve_init(A::MatElem)\n\nReturn a context object C that allows to efficiently solve linear systems Ax = b or xA = b for different b.\n\nExample\n\njulia> A = QQ[1 2 3; 0 3 0; 5 0 0];\n\njulia> C = solve_init(A)\nLinear solving context of matrix\n [1//1 2//1 3//1]\n [0//1 3//1 0//1]\n [5//1 0//1 0//1]\n\njulia> solve(C, [QQ(1), QQ(1), QQ(1)], side = :left)\n3-element Vector{Rational{BigInt}}:\n 1//3\n 1//9\n 2//15\n\njulia> solve(C, [QQ(1), QQ(1), QQ(1)], side = :right)\n3-element Vector{Rational{BigInt}}:\n 1//5\n 1//3\n 2//45\n\n\n\n\n\n","category":"function"},{"location":"AbstractAlgebra/linear_solving/","page":"Linear solving","title":"Linear solving","text":"Now the functions solve, can_solve, etc. can be used with C in place of A. This way the time-consuming part of the solving (i.e. computing a reduced form of A) is only done once and the result cached in C to be reused.","category":"page"},{"location":"AbstractAlgebra/linear_solving/#Detailed-documentation","page":"Linear solving","title":"Detailed documentation","text":"","category":"section"},{"location":"AbstractAlgebra/linear_solving/","page":"Linear solving","title":"Linear solving","text":"solve\ncan_solve\ncan_solve_with_solution\ncan_solve_with_solution_and_kernel\nkernel","category":"page"},{"location":"AbstractAlgebra/linear_solving/#solve","page":"Linear solving","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_verbosity_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.RelSimpleNumFieldElem{Hecke.RelSimpleNumFieldElem{AbsSimpleNumFieldElem}}}:\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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\nsolve(A::MatElem{T}, b::Vector{T}; side::Symbol = :left) where T\nsolve(A::MatElem{T}, b::MatElem{T}; side::Symbol = :left) where T\nsolve(C::SolveCtx{T}, b::Vector{T}; side::Symbol = :left) where T\nsolve(C::SolveCtx{T}, b::MatElem{T}; side::Symbol = :left) where T\n\nReturn x of same type as b solving the linear system xA = b, if side == :left (default), or Ax = b, if side == :right.\n\nIf no solution exists, an error is raised.\n\nIf a context object C is supplied, then the above applies for A = matrix(C).\n\nSee also can_solve_with_solution.\n\n\n\n\n\n","category":"function"},{"location":"AbstractAlgebra/linear_solving/#can_solve","page":"Linear solving","title":"can_solve","text":" can_solve(f::QuadBin, n::IntegerUnion) -> Bool\n\nFor a binary quadratic form f with negative discriminant and an integer n, return whether f represents n.\n\n\n\n\n\ncan_solve(A::MatElem{T}, b::Vector{T}; side::Symbol = :left) where T\ncan_solve(A::MatElem{T}, b::MatElem{T}; side::Symbol = :left) where T\ncan_solve(C::SolveCtx{T}, b::Vector{T}; side::Symbol = :left) where T\ncan_solve(C::SolveCtx{T}, b::MatElem{T}; side::Symbol = :left) where T\n\nReturn true if the linear system xA = b or Ax = b with side == :left (default) or side == :right, respectively, has a solution and false otherwise.\n\nIf a context object C is supplied, then the above applies for A = matrix(C).\n\nSee also can_solve_with_solution.\n\n\n\n\n\n","category":"function"},{"location":"AbstractAlgebra/linear_solving/#can_solve_with_solution","page":"Linear solving","title":"can_solve_with_solution","text":" can_solve_with_solution(f::QuadBin, n::IntegerUnion)\n -> Bool, Tuple{ZZRingElem, ZZRingElem}\n\nFor a binary quadratic form f with negative discriminant and an integer n, return the tuple (true, (x, y)) if f(x y) = n for integers x, y. If no such integers exist, return (false, (0, 0))\n\n\n\n\n\ncan_solve_with_solution(A::MatElem{T}, b::Vector{T}; side::Symbol = :left) where T\ncan_solve_with_solution(A::MatElem{T}, b::MatElem{T}; side::Symbol = :left) where T\ncan_solve_with_solution(C::SolveCtx{T}, b::Vector{T}; side::Symbol = :left) where T\ncan_solve_with_solution(C::SolveCtx{T}, b::MatElem{T}; side::Symbol = :left) where T\n\nReturn true and x of same type as b solving the linear system xA = b, if such a solution exists. Return false and an empty vector or matrix, if the system has no solution.\n\nIf side == :right, the system Ax = b is solved.\n\nIf a context object C is supplied, then the above applies for A = matrix(C).\n\nSee also solve.\n\n\n\n\n\n","category":"function"},{"location":"AbstractAlgebra/linear_solving/#can_solve_with_solution_and_kernel","page":"Linear solving","title":"can_solve_with_solution_and_kernel","text":"can_solve_with_solution_and_kernel(A::MatElem{T}, b::Vector{T}; side::Symbol = :left) where T\ncan_solve_with_solution_and_kernel(A::MatElem{T}, b::MatElem{T}; side::Symbol = :left) where T\ncan_solve_with_solution_and_kernel(C::SolveCtx{T}, b::Vector{T}; side::Symbol = :left) where T\ncan_solve_with_solution_and_kernel(C::SolveCtx{T}, b::MatElem{T}; side::Symbol = :left) where T\n\nReturn true, x of same type as b solving the linear system xA = b, together with a matrix K giving the kernel of A (i.e. KA = 0), if such a solution exists. Return false, an empty vector or matrix and an empty matrix, if the system has no solution.\n\nIf side == :right, the system Ax = b is solved.\n\nIf a context object C is supplied, then the above applies for A = matrix(C).\n\nSee also solve and kernel.\n\n\n\n\n\n","category":"function"},{"location":"AbstractAlgebra/linear_solving/#kernel","page":"Linear solving","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\nkernel(M::SMat{T}; side::Symbol = :left) where {T <: FieldElement}\n\nReturn a matrix N containing a basis of the kernel of M. If side is :left (default), the left kernel is computed, i.e. the matrix of rows whose span gives the left kernel space. If side is :right, the right kernel is computed, i.e. the matrix of columns whose span is the right kernel space.\n\n\n\n\n\nkernel(h::FinGenAbGroupHom) -> FinGenAbGroup, Map\n\nLet G be the domain of h. This function returns an abelian group A and an injective morphism f colon A to G, such that the image of f is the kernel of h.\n\n\n\n\n\nkernel(f::TorQuadModuleMap) -> TorQuadModule, TorQuadModuleMap\n\nGiven an abelian group homomorphism f between two torsion quadratic modules T and U, return the kernel S of f as well as the injection S to T.\n\n\n\n\n\nkernel(f::AbstractAlgebra.Map(SAlgHom))\n\nReturn the kernel of the algebra homomorphism f.\n\n\n\n\n\nkernel(f::AbstractAlgebra.Map(SIdAlgHom))\n\nReturn the kernel of the identity algebra homomorphism.\n\n\n\n\n\nkernel(A::MatElem; side::Symbol = :left)\nkernel(C::SolveCtx; side::Symbol = :left)\n\nReturn a matrix K whose rows generate the left kernel of A, that is, KA is the zero matrix.\n\nIf side == :right, the columns of K generate the right kernel of A, that is, AK is the zero matrix.\n\nIf the base ring is a principal ideal domain, the rows or columns respectively of K are a basis of the respective kernel.\n\nIf a context object C is supplied, then the above applies for A = matrix(C).\n\n\n\n\n\nkernel(F::AffAlgHom)\n\nReturn the kernel of F.\n\n\n\n\n\nkernel(f::GAPGroupHomomorphism)\n\nReturn the kernel of f, together with its embedding into domain(f).\n\n\n\n\n\nkernel(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\nkernel(a::FreeModuleHom)\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(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 R\n\njulia> G = free_module(R, 2)\nFree module of rank 2 over R\n\njulia> V = [y*G[1], x*G[1]+y*G[2], z*G[2]];\n\njulia> a = hom(F, G, V);\n\njulia> kernel(a)\n(Submodule with 1 generator\n1 -> x*z*e[1] - y*z*e[2] + y^2*e[3]\nrepresented as subquotient with no relations., Map 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 R)\n\njulia> Rg, (x, y, z) = graded_polynomial_ring(QQ, [:x, :y, :z]);\n\njulia> F = graded_free_module(Rg, 3);\n\njulia> G = graded_free_module(Rg, 2);\n\njulia> V = [y*G[1], x*G[1]+y*G[2], z*G[2]];\n\njulia> a = hom(F, G, V);\n\njulia> kernel(a)\n(Graded submodule of F\n1 -> x*z*e[1] - y*z*e[2] + y^2*e[3]\nrepresented as subquotient with no relations, Graded submodule of F\n1 -> x*z*e[1] - y*z*e[2] + y^2*e[3]\nrepresented as subquotient with no relations -> F\nx*z*e[1] - y*z*e[2] + y^2*e[3] -> x*z*e[1] - y*z*e[2] + y^2*e[3]\nHomogeneous module homomorphism)\n\n\n\n\n\n\nkernel(a::SubQuoHom)\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\n\n\n\n\nkernel(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 R\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> Rg, (x, y, z) = graded_polynomial_ring(QQ, [: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*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*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\ny*e[1] -> y*e[1]\n-x*y*e[1] -> -x*y*e[1]\nHomogeneous module homomorphism)\n\n\n\n\n\n\nkernel(h::LieAlgebraHom) -> LieAlgebraIdeal\n\nReturn the kernel of h as an ideal of the domain.\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"function"},{"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":"Experimental/GroebnerWalk/introduction/","page":"Usage","title":"Usage","text":"CurrentModule = Oscar","category":"page"},{"location":"Experimental/GroebnerWalk/introduction/#Usage","page":"Usage","title":"Usage","text":"","category":"section"},{"location":"Experimental/GroebnerWalk/introduction/","page":"Usage","title":"Usage","text":"The Gröbner walk is an approach to reduce the computational complexity of Gröbner basis computations as proposed by [AGK97]. These incarnations of the Gröbner walk refer to a family of algorithms that perform a reverse local search on the cones of the Gröbner fan. Then, a Gröbner basis is calculated for each encountered cone while reusing the generators obtained from the previous cone.","category":"page"},{"location":"Experimental/GroebnerWalk/introduction/","page":"Usage","title":"Usage","text":"The implemented algorithms may be accessed using the following function.","category":"page"},{"location":"Experimental/GroebnerWalk/introduction/","page":"Usage","title":"Usage","text":" groebner_walk(\n I::MPolyIdeal, \n target::MonomialOrdering = lex(base_ring(I)),\n start::MonomialOrdering = default_ordering(base_ring(I));\n perturbation_degree = ngens(base_ring(I)),\n algorithm::Symbol = :standard\n )","category":"page"},{"location":"Experimental/GroebnerWalk/introduction/#groebner_walk","page":"Usage","title":"groebner_walk","text":"groebner_walk(\n I::MPolyIdeal, \n target::MonomialOrdering = lex(base_ring(I)),\n start::MonomialOrdering = default_ordering(base_ring(I));\n perturbation_degree = ngens(base_ring(I)),\n algorithm::Symbol = :standard\n)\n\nCompute a reduced Groebner basis w.r.t. to the monomial ordering target by converting it from a Groebner basis with respect to the ordering start using the Groebner Walk.\n\nArguments\n\nI::MPolyIdeal: ideal one wants to compute a Groebner basis for.\ntarget::MonomialOrdering=:lex: monomial ordering one wants to compute a Groebner basis for.\nstart::MonomialOrdering=:degrevlex: monomial ordering to begin the conversion.\nperturbationDegree::Int=2: the perturbation degree for the perturbed Walk.\nalgorithm::Symbol=:standard: strategy of the Groebner Walk. One can choose between:\nstandard: Standard Walk [CLO05],\ngeneric: Generic Walk [FJLT07],\nperturbed: Perturbed Walk [AGK96].\n\nExamples\n\njulia> R,(x,y) = polynomial_ring(QQ, [:x,:y]);\n\njulia> I = ideal([y^4+ x^3-x^2+x,x^4]);\n\njulia> groebner_walk(I, lex(R))\nGröbner basis with elements\n 1 -> x + y^12 - y^8 + y^4\n 2 -> y^16\nwith respect to the ordering\n lex([x, y])\n\njulia> groebner_walk(I, lex(R); algorithm=:generic)\nGröbner basis with elements\n 1 -> y^16\n 2 -> x + y^12 - y^8 + y^4\nwith respect to the ordering\n lex([x, y])\n\njulia> set_verbosity_level(:groebner_walk, 1);\n\njulia> groebner_walk(I, lex(R))\nResults for standard_walk\nCrossed Cones in: \nZZRingElem[1, 1]\nZZRingElem[4, 3]\nZZRingElem[4, 1]\nZZRingElem[12, 1]\nCones crossed: 4\nGröbner basis with elements\n 1 -> x + y^12 - y^8 + y^4\n 2 -> y^16\nwith respect to the ordering\n lex([x, y])\n\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"function"},{"location":"Experimental/DoubleAndHyperComplexes/user_interface/","page":"Double complexes – the user's interface","title":"Double complexes – the user's interface","text":"CurrentModule = Oscar","category":"page"},{"location":"Experimental/DoubleAndHyperComplexes/user_interface/#Double-complexes-–-the-user's-interface","page":"Double complexes – the user's interface","title":"Double complexes – the user's interface","text":"","category":"section"},{"location":"Experimental/DoubleAndHyperComplexes/user_interface/","page":"Double complexes – the user's interface","title":"Double complexes – the user's interface","text":"We briefly review the mathematical notion of a double complex. Let mathcal A be an Abelian category. A double complex D_bullet bullet consists of a collection of objects D_i j in mathcal A with indices (i j) in mathbb Z^2 and usually arranged in a matrix-like grid, together with two collections of morphisms D_i j to D_i pm 1 j, the horizontal morphisms, and D_i j to D_i j pm 1, the vertical morphisms, so that both the rows and the columns of D_bullet bullet are complexes in the classical sense and such that all resulting squares of maps commute.","category":"page"},{"location":"Experimental/DoubleAndHyperComplexes/user_interface/","page":"Double complexes – the user's interface","title":"Double complexes – the user's interface","text":"In practice one usually encounters complexes which are bounded in the sense that outside some specified area of indices (i j) in mathbb Z^2 the entries D_i j are all zero. Such entries are then usually omitted. ","category":"page"},{"location":"Experimental/DoubleAndHyperComplexes/user_interface/#Basic-getters-and-attributes","page":"Double complexes – the user's interface","title":"Basic getters and attributes","text":"","category":"section"},{"location":"Experimental/DoubleAndHyperComplexes/user_interface/","page":"Double complexes – the user's interface","title":"Double complexes – the user's interface","text":"In OSCAR the generic functionality for double complexes is declared for the abstract type AbsDoubleComplexOfMorphisms. These functions comprise","category":"page"},{"location":"Experimental/DoubleAndHyperComplexes/user_interface/","page":"Double complexes – the user's interface","title":"Double complexes – the user's interface","text":" getindex(D::AbsDoubleComplexOfMorphisms, i::Int, j::Int) # Get the `(i,j)`-th entry of `D`","category":"page"},{"location":"Experimental/DoubleAndHyperComplexes/user_interface/","page":"Double complexes – the user's interface","title":"Double complexes – the user's interface","text":"horizontal_map(dc::AbsDoubleComplexOfMorphisms, i::Int, j::Int)\nvertical_map(dc::AbsDoubleComplexOfMorphisms, i::Int, j::Int)","category":"page"},{"location":"Experimental/DoubleAndHyperComplexes/user_interface/#horizontal_map-Tuple{Oscar.AbsDoubleComplexOfMorphisms, Int64, Int64}","page":"Double complexes – the user's interface","title":"horizontal_map","text":"horizontal_map(dc::AbsDoubleComplexOfMorphisms, i::Int, j::Int)\n\nReturn the morphism dci j dci 1 j (the sign depending on the horizontal_direction of dc). \n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/DoubleAndHyperComplexes/user_interface/#vertical_map-Tuple{Oscar.AbsDoubleComplexOfMorphisms, Int64, Int64}","page":"Double complexes – the user's interface","title":"vertical_map","text":"vertical_map(dc::AbsDoubleComplexOfMorphisms, i::Int, j::Int)\n\nReturn the morphism dci j dci j 1 (the sign depending on the vertical_direction of dc).\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/DoubleAndHyperComplexes/user_interface/","page":"Double complexes – the user's interface","title":"Double complexes – the user's interface","text":"In which direction the maps in the rows and columns go can be asked with the following methods:","category":"page"},{"location":"Experimental/DoubleAndHyperComplexes/user_interface/","page":"Double complexes – the user's interface","title":"Double complexes – the user's interface","text":"horizontal_direction(dc::AbsDoubleComplexOfMorphisms)\nvertical_direction(dc::AbsDoubleComplexOfMorphisms)","category":"page"},{"location":"Experimental/DoubleAndHyperComplexes/user_interface/#horizontal_direction-Tuple{Oscar.AbsDoubleComplexOfMorphisms}","page":"Double complexes – the user's interface","title":"horizontal_direction","text":"horizontal_direction(dc::AbsDoubleComplexOfMorphisms)\n\nReturn a symbol :chain or :cochain depending on whether the morphisms of the rows of dc decrease or increase the (co-)homological index.\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/DoubleAndHyperComplexes/user_interface/#vertical_direction-Tuple{Oscar.AbsDoubleComplexOfMorphisms}","page":"Double complexes – the user's interface","title":"vertical_direction","text":"vertical_direction(dc::AbsDoubleComplexOfMorphisms)\n\nReturn a symbol :chain or :cochain depending on whether the morphisms of the columns of dc decrease or increase the (co-)homological index.\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/DoubleAndHyperComplexes/user_interface/","page":"Double complexes – the user's interface","title":"Double complexes – the user's interface","text":"Double complexes can be bounded or unbounded. It is important to note that even if such bounds exist and are known, this is a priori not related to whether or not certain entries are computable! I.e. even in the case of a bounded complex dc it might still be valid to call dc[i, j] beyond that bound. In general, one should use the following functions to determine whether or not it is legitimate to ask for a specific entry.","category":"page"},{"location":"Experimental/DoubleAndHyperComplexes/user_interface/","page":"Double complexes – the user's interface","title":"Double complexes – the user's interface","text":" has_index(D::AbsDoubleComplexOfMorphisms, i::Int, j::Int)\n can_compute_index(D::AbsDoubleComplexOfMorphisms, i::Int, j::Int)\n has_horizontal_map(dc::AbsDoubleComplexOfMorphisms, i::Int, j::Int)\n can_compute_horizontal_map(dc::AbsDoubleComplexOfMorphisms, i::Int, j::Int)\n has_vertical_map(dc::AbsDoubleComplexOfMorphisms, i::Int, j::Int)\n can_compute_vertical_map(dc::AbsDoubleComplexOfMorphisms, i::Int, j::Int)","category":"page"},{"location":"Experimental/DoubleAndHyperComplexes/user_interface/#has_index-Tuple{Oscar.AbsDoubleComplexOfMorphisms, Int64, Int64}","page":"Double complexes – the user's interface","title":"has_index","text":"has_index(D::AbsDoubleComplexOfMorphisms, i::Int, j::Int)\n\nReturn true if the (i, j)-th entry of D is already known, false otherwise.\n\nIf the result is false, then it might nevertheless still be possible to compute D[i, j]; use can_compute_index for such queries.\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/DoubleAndHyperComplexes/user_interface/#can_compute_index-Tuple{Oscar.AbsDoubleComplexOfMorphisms, Int64, Int64}","page":"Double complexes – the user's interface","title":"can_compute_index","text":"can_compute_index(D::AbsDoubleComplexOfMorphisms, i::Int, j::Int)\n\nReturn true if the entry D[i, j] is known or D knows how to compute it.\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/DoubleAndHyperComplexes/user_interface/#has_horizontal_map-Tuple{Oscar.AbsDoubleComplexOfMorphisms, Int64, Int64}","page":"Double complexes – the user's interface","title":"has_horizontal_map","text":"has_horizontal_map(dc::AbsDoubleComplexOfMorphisms, i::Int, j::Int)\n\nChecks whether the double complex dc has the horizontal morphism dc[i, j] → dc[i ± 1, j], the sign depending on the horizontal_direction of dc.\n\nIf this returns false this might just mean that the map has not been computed, yet. Use can_compute_horizontal_map to learn whether or not this is possible.\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/DoubleAndHyperComplexes/user_interface/#can_compute_horizontal_map-Tuple{Oscar.AbsDoubleComplexOfMorphisms, Int64, Int64}","page":"Double complexes – the user's interface","title":"can_compute_horizontal_map","text":"can_compute_horizontal_map(dc::AbsDoubleComplexOfMorphisms, i::Int, j::Int)\n\nReturn true if dc can compute the horizontal morphism dc[i, j] → dc[i ± 1, j], the sign depending on the horizontal_direction of dc, and false otherwise.\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/DoubleAndHyperComplexes/user_interface/#has_vertical_map-Tuple{Oscar.AbsDoubleComplexOfMorphisms, Int64, Int64}","page":"Double complexes – the user's interface","title":"has_vertical_map","text":"has_vertical_map(dc::AbsDoubleComplexOfMorphisms, i::Int, j::Int)\n\nChecks whether the double complex dc has the vertical morphism dc[i, j] → dc[i, j ± 1], the sign depending on the vertical_direction of dc.\n\nIf this returns false this might just mean that the map has not been computed, yet. Use can_compute_vertical_map to learn whether or not this is possible.\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/DoubleAndHyperComplexes/user_interface/#can_compute_vertical_map-Tuple{Oscar.AbsDoubleComplexOfMorphisms, Int64, Int64}","page":"Double complexes – the user's interface","title":"can_compute_vertical_map","text":"can_compute_vertical_map(dc::AbsDoubleComplexOfMorphisms, i::Int, j::Int)\n\nReturn true if dc can compute the vertical morphism dc[i, j] → dc[i, j ± 1], the sign depending on the vertical_direction of dc, and false otherwise.\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/DoubleAndHyperComplexes/user_interface/","page":"Double complexes – the user's interface","title":"Double complexes – the user's interface","text":"Explicitly known bounds for the non-zero entries of a complex are nevertheless relevant for various generic functionalities. For example, computing a total complex is only possible in practice if one has an a priori estimate where the non-zero entries are located. For such purposes, we provide the following functionality:","category":"page"},{"location":"Experimental/DoubleAndHyperComplexes/user_interface/","page":"Double complexes – the user's interface","title":"Double complexes – the user's interface","text":"has_upper_bound(D::AbsDoubleComplexOfMorphisms)\nhas_lower_bound(D::AbsDoubleComplexOfMorphisms)\nhas_right_bound(D::AbsDoubleComplexOfMorphisms)\nhas_left_bound(D::AbsDoubleComplexOfMorphisms)","category":"page"},{"location":"Experimental/DoubleAndHyperComplexes/user_interface/#has_upper_bound-Tuple{Oscar.AbsDoubleComplexOfMorphisms}","page":"Double complexes – the user's interface","title":"has_upper_bound","text":"has_upper_bound(D::AbsDoubleComplexOfMorphisms)\n\nReturn true if a universal upper bound j B for non-zero D[i, j] is known; false otherwise.\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/DoubleAndHyperComplexes/user_interface/#has_lower_bound-Tuple{Oscar.AbsDoubleComplexOfMorphisms}","page":"Double complexes – the user's interface","title":"has_lower_bound","text":"has_lower_bound(D::AbsDoubleComplexOfMorphisms)\n\nReturn true if a universal upper bound B j for non-zero D[i, j] is known; false otherwise.\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/DoubleAndHyperComplexes/user_interface/#has_right_bound-Tuple{Oscar.AbsDoubleComplexOfMorphisms}","page":"Double complexes – the user's interface","title":"has_right_bound","text":"has_right_bound(D::AbsDoubleComplexOfMorphisms)\n\nReturn true if a universal upper bound i B for non-zero D[i, j] is known; false otherwise.\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/DoubleAndHyperComplexes/user_interface/#has_left_bound-Tuple{Oscar.AbsDoubleComplexOfMorphisms}","page":"Double complexes – the user's interface","title":"has_left_bound","text":"has_left_bound(D::AbsDoubleComplexOfMorphisms)\n\nReturn true if a universal upper bound B i for non-zero D[i, j] is known; false otherwise.\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/DoubleAndHyperComplexes/user_interface/","page":"Double complexes – the user's interface","title":"Double complexes – the user's interface","text":"If they exist, these bounds can be asked for using ","category":"page"},{"location":"Experimental/DoubleAndHyperComplexes/user_interface/","page":"Double complexes – the user's interface","title":"Double complexes – the user's interface","text":"right_bound(D::AbsDoubleComplexOfMorphisms)\nleft_bound(D::AbsDoubleComplexOfMorphisms)\nupper_bound(D::AbsDoubleComplexOfMorphisms)\nlower_bound(D::AbsDoubleComplexOfMorphisms)","category":"page"},{"location":"Experimental/DoubleAndHyperComplexes/user_interface/#right_bound-Tuple{Oscar.AbsDoubleComplexOfMorphisms}","page":"Double complexes – the user's interface","title":"right_bound","text":"right_bound(D::AbsDoubleComplexOfMorphisms)\n\nReturn a bound B such that D[i, j] can be assumed to be zero for i B. Whether or not requests for D[i, j] beyond that bound are legitimate can be checked using can_compute_index.\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/DoubleAndHyperComplexes/user_interface/#left_bound-Tuple{Oscar.AbsDoubleComplexOfMorphisms}","page":"Double complexes – the user's interface","title":"left_bound","text":"left_bound(D::AbsDoubleComplexOfMorphisms)\n\nReturn a bound B such that D[i, j] can be assumed to be zero for i B. Whether or not requests for D[i, j] beyond that bound are legitimate can be checked using can_compute_index.\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/DoubleAndHyperComplexes/user_interface/#upper_bound-Tuple{Oscar.AbsDoubleComplexOfMorphisms}","page":"Double complexes – the user's interface","title":"upper_bound","text":"upper_bound(D::AbsDoubleComplexOfMorphisms)\n\nReturn a bound B such that D[i, j] can be assumed to be zero for j B. Whether or not requests for D[i, j] beyond that bound are legitimate can be checked using can_compute_index.\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/DoubleAndHyperComplexes/user_interface/#lower_bound-Tuple{Oscar.AbsDoubleComplexOfMorphisms}","page":"Double complexes – the user's interface","title":"lower_bound","text":"lower_bound(D::AbsDoubleComplexOfMorphisms)\n\nReturn a bound B such that D[i, j] can be assumed to be zero for j B. Whether or not requests for D[i, j] beyond that bound are legitimate can be checked using can_compute_index.\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/DoubleAndHyperComplexes/user_interface/","page":"Double complexes – the user's interface","title":"Double complexes – the user's interface","text":"It is also possible to query whether or not a double complex is already complete in the sense that it knows about all of its non-zero entries.","category":"page"},{"location":"Experimental/DoubleAndHyperComplexes/user_interface/","page":"Double complexes – the user's interface","title":"Double complexes – the user's interface","text":"is_complete(D::AbsDoubleComplexOfMorphisms)","category":"page"},{"location":"Experimental/DoubleAndHyperComplexes/user_interface/#is_complete-Tuple{Oscar.AbsDoubleComplexOfMorphisms}","page":"Double complexes – the user's interface","title":"is_complete","text":"is_complete(dc::AbsDoubleComplexOfMorphisms)\n\nReturn true if for all indices (i, j) with has_index(dc, i, j) = true and dc[i, j] non-zero, the vertex (i, j) is lying on an \"island\" of non-zero entries in the grid of the double complex, which is bounded by either zero entries or entries for indices (i', j') where can_compute_index(dc, i', j') = false. At least one index dc[i, j] must be known for this to return true.\n\n ⋮ ⋮ ⋮ ⋮ ⋮ ⋮ ⋮ ⋮ ⋮ ⋮ ⋮ ⋮ ⋮ ⋮ ⋮ ⋮ \n ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ \n… → ? → ? → ? → ? → ? → ? → ? → ? → ? → ? → ? → 0 → 0 → ? → - → - → …\n ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ \n… → ? → ? → 0 → 0 → 0 → ? → ? → 0 → 0 → 0 → 0 → * → * → 0 → - → - → …\n ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ \n… → 0 → 0 → * → * → * → 0 → ? → 0 → ? → 0 → 0 → * → * → * → - → - → …\n ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ \n… → 0 → * → * → * → 0 → ? → ? → 0 → 0 → ? → 0 → * → 0 → * → - → - → …\n ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ \n… → 0 → * → * → * → 0 → ? → 0 → 0 → 0 → 0 → * → * → 0 → 0 → - → - → …\n ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ \n… → ? → 0 → 0 → 0 → ? → ? → ? → ? → ? → ? → 0 → 0 → ? → ? → - → - → …\n ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ \n ⋮ ⋮ ⋮ ⋮ ⋮ ⋮ ⋮ ⋮ ⋮ ⋮ ⋮ ⋮ ⋮ ⋮ ⋮ ⋮\n\nExample of a pattern of a double complex with is_complete = true. 0 : zero entry - : entry can not be computed (can_compute_index returns false) * : non-zero entry which has been computed ? : entry can be computed, but that has not yet been done\n\n!!! note If the double complex has several of the above \"islands\", then is_complete might return true even though one or more of the \"islands\" have not yet been uncovered. Use this carefully if your full double complex might be separated by zero entries!\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/DoubleAndHyperComplexes/user_interface/#Generic-functionality","page":"Double complexes – the user's interface","title":"Generic functionality","text":"","category":"section"},{"location":"Experimental/DoubleAndHyperComplexes/user_interface/","page":"Double complexes – the user's interface","title":"Double complexes – the user's interface","text":"total_complex(D::AbsDoubleComplexOfMorphisms)","category":"page"},{"location":"Experimental/DoubleAndHyperComplexes/user_interface/#total_complex-Tuple{Oscar.AbsDoubleComplexOfMorphisms}","page":"Double complexes – the user's interface","title":"total_complex","text":"total_complex(D::AbsDoubleComplexOfMorphisms)\n\nConstruct the total complex of the double complex D. \n\nNote that D needs to be reasonably bounded for this to work so that the strands ᵢⱼₖ Dᵢⱼ are finite for every k. Moreover, the generic code uses the internal function _direct_sum. See the docstring of that function to learn more.\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/DoubleAndHyperComplexes/user_interface/#Constructors","page":"Double complexes – the user's interface","title":"Constructors","text":"","category":"section"},{"location":"Experimental/DoubleAndHyperComplexes/user_interface/","page":"Double complexes – the user's interface","title":"Double complexes – the user's interface","text":" tensor_product(C1::ComplexOfMorphisms{ChainType}, C2::ComplexOfMorphisms{ChainType}) where {ChainType}","category":"page"},{"location":"Experimental/DoubleAndHyperComplexes/user_interface/#tensor_product-Union{Tuple{ChainType}, Tuple{ComplexOfMorphisms{ChainType}, ComplexOfMorphisms{ChainType}}} where ChainType","page":"Double complexes – the user's interface","title":"tensor_product","text":"tensor_product(C::ComplexOfMorphisms{ChainType}, D::ComplexOfMorphisms{ChainType}) where {ChainType}\n\nCreate the tensor product of two complexes C and D as a double complex.\n\nIn order for the generic implementation to work for your specific ChainType the following needs to be implemented.\n\nmorphism_type(ChainType) must produce the type of morphisms between objects of type ChainType;\nthe call signature for function (fac::TensorProductFactory{ChainType})(dc::AbsDoubleComplexOfMorphisms, i::Int, j::Int) needs to be overwritten for your specific instance of ChainType to produce the (i, j)-th entry of the double complex, i.e. the tensor product of C[i] and D[j];\nthe call signature for function (fac::HorizontalTensorMapFactory{ChainType})(dc::AbsDoubleComplexOfMorphisms, i::Int, j::Int) needs to be overwritten to produce the map on tensor products C[i] ⊗ D[j] → C[i±1] ⊗ D[j] induced by the (co-)boundary map on C (the sign depending on the typ of C);\nsimilarly for the VerticalTensorMapFactory.\n\nSee the file experimental/DoubleComplex/src/tensor_products.jl for examples.\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"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 ArbFieldElem 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()","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":"julia> CC = ComplexField()\nComplex field\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/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":"julia> c = onei(CC)\n1.0000000000000000000*im","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":"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::ArbFieldElem)","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":"julia> RR = RealField()\nReal field\n\njulia> CC = ComplexField()\nComplex field\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/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":"julia> 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","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":"julia> 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/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::ArbFieldElem, y::ZZRingElem)\n==(x::ZZRingElem, y::ArbFieldElem)\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":"julia> 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) == y\ntrue\n\njulia> z != 1.23\ntrue","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":"julia> 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/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":"julia> 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/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 ComplexFieldElem 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":"julia> 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/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()\nset_precision!(ComplexField, 200) do\n a = const_pi(CC)\nend","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::EllipticCurve) -> 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":"julia> 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/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":"julia> # These are two of the roots of x^5 + 3x + 1\n\njulia> a = CC(1.0050669478588622428791051888364775253, -0.93725915669289182697903585868761513585)\n[1.0050669478588623029 +/- 2.25e-20] - [0.93725915669289183718 +/- 1.50e-21]*im\n\njulia> b = CC(-0.33198902958450931620250069492231652319)\n-[0.33198902958450932088 +/- 4.15e-22]\n\njulia> V1 = [CC(1), a, a^2, a^3, a^4, a^5]; # We recover the polynomial from one root....\n\njulia> W = lindep(V1, 20)\n6-element Vector{ZZRingElem}:\n 1\n 3\n 0\n 0\n 0\n 1\n\njulia> V2 = [CC(1), b, b^2, b^3, b^4, b^5]; # ...or from two\n\njulia> Vs = [transpose(V1); transpose(V2)];\n\njulia> X = lindep(Vs, 20)\n6-element Vector{ZZRingElem}:\n 1\n 3\n 0\n 0\n 0\n 1","category":"page"},{"location":"Rings/intro/","page":"Introduction","title":"Introduction","text":"CurrentModule = Oscar\nDocTestSetup = Oscar.doctestsetup()","category":"page"},{"location":"Rings/intro/#rings","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 = Oscar.doctestsetup()","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":"[JT13]\n[Zie95]","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)\nPolytope 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":"There are two specialized Vector-like types, PointVector and RayVector, which commonly are returned by functions from Polyhedral Geometry. These can also be manually constructed:","category":"page"},{"location":"PolyhedralGeometry/intro/","page":"Introduction","title":"Introduction","text":"point_vector\nray_vector","category":"page"},{"location":"PolyhedralGeometry/intro/#point_vector","page":"Introduction","title":"point_vector","text":"point_vector(p = QQ, v::AbstractVector)\n\nReturn a PointVector resembling a point whose coordinates equal the entries of v. p specifies the Field or Type of its coefficients.\n\n\n\n\n\n","category":"function"},{"location":"PolyhedralGeometry/intro/#ray_vector","page":"Introduction","title":"ray_vector","text":"ray_vector(p = QQ, v::AbstractVector)\n\nReturn a RayVector resembling a ray from the origin through the point whose coordinates equal the entries of v. p specifies the Field or Type of its coefficients.\n\n\n\n\n\n","category":"function"},{"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{<:PointVector} 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":"Similar to points and rays, there are types AffineHalfspace, LinearHalfspace, AffineHyperplane and LinearHyperplane:","category":"page"},{"location":"PolyhedralGeometry/intro/","page":"Introduction","title":"Introduction","text":"affine_halfspace\nlinear_halfspace\naffine_hyperplane\nlinear_hyperplane","category":"page"},{"location":"PolyhedralGeometry/intro/#affine_halfspace","page":"Introduction","title":"affine_halfspace","text":"affine_halfspace(p = QQ, a, b)\n\nReturn the Oscar.AffineHalfspace H(a,b), which is given by a vector a and a value b such that H(ab) = x ax b p specifies the Field or Type of its coefficients.\n\n\n\n\n\n","category":"function"},{"location":"PolyhedralGeometry/intro/#linear_halfspace","page":"Introduction","title":"linear_halfspace","text":"linear_halfspace(p = QQ, a, b)\n\nReturn the Oscar.LinearHalfspace H(a), which is given by a vector a such that H(ab) = x ax 0 p specifies the Field or Type of its coefficients.\n\n\n\n\n\n","category":"function"},{"location":"PolyhedralGeometry/intro/#affine_hyperplane","page":"Introduction","title":"affine_hyperplane","text":"affine_hyperplane(p = QQ, a, b)\n\nReturn the Oscar.AffineHyperplane H(a,b), which is given by a vector a and a value b such that H(ab) = x ax = b p specifies the Field or Type of its coefficients.\n\n\n\n\n\n","category":"function"},{"location":"PolyhedralGeometry/intro/#linear_hyperplane","page":"Introduction","title":"linear_hyperplane","text":"linear_hyperplane(p = QQ, a, b)\n\nReturn the Oscar.LinearHyperplane H(a), which is given by a vector a such that H(ab) = x ax = 0 p specifies the Field or Type of its coefficients.\n\n\n\n\n\n","category":"function"},{"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 of this example and the print of an IncidenceMatrix list the non-zero indices for each row.\n\njulia> IM = incidence_matrix([[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":"The unique nature of the IncidenceMatrix allows for different ways of construction:","category":"page"},{"location":"PolyhedralGeometry/intro/","page":"Introduction","title":"Introduction","text":"incidence_matrix","category":"page"},{"location":"PolyhedralGeometry/intro/#incidence_matrix","page":"Introduction","title":"incidence_matrix","text":"incidence_matrix(r::Base.Integer, c::Base.Integer)\n\nReturn an IncidenceMatrix of size r x c whose entries are all false.\n\nExamples\n\njulia> IM = incidence_matrix(8, 5)\n8×5 IncidenceMatrix\n[]\n[]\n[]\n[]\n[]\n[]\n[]\n[]\n\n\n\n\n\n\nincidence_matrix(mat::Union{AbstractMatrix{Bool}, IncidenceMatrix})\n\nConvert mat to an IncidenceMatrix.\n\nExamples\n\njulia> IM = incidence_matrix([true false true false true false; false true false true false true])\n2×6 IncidenceMatrix\n[1, 3, 5]\n[2, 4, 6]\n\n\n\n\n\n\nincidence_matrix(mat::AbstractMatrix)\n\nConvert the 0/1 matrix mat to an IncidenceMatrix. Entries become true if the initial entry is 1 and false if the initial entry is 0.\n\nExamples\n\njulia> IM = incidence_matrix([1 0 1 0 1 0; 0 1 0 1 0 1])\n2×6 IncidenceMatrix\n[1, 3, 5]\n[2, 4, 6]\n\n\n\n\n\n\nincidence_matrix(r::Base.Integer, c::Base.Integer, incidenceRows::AbstractVector{<:AbstractVector{<:Base.Integer}})\n\nReturn an IncidenceMatrix of size r x c. The i-th element of incidenceRows lists the indices of the true entries of the i-th row.\n\nExamples\n\njulia> IM = incidence_matrix(3, 4, [[2, 3], [1]])\n3×4 IncidenceMatrix\n[2, 3]\n[1]\n[]\n\n\n\n\n\n\nincidence_matrix(incidenceRows::AbstractVector{<:AbstractVector{<:Base.Integer}})\n\nReturn an IncidenceMatrix where the i-th element of incidenceRows lists the indices of the true entries of the i-th row. The dimensions of the result are the smallest possible row and column count that can be deduced from the input.\n\nExamples\n\njulia> IM = incidence_matrix([[2, 3], [1]])\n2×3 IncidenceMatrix\n[2, 3]\n[1]\n\n\n\n\n\n\nincidence_matrix(g::Graph{T}) where {T <: Union{Directed, Undirected}}\n\nReturn an unsigned (boolean) incidence matrix representing a graph g.\n\nExamples\n\njulia> g = Graph{Directed}(5);\n\njulia> add_edge!(g, 1, 3);\n\njulia> add_edge!(g, 3, 4);\n\njulia> incidence_matrix(g)\n5×2 IncidenceMatrix\n[1]\n[]\n[1, 2]\n[2]\n[]\n\n\n\n\n\n","category":"function"},{"location":"PolyhedralGeometry/intro/","page":"Introduction","title":"Introduction","text":"From the examples 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 = incidence_matrix([[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 = incidence_matrix([[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::Union{Polyhedron{<:Union{Float64,FieldElem}}, Cone{<:Union{Float64,FieldElem}}, PolyhedralFan{<:Union{Float64,FieldElem}}, PolyhedralComplex{<:Union{Float64,FieldElem}}, SubdivisionOfPoints{<:Union{Float64,FieldElem}}, Graph, SimplicialComplex}; kwargs...)","category":"page"},{"location":"PolyhedralGeometry/intro/#visualize-Tuple{Union{SimplicialComplex, Cone{<:Union{Float64, FieldElem}}, Graph, PolyhedralComplex{<:Union{Float64, FieldElem}}, PolyhedralFan{<:Union{Float64, FieldElem}}, Polyhedron, SubdivisionOfPoints{<:Union{Float64, FieldElem}}}}","page":"Introduction","title":"visualize","text":"visualize(P::Union{Polyhedron{T}, Cone{T}, PolyhedralFan{T}, PolyhedralComplex{T}, SubdivisionOfPoints{T}}; kwargs...) where T<:Union{FieldElem, 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 [Zie95].\n\nIn higher dimensions there is no standard method; use projections to lower dimensions or try ideas from [GJRW10].\n\nExtended help\n\nKeyword Arguments\n\nColors\n\nColors can be given as\n\na literal String, e.g. \"green\".\na String of the format \"r g b\" where r g b in 0 dots 255 are integers corresponding to the R/G/B values of the color.\na String of the format \"r g b\" where r g b in 0 1 are decimal values corresponding to the R/G/B values of the color.\n\nPossible arguments are:\n\nFacetColor: Filling color of the polygons.\nEdgeColor: Color of the boundary lines.\nPointColor/VertexColor: Color of the spheres or rectangles representing the points.\n\nScaling and other gradient properties\n\nThese arguments can be given as a floating point number:\n\nFacetTransparency: Transparency factor of the polygons between 0 (opaque) and 1 (completely translucent).\nEdgeThickness: Scaling factor for the thickness of the boundary lines.\nPointThickness/VertexThickness`: Scaling factor for the size of the spheres or rectangles representing the points.\n\nCamera\n\nThese arguments can be given as a 3-element vector over floating point numbers:\n\nViewPoint: Position of the camera.\nViewDirection: Direction of the camera.\n\nAppearance and Texts\n\nThese arguments can be given as a string:\n\nFacetStyle: If set to \"hidden\", the inner area of the polygons are not rendered at all.\nFacetLabels: If set to \"hidden\", the facet labels are not displayed (in the most cases this is the default behavior). TODO\nEdgeStyle: If set to \"hidden\", the boundary lines are not rendered.\nName: The name of this visual object in the drawing.\nPointLabels/VertexLabels: If set to \"hidden\", no point labels are displayed.\nPointStyle/VertexStyle: If set to \"hidden\", neither point nor its label is rendered.\nLabelAlignment: Defines the alignment of the vertex labels: \"left\", \"right\" or \"center\".\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 [GHJ16]. 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":"","page":"Welcome to OSCAR","title":"Welcome to OSCAR","text":"If you have used OSCAR in the preparation of a paper, please cite it as described here.","category":"page"},{"location":"PolyhedralGeometry/subdivisions_of_points/","page":"Subdivisions of Points","title":"Subdivisions of Points","text":"CurrentModule = Oscar\nDocTestSetup = Oscar.doctestsetup()","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(::Oscar.scalar_type_or_field, Points::Union{Oscar.MatElem,AbstractMatrix}, Incidence::IncidenceMatrix)\nsubdivision_of_points(::Oscar.scalar_type_or_field, Points::Union{Oscar.MatElem,AbstractMatrix}, Weights::AbstractVector)","category":"page"},{"location":"PolyhedralGeometry/subdivisions_of_points/#subdivision_of_points-Tuple{Union{Field, Type{<:Union{Float64, FieldElem}}}, Union{MatElem, AbstractMatrix}, IncidenceMatrix}","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\nwarning: Warning\nIt is required, but not checked, that the cells cover the convex hull of the points. Likewise it is not checked that the cells form a proper polyhedral complex.\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 = incidence_matrix([[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-Tuple{Union{Field, Type{<:Union{Float64, FieldElem}}}, Union{MatElem, AbstractMatrix}, AbstractVector}","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{T}) where T<:scalar_types\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 = incidence_matrix([[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\nOptionally IncidenceMatrix can be passed as a first argument to return the incidence matrix specifying 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 = incidence_matrix([[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\njulia> maximal_cells(IncidenceMatrix, MOAE)\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\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-Union{Tuple{SubdivisionOfPoints{T}}, Tuple{T}} where T<:Union{Float64, FieldElem}","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 = incidence_matrix([[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 = incidence_matrix([[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":"Hecke/howto/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/howto/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/howto/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/howto/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/howto/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/howto/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/howto/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/howto/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/howto/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/howto/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/howto/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":"Experimental/AlgebraicStatistics/markov/","page":"Discrete random variables","title":"Discrete random variables","text":"CurrentModule = Oscar\nDocTestSetup = Oscar.doctestsetup()","category":"page"},{"location":"Experimental/AlgebraicStatistics/markov/#Discrete-random-variables","page":"Discrete random variables","title":"Discrete random variables","text":"","category":"section"},{"location":"Experimental/AlgebraicStatistics/markov/","page":"Discrete random variables","title":"Discrete random variables","text":"The joint probability distribution of random variables X_1 ldots X_n is given by a tensor of order n. If the random variable X_i takes d_i states, the tensor is of format d_1 times cdots times d_n and consists of non-negative real numbers p_x_1 cdots x_n, for all choices x_i in d_i, which sum to 1. The functions below deal with the ambient polynomial ring in these p variables, special forms in them like marginals, and conditional independence ideals.","category":"page"},{"location":"Experimental/AlgebraicStatistics/markov/","page":"Discrete random variables","title":"Discrete random variables","text":"markov_ring(rvs::Pair{<:VarName, <:AbstractArray}...; unknown::VarName=\"p\", K::Field=QQ, cached=false)\ntensor_ring(rvs::Pair{<:VarName, <:AbstractArray}...; unknown::VarName=\"p\", K::Field=QQ, cached=false)\nring(R::MarkovRing)\nrandom_variables(R::MarkovRing)\nci_statements(R::MarkovRing)\nunknowns(R::MarkovRing)\ngens(R::MarkovRing)\nfind_random_variables(R::MarkovRing, K)\nfind_state(R::MarkovRing, K, x)\nstate_space(R::MarkovRing, K=random_variables(R))\nmarginal(R::MarkovRing, K, x)\nci_ideal(R::MarkovRing, stmts)","category":"page"},{"location":"Experimental/AlgebraicStatistics/markov/#markov_ring-Tuple{Vararg{Pair{<:Union{Char, AbstractString, Symbol}, <:AbstractArray}}}","page":"Discrete random variables","title":"markov_ring","text":"markov_ring(rvs::Pair{<:VarName, <:AbstractArray}...; unknown::VarName=\"p\", K::Field=QQ, cached=false)::MarkovRing\ntensor_ring(rvs::Pair{<:VarName, <:AbstractArray}...; unknown::VarName=\"p\", K::Field=QQ, cached=false)::MarkovRing\n\nThe polynomial ring whose unknowns are the entries of a probability tensor. rvs is a list of pairs X => Q where X is the name of a random variable and Q is the list of states it takes. The polynomial ring being constructed will have one variable for each element in the cartesian product of the Qs. It is a multivariate polynomial ring whose variables are named p[...] and whose coefficient field K is by default QQ. These settings can be changed via the optional arguments.\n\nIf cached is true, the internally generated polynomial ring will be cached.\n\nThe name tensor_ring is an alias for the constructor markov_ring because that is really what a MarkovRing is: the coordinate ring of tensors of a fixed format. The name MarkovRing is kept for compatibility in terminology with the Macaulay2 package GraphicalModels.\n\nExamples\n\njulia> R = markov_ring(\"A\" => 1:2, \"B\" => 1:2, \"X\" => 1:2, \"Y\" => 1:2)\nMarkovRing for random variables A -> {1, 2}, B -> {1, 2}, X -> {1, 2}, Y -> {1, 2} in 16 variables over Rational field\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/AlgebraicStatistics/markov/#tensor_ring-Tuple{Vararg{Pair{<:Union{Char, AbstractString, Symbol}, <:AbstractArray}}}","page":"Discrete random variables","title":"tensor_ring","text":"markov_ring(rvs::Pair{<:VarName, <:AbstractArray}...; unknown::VarName=\"p\", K::Field=QQ, cached=false)::MarkovRing\ntensor_ring(rvs::Pair{<:VarName, <:AbstractArray}...; unknown::VarName=\"p\", K::Field=QQ, cached=false)::MarkovRing\n\nThe polynomial ring whose unknowns are the entries of a probability tensor. rvs is a list of pairs X => Q where X is the name of a random variable and Q is the list of states it takes. The polynomial ring being constructed will have one variable for each element in the cartesian product of the Qs. It is a multivariate polynomial ring whose variables are named p[...] and whose coefficient field K is by default QQ. These settings can be changed via the optional arguments.\n\nIf cached is true, the internally generated polynomial ring will be cached.\n\nThe name tensor_ring is an alias for the constructor markov_ring because that is really what a MarkovRing is: the coordinate ring of tensors of a fixed format. The name MarkovRing is kept for compatibility in terminology with the Macaulay2 package GraphicalModels.\n\nExamples\n\njulia> R = markov_ring(\"A\" => 1:2, \"B\" => 1:2, \"X\" => 1:2, \"Y\" => 1:2)\nMarkovRing for random variables A -> {1, 2}, B -> {1, 2}, X -> {1, 2}, Y -> {1, 2} in 16 variables over Rational field\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/AlgebraicStatistics/markov/#ring-Tuple{MarkovRing}","page":"Discrete random variables","title":"ring","text":"ring(R::MarkovRing)\n\nReturn the multivariate polynomial ring inside R.\n\nExamples\n\njulia> R = markov_ring(\"A\" => 1:2, \"B\" => 1:2, \"X\" => 1:2, \"Y\" => 1:2)\nMarkovRing for random variables A -> {1, 2}, B -> {1, 2}, X -> {1, 2}, Y -> {1, 2} in 16 variables over Rational field\n\njulia> ring(R)\nMultivariate polynomial ring in 16 variables p[1, 1, 1, 1], p[2, 1, 1, 1], p[1, 2, 1, 1], p[2, 2, 1, 1], ..., p[2, 2, 2, 2]\n over rational field\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/AlgebraicStatistics/markov/#random_variables-Tuple{MarkovRing}","page":"Discrete random variables","title":"random_variables","text":"random_variables(R::MarkovRing)\n\nReturn the list of random variables used to create the MarkovRing.\n\nExamples\n\njulia> R = markov_ring(\"A\" => 1:2, \"B\" => 1:2, \"X\" => 1:2, \"Y\" => 1:2)\nMarkovRing for random variables A -> {1, 2}, B -> {1, 2}, X -> {1, 2}, Y -> {1, 2} in 16 variables over Rational field\n\njulia> random_variables(R)\n4-element Vector{Union{Char, AbstractString, Symbol}}:\n \"A\"\n \"B\"\n \"X\"\n \"Y\"\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/AlgebraicStatistics/markov/#ci_statements-Tuple{MarkovRing}","page":"Discrete random variables","title":"ci_statements","text":"ci_statements(R::MarkovRing)\n\nReturns all the CIStmt objects which can be formed on the random_variables(R).\n\njulia> R = markov_ring(\"A\" => 1:2, \"B\" => 1:2, \"X\" => 1:2, \"Y\" => 1:2)\nMarkovRing for random variables A -> {1, 2}, B -> {1, 2}, X -> {1, 2}, Y -> {1, 2} in 16 variables over Rational field\n\njulia> ci_statements(R)\n24-element Vector{CIStmt}:\n [A _||_ Y | {}]\n [A _||_ Y | B]\n [A _||_ Y | X]\n [A _||_ Y | {B, X}]\n [B _||_ Y | {}]\n [B _||_ Y | A]\n [B _||_ Y | X]\n [B _||_ Y | {A, X}]\n [X _||_ Y | {}]\n [X _||_ Y | A]\n ⋮\n [A _||_ X | {B, Y}]\n [B _||_ X | {}]\n [B _||_ X | A]\n [B _||_ X | Y]\n [B _||_ X | {A, Y}]\n [A _||_ B | {}]\n [A _||_ B | X]\n [A _||_ B | Y]\n [A _||_ B | {X, Y}]\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/AlgebraicStatistics/markov/#unknowns-Tuple{MarkovRing}","page":"Discrete random variables","title":"unknowns","text":"unknowns(R::MarkovRing)\n\nReturn the generators of the polynomial ring.\n\nExamples\n\njulia> R = markov_ring(\"A\" => 1:2, \"B\" => 1:2, \"X\" => 1:2, \"Y\" => 1:2)\nMarkovRing for random variables A -> {1, 2}, B -> {1, 2}, X -> {1, 2}, Y -> {1, 2} in 16 variables over Rational field\n\njulia> unknowns(R)\nDict{NTuple{4, Int64}, QQMPolyRingElem} with 16 entries:\n (2, 2, 2, 2) => p[2, 2, 2, 2]\n (2, 2, 2, 1) => p[2, 2, 2, 1]\n (1, 2, 1, 2) => p[1, 2, 1, 2]\n (1, 2, 1, 1) => p[1, 2, 1, 1]\n (2, 2, 1, 2) => p[2, 2, 1, 2]\n (2, 2, 1, 1) => p[2, 2, 1, 1]\n (1, 1, 2, 2) => p[1, 1, 2, 2]\n (1, 1, 2, 1) => p[1, 1, 2, 1]\n (2, 1, 2, 2) => p[2, 1, 2, 2]\n (2, 1, 2, 1) => p[2, 1, 2, 1]\n (1, 1, 1, 2) => p[1, 1, 1, 2]\n (1, 1, 1, 1) => p[1, 1, 1, 1]\n (1, 2, 2, 2) => p[1, 2, 2, 2]\n (1, 2, 2, 1) => p[1, 2, 2, 1]\n (2, 1, 1, 2) => p[2, 1, 1, 2]\n (2, 1, 1, 1) => p[2, 1, 1, 1]\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/AlgebraicStatistics/markov/#gens-Tuple{MarkovRing}","page":"Discrete random variables","title":"gens","text":"gens(R::MarkovRing)\n\nAlias for unknowns. Return generators of the polynomial ring.\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/AlgebraicStatistics/markov/#find_random_variables-Tuple{MarkovRing, Any}","page":"Discrete random variables","title":"find_random_variables","text":"find_random_variables(R::MarkovRing, K)\n\nGiven a subset K of random_variables(R) return its indices into the data structure R.random_variables.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/AlgebraicStatistics/markov/#find_state-Tuple{MarkovRing, Any, Any}","page":"Discrete random variables","title":"find_state","text":"find_state(R::MarkovRing, K, x)\n\nGiven a set of random variables K and a joint event x they can take, return the index vector y of x in the data structure R.state_spaces such that x[i] = R.state_spaces[J[i]][v[i]] where J = find_random_variables(R, K).\n\n\n\n\n\n","category":"method"},{"location":"Experimental/AlgebraicStatistics/markov/#state_space","page":"Discrete random variables","title":"state_space","text":"state_space(R::MarkovRing, K=random_variables(R))\n\nReturn all states that the random subvector indexed by K can attain in the ring R. The result is an Iterators.product iterator unless K has only one element in which case it is a vector.\n\nExamples\n\njulia> R = markov_ring(\"A\" => 1:2, \"B\" => 1:2, \"X\" => 1:2, \"Y\" => 1:2)\nMarkovRing for random variables A -> {1, 2}, B -> {1, 2}, X -> {1, 2}, Y -> {1, 2} in 16 variables over Rational field\n\njulia> collect(state_space(R, [\"A\", \"B\"]))\n2×2 Matrix{Tuple{Int64, Int64}}:\n (1, 1) (1, 2)\n (2, 1) (2, 2)\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"function"},{"location":"Experimental/AlgebraicStatistics/markov/#marginal-Tuple{MarkovRing, Any, Any}","page":"Discrete random variables","title":"marginal","text":"marginal(R::MarkovRing, K, x)\n\nReturn a marginal as a sum of unknowns from R. The argument K lists random variables which are fixed to the event x; all other random variables in R are summed over their respective state spaces.\n\nExamples\n\njulia> R = markov_ring(\"A\" => 1:2, \"B\" => 1:2, \"X\" => 1:2, \"Y\" => 1:2)\nMarkovRing for random variables A -> {1, 2}, B -> {1, 2}, X -> {1, 2}, Y -> {1, 2} in 16 variables over Rational field\n\njulia> marginal(R, [\"A\", \"X\"], [1,2])\np[1, 1, 2, 1] + p[1, 2, 2, 1] + p[1, 1, 2, 2] + p[1, 2, 2, 2]\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/AlgebraicStatistics/markov/#ci_ideal-Tuple{MarkovRing, Any}","page":"Discrete random variables","title":"ci_ideal","text":"ci_ideal(R::MarkovRing, stmts)::MPolyIdeal\n\nReturn the ideal for the conditional independence statements given by stmts.\n\nExamples\n\njulia> R = markov_ring(\"A\" => 1:2, \"B\" => 1:2, \"X\" => 1:2)\nMarkovRing for random variables A -> {1, 2}, B -> {1, 2}, X -> {1, 2} in 8 variables over Rational field\n\njulia> ci_ideal(R, [CI\"X,A|B\", CI\"X,B|A\"])\nIdeal generated by\n p[1, 1, 1]*p[2, 1, 2] - p[2, 1, 1]*p[1, 1, 2]\n p[1, 2, 1]*p[2, 2, 2] - p[2, 2, 1]*p[1, 2, 2]\n p[1, 1, 1]*p[1, 2, 2] - p[1, 2, 1]*p[1, 1, 2]\n p[2, 1, 1]*p[2, 2, 2] - p[2, 2, 1]*p[2, 1, 2]\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Rings/rational/","page":"Rationals","title":"Rationals","text":"CurrentModule = Oscar\nDocTestSetup = Oscar.doctestsetup()","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_perfect_power_with_data(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_perfect_power_with_data(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 [Huy16] 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_verbosity_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 [Shi15] 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":"Combinatorics/EnumerativeCombinatorics/tableaux/#Tableaux","page":"Tableaux","title":"Tableaux","text":"","category":"section"},{"location":"Combinatorics/EnumerativeCombinatorics/tableaux/","page":"Tableaux","title":"Tableaux","text":"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 lambda of a non-negative integer n (the total number of boxes of the diagram). The diagram is then said to be of shape lambda. Conversely, one can associate to any partition lambda a Young diagram in the obvious way, so Young diagrams are just another way to look at partitions.","category":"page"},{"location":"Combinatorics/EnumerativeCombinatorics/tableaux/","page":"Tableaux","title":"Tableaux","text":"A Young tableau of shape lambda is a filling of the boxes of the Young diagram of lambda 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.","category":"page"},{"location":"Combinatorics/EnumerativeCombinatorics/tableaux/","page":"Tableaux","title":"Tableaux","text":"In OSCAR, a tableau is internally stored as an array of arrays and is represented by the type YoungTableau{T} which is a subtype of AbstractVector{AbstractVector{T}}, where T is the integer type of the filling. As for partitions, one may increase performance by casting into smaller integer types, e.g. Int8.","category":"page"},{"location":"Combinatorics/EnumerativeCombinatorics/tableaux/","page":"Tableaux","title":"Tableaux","text":"young_tableau","category":"page"},{"location":"Combinatorics/EnumerativeCombinatorics/tableaux/#young_tableau","page":"Tableaux","title":"young_tableau","text":"young_tableau([::Type{T}], v::Vector{Vector{<:IntegerUnion}}; check::Bool = true) where T <: IntegerUnion\n\nReturn the Young tableau given by v as an object of type YoungTableau{T}.\n\nThe element type T may be optionally specified, see also the examples below.\n\nIf check is true (default), it is checked whether v defines a tableau, that is, whether the structure of v defines a partition.\n\nExamples\n\njulia> young_tableau([[1, 2, 3], [4, 5], [6]])\n+---+---+---+\n| 1 | 2 | 3 |\n+---+---+---+\n| 4 | 5 |\n+---+---+\n| 6 |\n+---+\n\njulia> young_tableau(Int8, [[1, 2, 3], [4, 5], [6]]) # save the elements in 8-bit integers\n+---+---+---+\n| 1 | 2 | 3 |\n+---+---+---+\n| 4 | 5 |\n+---+---+\n| 6 |\n+---+\n\n\n\n\n\n","category":"function"},{"location":"Combinatorics/EnumerativeCombinatorics/tableaux/#Operations","page":"Tableaux","title":"Operations","text":"","category":"section"},{"location":"Combinatorics/EnumerativeCombinatorics/tableaux/","page":"Tableaux","title":"Tableaux","text":"hook_length\nhook_lengths\nshape\nweight\nreading_word","category":"page"},{"location":"Combinatorics/EnumerativeCombinatorics/tableaux/#hook_length","page":"Tableaux","title":"hook_length","text":"hook_length(tab::YoungTableau, i::Integer, j::Integer)\nhook_length(lambda::Partition, i::Integer, j::Integer)\n\nReturn the hook length of the box with coordinates (i, j) in the Young tableau tab respectively the Young diagram of shape lambda.\n\nThe 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.\n\nSee also hook_lengths.\n\n\n\n\n\n","category":"function"},{"location":"Combinatorics/EnumerativeCombinatorics/tableaux/#hook_lengths","page":"Tableaux","title":"hook_lengths","text":"hook_lengths(lambda::Partition)\n\nReturn the Young tableau of shape lambda in which the entry at position (i, j) is equal to the hook length of the corresponding box.\n\nSee also hook_length.\n\n\n\n\n\n","category":"function"},{"location":"Combinatorics/EnumerativeCombinatorics/tableaux/#shape","page":"Tableaux","title":"shape","text":"shape(tab::YoungTableau)\n\nReturn the shape of the tableau tab, i.e. the partition given by the lengths of the rows of the tableau.\n\n\n\n\n\n","category":"function"},{"location":"Combinatorics/EnumerativeCombinatorics/tableaux/#weight","page":"Tableaux","title":"weight","text":"weight(tab::YoungTableau)\n\nReturn the weight of the tableau tab as 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/EnumerativeCombinatorics/tableaux/#reading_word","page":"Tableaux","title":"reading_word","text":"reading_word(tab::YoungTableau)\n\nReturn the reading word of the tableau tab as an array, i.e. the word obtained by concatenating the fillings of the rows, starting from the bottom row.\n\nExamples\n\njulia> reading_word(young_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/EnumerativeCombinatorics/tableaux/#Semistandard-tableaux","page":"Tableaux","title":"Semistandard tableaux","text":"","category":"section"},{"location":"Combinatorics/EnumerativeCombinatorics/tableaux/","page":"Tableaux","title":"Tableaux","text":"is_semistandard\nsemistandard_tableaux","category":"page"},{"location":"Combinatorics/EnumerativeCombinatorics/tableaux/#is_semistandard","page":"Tableaux","title":"is_semistandard","text":"is_semistandard(tab::YoungTableau)\n\nReturn true if the tableau tab is semistandard and false otherwise.\n\nA tableau is called semistandard if the entries weakly increase along each row and strictly increase down each column.\n\nSee also is_standard.\n\n\n\n\n\n","category":"function"},{"location":"Combinatorics/EnumerativeCombinatorics/tableaux/#semistandard_tableaux","page":"Tableaux","title":"semistandard_tableaux","text":"semistandard_tableaux(shape::Partition{T}, max_val::T = sum(shape)) where T <: IntegerUnion\nsemistandard_tableaux(shape::Vector{T}, max_val::T = sum(shape)) where T <: IntegerUnion\n\nReturn an iterator over all semistandard Young tableaux of given shape shape and filling elements bounded by max_val.\n\nBy default, max_val is equal to the sum of the shape partition (the number of boxes in the Young diagram).\n\nThe list of tableaux is in lexicographic order from left to right and top to bottom.\n\n\n\n\n\nsemistandard_tableaux(box_num::T, max_val::T = box_num) where T <: Integer\n\nReturn an iterator over all semistandard Young tableaux consisting of box_num boxes and filling elements bounded by max_val.\n\n\n\n\n\nsemistandard_tableaux(s::Partition{T}, weight::Vector{T}) where T <: Integer\nsemistandard_tableaux(s::Vector{T}, weight::Vector{T}) where T <: Integer\n\nReturn an iterator over all semistandard Young tableaux with shape s and given weight. This requires that sum(s) = sum(weight).\n\n\n\n\n\n","category":"function"},{"location":"Combinatorics/EnumerativeCombinatorics/tableaux/#Standard-tableaux","page":"Tableaux","title":"Standard tableaux","text":"","category":"section"},{"location":"Combinatorics/EnumerativeCombinatorics/tableaux/","page":"Tableaux","title":"Tableaux","text":"is_standard\nstandard_tableaux","category":"page"},{"location":"Combinatorics/EnumerativeCombinatorics/tableaux/#is_standard","page":"Tableaux","title":"is_standard","text":"is_standard(tab::YoungTableau)\n\nReturn true if the tableau tab is standard and false otherwise.\n\nA tableau is called standard if it is semistandard and the entries are in bijection with 1, ..., n, where n is the number of boxes.\n\nSee also is_semistandard.\n\n\n\n\n\n","category":"function"},{"location":"Combinatorics/EnumerativeCombinatorics/tableaux/#standard_tableaux","page":"Tableaux","title":"standard_tableaux","text":"standard_tableaux(s::Partition)\nstandard_tableaux(s::Vector{Integer})\n\nReturn an iterator over all standard Young tableaux of a given shape s.\n\n\n\n\n\nstandard_tableaux(n::IntegerUnion)\n\nReturn an iterator over all standard Young tableaux with n boxes.\n\n\n\n\n\n","category":"function"},{"location":"Combinatorics/EnumerativeCombinatorics/tableaux/","page":"Tableaux","title":"Tableaux","text":"number_of_standard_tableaux","category":"page"},{"location":"Combinatorics/EnumerativeCombinatorics/tableaux/#number_of_standard_tableaux","page":"Tableaux","title":"number_of_standard_tableaux","text":"number_of_standard_tableaux(lambda::Partition)\n\nReturn the number of standard Young tableaux of shape lambda.\n\n\n\n\n\n","category":"function"},{"location":"Combinatorics/EnumerativeCombinatorics/tableaux/","page":"Tableaux","title":"Tableaux","text":"The number f^lambda of standard Young tableaux of shape lambda is computed using the hook length formula","category":"page"},{"location":"Combinatorics/EnumerativeCombinatorics/tableaux/","page":"Tableaux","title":"Tableaux","text":"f^lambda = fracnprod_i j h_lambda(i j)","category":"page"},{"location":"Combinatorics/EnumerativeCombinatorics/tableaux/","page":"Tableaux","title":"Tableaux","text":"where the product is taken over all boxes in the Young diagram of lambda and h_lambda denotes the hook length of the box (i j).","category":"page"},{"location":"Combinatorics/EnumerativeCombinatorics/tableaux/","page":"Tableaux","title":"Tableaux","text":"schensted\nbump!","category":"page"},{"location":"Combinatorics/EnumerativeCombinatorics/tableaux/#schensted","page":"Tableaux","title":"schensted","text":"schensted(sigma::Vector{<:IntegerUnion})\nschensted(sigma::PermGroupElem)\n\nReturn the pair of standard Young tableaux (the insertion and the recording tableau) corresponding to the permutation sigma under the Robinson-Schensted correspondence.\n\nExamples\n\njulia> P, Q = schensted([3, 1, 6, 2, 5, 4]);\n\njulia> P\n+---+---+---+\n| 1 | 2 | 4 |\n+---+---+---+\n| 3 | 5 |\n+---+---+\n| 6 |\n+---+\n\njulia> Q\n+---+---+---+\n| 1 | 3 | 5 |\n+---+---+---+\n| 2 | 4 |\n+---+---+\n| 6 |\n+---+\n\n\n\n\n\n\n","category":"function"},{"location":"Combinatorics/EnumerativeCombinatorics/tableaux/#bump!","page":"Tableaux","title":"bump!","text":"bump!(tab::YoungTableau, x::Int)\n\nInsert the integer x into the tableau tab according to the bumping algorithm by applying the Schensted insertion.\n\n\n\n\n\nbump!(tab::YoungTableau, x::Integer, Q::YoungTableau, y::Integer)\n\nInsert the integer x into tab according to the bumping algorithm by applying the Schensted insertion and insert the integer y into Q at the same position as x in tab.\n\n\n\n\n\n","category":"function"},{"location":"Hecke/manual/quad_forms/discriminant_group/#Discriminant-Groups","page":"Discriminant Groups","title":"Discriminant Groups","text":"","category":"section"},{"location":"Hecke/manual/quad_forms/discriminant_group/","page":"Discriminant Groups","title":"Discriminant Groups","text":"CurrentModule = Hecke\nDocTestSetup = quote\n using Hecke\n end","category":"page"},{"location":"Hecke/manual/quad_forms/discriminant_group/#Torsion-Quadratic-Modules","page":"Discriminant Groups","title":"Torsion Quadratic Modules","text":"","category":"section"},{"location":"Hecke/manual/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/manual/quad_forms/discriminant_group/","page":"Discriminant Groups","title":"Discriminant Groups","text":"b MN times MN to mathbbQ n mathbbZ","category":"page"},{"location":"Hecke/manual/quad_forms/discriminant_group/","page":"Discriminant Groups","title":"Discriminant Groups","text":"as well as a quadratic form","category":"page"},{"location":"Hecke/manual/quad_forms/discriminant_group/","page":"Discriminant Groups","title":"Discriminant Groups","text":"q MN to mathbbQ m mathbbZ","category":"page"},{"location":"Hecke/manual/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/manual/quad_forms/discriminant_group/","page":"Discriminant Groups","title":"Discriminant Groups","text":"torsion_quadratic_module(M::ZZLat, N::ZZLat)","category":"page"},{"location":"Hecke/manual/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::RationalUnion = QQFieldElem(0),\n modulus_qf::RationalUnion = 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\nOne can decide on the modulus for the associated finite bilinear and quadratic forms by setting modulus and modulus_qf respectively to the desired values.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/quad_forms/discriminant_group/#The-underlying-Type","page":"Discriminant Groups","title":"The underlying Type","text":"","category":"section"},{"location":"Hecke/manual/quad_forms/discriminant_group/","page":"Discriminant Groups","title":"Discriminant Groups","text":"TorQuadModule","category":"page"},{"location":"Hecke/manual/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)\n(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(basis_matrix(M), v; side = :left).\n\n\n\n\n\n","category":"type"},{"location":"Hecke/manual/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/manual/quad_forms/discriminant_group/#Attributes","page":"Discriminant Groups","title":"Attributes","text":"","category":"section"},{"location":"Hecke/manual/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/manual/quad_forms/discriminant_group/#abelian_group-Tuple{TorQuadModule}","page":"Discriminant Groups","title":"abelian_group","text":"abelian_group(T::TorQuadModule) -> FinGenAbGroup\n\nReturn the underlying abelian group of T.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/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/manual/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/manual/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/manual/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/manual/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/manual/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/manual/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/manual/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/manual/quad_forms/discriminant_group/#Elements","page":"Discriminant Groups","title":"Elements","text":"","category":"section"},{"location":"Hecke/manual/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/manual/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/manual/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/manual/quad_forms/discriminant_group/#Lift-to-the-cover","page":"Discriminant Groups","title":"Lift to the cover","text":"","category":"section"},{"location":"Hecke/manual/quad_forms/discriminant_group/","page":"Discriminant Groups","title":"Discriminant Groups","text":"lift(a::TorQuadModuleElem)\nrepresentative(::TorQuadModuleElem)","category":"page"},{"location":"Hecke/manual/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/manual/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/manual/quad_forms/discriminant_group/#Orthogonal-submodules","page":"Discriminant Groups","title":"Orthogonal submodules","text":"","category":"section"},{"location":"Hecke/manual/quad_forms/discriminant_group/","page":"Discriminant Groups","title":"Discriminant Groups","text":"orthogonal_submodule(T::TorQuadModule, S::TorQuadModule)","category":"page"},{"location":"Hecke/manual/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/manual/quad_forms/discriminant_group/#Isometry","page":"Discriminant Groups","title":"Isometry","text":"","category":"section"},{"location":"Hecke/manual/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/manual/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, TorQuadModuleMap\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: finite quadratic module -> finite quadratic module)\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: finite quadratic module -> finite quadratic module)\n\njulia> U2, _ = sub(T, [T[4], T[2]+T[3]+T[5]])\n(Finite quadratic module: (Z/3)^2 -> Q/2Z, Map: finite quadratic module -> finite quadratic module)\n\njulia> bool, phi = is_isometric_with_isometry(U2, T2)\n(true, Map: finite quadratic module -> finite quadratic module)\n\njulia> is_bijective(phi)\ntrue\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/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, TorQuadModuleMap\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: finite quadratic module -> finite quadratic module)\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: finite quadratic module -> finite quadratic module)\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/manual/quad_forms/discriminant_group/#Primary-and-elementary-modules","page":"Discriminant Groups","title":"Primary and elementary modules","text":"","category":"section"},{"location":"Hecke/manual/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/manual/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/manual/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/manual/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/manual/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/manual/quad_forms/discriminant_group/#Smith-normal-form","page":"Discriminant Groups","title":"Smith normal form","text":"","category":"section"},{"location":"Hecke/manual/quad_forms/discriminant_group/","page":"Discriminant Groups","title":"Discriminant Groups","text":"snf(T::TorQuadModule)\nis_snf(T::TorQuadModule)","category":"page"},{"location":"Hecke/manual/quad_forms/discriminant_group/#snf-Tuple{TorQuadModule}","page":"Discriminant Groups","title":"snf","text":"snf(T::TorQuadModule) -> TorQuadModule, TorQuadModuleMap\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/manual/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/manual/quad_forms/discriminant_group/#Discriminant-Groups-2","page":"Discriminant Groups","title":"Discriminant Groups","text":"","category":"section"},{"location":"Hecke/manual/quad_forms/discriminant_group/","page":"Discriminant Groups","title":"Discriminant Groups","text":"See [Nik79] 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/manual/quad_forms/discriminant_group/#From-a-lattice","page":"Discriminant Groups","title":"From a lattice","text":"","category":"section"},{"location":"Hecke/manual/quad_forms/discriminant_group/","page":"Discriminant Groups","title":"Discriminant Groups","text":"discriminant_group(::ZZLat)","category":"page"},{"location":"Hecke/manual/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/manual/quad_forms/discriminant_group/#From-a-matrix","page":"Discriminant Groups","title":"From a matrix","text":"","category":"section"},{"location":"Hecke/manual/quad_forms/discriminant_group/","page":"Discriminant Groups","title":"Discriminant Groups","text":"torsion_quadratic_module(q::QQMatrix)","category":"page"},{"location":"Hecke/manual/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/manual/quad_forms/discriminant_group/#Rescaling-the-form","page":"Discriminant Groups","title":"Rescaling the form","text":"","category":"section"},{"location":"Hecke/manual/quad_forms/discriminant_group/","page":"Discriminant Groups","title":"Discriminant Groups","text":"rescale(T::TorQuadModule, k::RingElement)","category":"page"},{"location":"Hecke/manual/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/manual/quad_forms/discriminant_group/#Invariants","page":"Discriminant Groups","title":"Invariants","text":"","category":"section"},{"location":"Hecke/manual/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/manual/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/manual/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/manual/quad_forms/discriminant_group/#radical_bilinear-Tuple{TorQuadModule}","page":"Discriminant Groups","title":"radical_bilinear","text":"radical_bilinear(T::TorQuadModule) -> TorQuadModule, TorQuadModuleMap\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/manual/quad_forms/discriminant_group/#radical_quadratic-Tuple{TorQuadModule}","page":"Discriminant Groups","title":"radical_quadratic","text":"radical_quadratic(T::TorQuadModule) -> TorQuadModule, TorQuadModuleMap\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/manual/quad_forms/discriminant_group/#normal_form-Tuple{TorQuadModule}","page":"Discriminant Groups","title":"normal_form","text":"normal_form(T::TorQuadModule; partial=false) -> TorQuadModule, TorQuadModuleMap\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/manual/quad_forms/discriminant_group/#Genus","page":"Discriminant Groups","title":"Genus","text":"","category":"section"},{"location":"Hecke/manual/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/manual/quad_forms/discriminant_group/#genus-Tuple{TorQuadModule, Tuple{Int64, Int64}}","page":"Discriminant Groups","title":"genus","text":"genus(T::TorQuadModule, signature_pair::Tuple{Int, Int};\n parity::RationalUnion = modulus_quadratic_form(T))\n -> ZZGenus\n\nReturn the genus of an integer lattice whose discriminant group has the bilinear form of T, the given signature_pair and the given parity.\n\nThe argument parity is one of the following: either parity == 1 for genera of odd lattices, or parity == 2 for even lattices. By default, parity is set to be as the parity of the quadratic form on T\n\nIf no such genus exists, raise an error.\n\nReference\n\n[Nik79] Corollary 1.9.4 and 1.16.3.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/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/manual/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};\n parity::RationalUnion = modulus_quadratic_form(T)) -> Bool\n\nReturn if there is an integral lattice whose discriminant form has the bilinear form of T, whose signatures match signature_pair and which is of parity parity.\n\nThe argument parity is one of the following: either parity == 1 for genera of odd lattices, or parity == 2 for even lattices. By default, parity is set to be as the parity of the quadratic form on T\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/quad_forms/discriminant_group/#Categorical-constructions","page":"Discriminant Groups","title":"Categorical constructions","text":"","category":"section"},{"location":"Hecke/manual/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/manual/quad_forms/discriminant_group/#direct_sum-Tuple{Vector{TorQuadModule}}","page":"Discriminant Groups","title":"direct_sum","text":"direct_sum(x::Vararg{TorQuadModule}) -> TorQuadModule, Vector{TorQuadModuleMap}\ndirect_sum(x::Vector{TorQuadModule}) -> TorQuadModule, Vector{TorQuadModuleMap}\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/manual/quad_forms/discriminant_group/#direct_product-Tuple{Vector{TorQuadModule}}","page":"Discriminant Groups","title":"direct_product","text":"direct_product(x::Vararg{TorQuadModule}) -> TorQuadModule, Vector{TorQuadModuleMap}\ndirect_product(x::Vector{TorQuadModule}) -> TorQuadModule, Vector{TorQuadModuleMap}\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/manual/quad_forms/discriminant_group/#biproduct-Tuple{Vector{TorQuadModule}}","page":"Discriminant Groups","title":"biproduct","text":"biproduct(x::Vararg{TorQuadModule}) -> TorQuadModule, Vector{TorQuadModuleMap}, Vector{TorQuadModuleMap}\nbiproduct(x::Vector{TorQuadModule}) -> TorQuadModule, Vector{TorQuadModuleMap}, Vector{TorQuadModuleMap}\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/manual/quad_forms/discriminant_group/#Submodules","page":"Discriminant Groups","title":"Submodules","text":"","category":"section"},{"location":"Hecke/manual/quad_forms/discriminant_group/","page":"Discriminant Groups","title":"Discriminant Groups","text":"submodules(::TorQuadModule)\nstable_submodules(::TorQuadModule, ::Vector{TorQuadModuleMap})","category":"page"},{"location":"Hecke/manual/quad_forms/discriminant_group/#submodules-Tuple{TorQuadModule}","page":"Discriminant Groups","title":"submodules","text":"submodules(T::TorQuadModule; 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/manual/quad_forms/discriminant_group/#stable_submodules-Tuple{TorQuadModule, Vector{TorQuadModuleMap}}","page":"Discriminant Groups","title":"stable_submodules","text":"stable_submodules(T::TorQuadModule, act::Vector{TorQuadModuleMap}; 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/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 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/","page":"Ring functionality","title":"Ring functionality","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/","page":"Ring functionality","title":"Ring functionality","text":"Note the exclamation point is a convention, which indicates that the object may be mutated in-place.","category":"page"},{"location":"AbstractAlgebra/ring/","page":"Ring functionality","title":"Ring functionality","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/","page":"Ring functionality","title":"Ring functionality","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/","page":"Ring functionality","title":"Ring functionality","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/","page":"Ring functionality","title":"Ring functionality","text":"zero!\none!\nadd!\nsub!\nmul!\nneg!\ninv!\naddmul!\nsubmul!\ndivexact!\ndiv!\nrem!\nmod!\ngcd!\nlcm!","category":"page"},{"location":"AbstractAlgebra/ring/#zero!","page":"Ring functionality","title":"zero!","text":"zero!(a)\n\nReturn zero(parent(a)), possibly modifying the object a in the process.\n\n\n\n\n\n","category":"function"},{"location":"AbstractAlgebra/ring/#one!","page":"Ring functionality","title":"one!","text":"one!(a)\n\nReturn one(parent(a)), possibly modifying the object a in the process.\n\n\n\n\n\n","category":"function"},{"location":"AbstractAlgebra/ring/#add!","page":"Ring functionality","title":"add!","text":"add!(z, a, b)\nadd!(a, b)\n\nReturn a + b, possibly modifying the object z in the process. Aliasing is permitted. The two argument version is a shorthand for add!(a, a, b).\n\n\n\n\n\n","category":"function"},{"location":"AbstractAlgebra/ring/#sub!","page":"Ring functionality","title":"sub!","text":"sub!(z, a, b)\nsub!(a, b)\n\nReturn a - b, possibly modifying the object z in the process. Aliasing is permitted. The two argument version is a shorthand for sub!(a, a, b).\n\n\n\n\n\n","category":"function"},{"location":"AbstractAlgebra/ring/#mul!","page":"Ring functionality","title":"mul!","text":"mul!(z, a, b)\nmul!(a, b)\n\nReturn a * b, possibly modifying the object z in the process. Aliasing is permitted. The two argument version is a shorthand for mul!(a, a, b).\n\n\n\n\n\n","category":"function"},{"location":"AbstractAlgebra/ring/#neg!","page":"Ring functionality","title":"neg!","text":"neg!(z, a)\nneg!(a)\n\nReturn -a, possibly modifying the object z in the process. Aliasing is permitted. The unary version is a shorthand for neg!(a, a).\n\n\n\n\n\n","category":"function"},{"location":"AbstractAlgebra/ring/#inv!","page":"Ring functionality","title":"inv!","text":"inv!(z, a)\ninv!(a)\n\nReturn AbstractAlgebra.inv(a), possibly modifying the object z in the process. Aliasing is permitted. The unary version is a shorthand for inv!(a, a).\n\nnote: Note\nAbstractAlgebra.inv and Base.inv differ only in their behavior on julia types like Integer and Rational{Int}. The former makes it adhere to the Ring interface.\n\n\n\n\n\n","category":"function"},{"location":"AbstractAlgebra/ring/#addmul!","page":"Ring functionality","title":"addmul!","text":"addmul!(z, a, b, t)\naddmul!(z, a, b)\n\nReturn z + a * b, possibly modifying the objects z and t in the process.\n\nThe second version is usually a shorthand for addmul!(z, a, b, parent(z)()), but in some cases may be more efficient. For multiple operations in a row that use temporary storage, it is still best to use the four argument version.\n\n\n\n\n\n","category":"function"},{"location":"AbstractAlgebra/ring/#submul!","page":"Ring functionality","title":"submul!","text":"submul!(z, a, b, t)\nsubmul!(z, a, b)\n\nReturn z - a * b, possibly modifying the objects z and t in the process.\n\nThe second version is usually a shorthand for submul!(z, a, b, parent(z)()), but in some cases may be more efficient. For multiple operations in a row that use temporary storage, it is still best to use the four argument version.\n\n\n\n\n\n","category":"function"},{"location":"AbstractAlgebra/ring/#divexact!","page":"Ring functionality","title":"divexact!","text":"divexact!(A::Generic.Mat{AbsSimpleNumFieldElem}, p::ZZRingElem)\n\nInplace: divide each entry of A by p.\n\n\n\n\n\ndivexact!(z, a, b)\ndivexact!(a, b)\n\nReturn divexact(a, b), possibly modifying the object z in the process. Aliasing is permitted. The two argument version is a shorthand for divexact(a, a, b).\n\n\n\n\n\n","category":"function"},{"location":"AbstractAlgebra/ring/#div!","page":"Ring functionality","title":"div!","text":"div!(z, a, b)\ndiv!(a, b)\n\nReturn div(a, b), possibly modifying the object z in the process. Aliasing is permitted. The two argument version is a shorthand for div(a, a, b).\n\nnote: Note\nAbstractAlgebra.div and Base.div differ only in their behavior on julia types like Integer and Rational{Int}. The former makes it adhere to the Ring interface.\n\n\n\n\n\n","category":"function"},{"location":"AbstractAlgebra/ring/#rem!","page":"Ring functionality","title":"rem!","text":"rem!(z, a, b)\nrem!(a, b)\n\nReturn rem(a, b), possibly modifying the object z in the process. Aliasing is permitted. The two argument version is a shorthand for rem(a, a, b).\n\n\n\n\n\n","category":"function"},{"location":"AbstractAlgebra/ring/#mod!","page":"Ring functionality","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\nmod!(A::Generic.Mat{AbsSimpleNumFieldElem}, m::ZZRingElem)\n\nInplace: reduce all entries of A modulo m, into the positive residue system.\n\n\n\n\n\nmod!(z, a, b)\nmod!(a, b)\n\nReturn mod(a, b), possibly modifying the object z in the process. Aliasing is permitted. The two argument version is a shorthand for mod(a, a, b).\n\n\n\n\n\nmod!(A::SRow{ZZRingElem}, n::Integer) -> SRow{ZZRingElem}\n\nInplace reduction of all entries of A modulo n to the positive residue system.\n\n\n\n\n\nmod!(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":"function"},{"location":"AbstractAlgebra/ring/#gcd!","page":"Ring functionality","title":"gcd!","text":"gcd!(z, a, b)\ngcd!(a, b)\n\nReturn gcd(a, b), possibly modifying the object z in the process. Aliasing is permitted. The two argument version is a shorthand for gcd(a, a, b).\n\n\n\n\n\n","category":"function"},{"location":"AbstractAlgebra/ring/#lcm!","page":"Ring functionality","title":"lcm!","text":"lcm!(z, a, b)\nlcm!(a, b)\n\nReturn lcm(a, b), possibly modifying the object z in the process. Aliasing is permitted. The two argument version is a shorthand for lcm(a, a, b).\n\n\n\n\n\n","category":"function"},{"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/#is_irreducible-Tuple{T} where T<:RingElement","page":"Ring functionality","title":"is_irreducible","text":"is_irreducible(a::RingElement)\n\nReturn true if a is irreducible, else return false. Zero and units are by definition never irreducible.\n\n\n\n\n\n","category":"method"},{"location":"AbstractAlgebra/ring/#is_squarefree-Tuple{T} where T<:RingElement","page":"Ring functionality","title":"is_squarefree","text":"is_squarefree(a::RingElement)\n\nReturn true if a is squarefree, else return false. An element is squarefree if it it is not divisible by any squares except the squares of units.\n\n\n\n\n\n","category":"method"},{"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\nSee unit(a::Fac), evaluate(a::Fac).\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":"NumberTheory/vinberg/","page":"Vinberg's algorithm","title":"Vinberg's algorithm","text":"CurrentModule = Oscar\nDocTestSetup = Oscar.doctestsetup()","category":"page"},{"location":"NumberTheory/vinberg/#Vinberg's-algorithm","page":"Vinberg's algorithm","title":"Vinberg's algorithm","text":"","category":"section"},{"location":"NumberTheory/vinberg/","page":"Vinberg's algorithm","title":"Vinberg's algorithm","text":"A Lorentzian lattice L is an integral Z-lattice of signature (s_+ s_-) with s_+=1 and s_-0. A root of r in L is a primitive vector s.t. reflection in the hyperplane r^perp maps L to itself. Let W(L)leq O(L) be the Weyl group, that is the group generated by reflections in the root hyperplanes of L. We say that L is reflective if W(L) is of finite index in O(L). For xy in L we write xy=Phi(xy) and x^2=Phi(xx) for the symmetric bilinear form in L.","category":"page"},{"location":"NumberTheory/vinberg/","page":"Vinberg's algorithm","title":"Vinberg's algorithm","text":"See for example [Tur18] for the theory of Arithmetic Reflection Groups and Reflective Lorentzian Lattices.","category":"page"},{"location":"NumberTheory/vinberg/#Description","page":"Vinberg's algorithm","title":"Description","text":"","category":"section"},{"location":"NumberTheory/vinberg/","page":"Vinberg's algorithm","title":"Vinberg's algorithm","text":"Vinberg's algorithm constructs a fundamental polyhedron P for a Lorentzian lattice L by computing its fundamental roots r, i.e. the roots r which are perpendicular to the faces of P and which have inner product at least 0 with the elements of P. Choose v_0 in L primitive with v_0^2 0 as a point that P should contain.","category":"page"},{"location":"NumberTheory/vinberg/","page":"Vinberg's algorithm","title":"Vinberg's algorithm","text":"Let Q be the Gram matrix of L with respect to some basis. A vector r is a fundamental root, if","category":"page"},{"location":"NumberTheory/vinberg/","page":"Vinberg's algorithm","title":"Vinberg's algorithm","text":"the vector r is primitive,\nreflection by r preserves the lattice, i.e. frac2r^2 r Q is an integer matrix,\nthe pair (r v_0) is positive oriented, i.e. r v_0 0,\nthe product r r geq 0 for all roots r already found.","category":"page"},{"location":"NumberTheory/vinberg/","page":"Vinberg's algorithm","title":"Vinberg's algorithm","text":"This implies that r^2 divides 2 i for i being the level of Q, i.e. the last invariant of the Smith normal form of Q. ","category":"page"},{"location":"NumberTheory/vinberg/","page":"Vinberg's algorithm","title":"Vinberg's algorithm","text":"P can be constructed by solving rv_0 = n and r^2 = k by increasing order of the value fracn^2k and r satisfying the above conditions.","category":"page"},{"location":"NumberTheory/vinberg/","page":"Vinberg's algorithm","title":"Vinberg's algorithm","text":"If v_0 lies on a root hyperplane, then P is not uniquely determined. In that case we need a direction vector v_1 which satisfies v v_1 neq 0 for all possible roots v with v_0 v = 0 ","category":"page"},{"location":"NumberTheory/vinberg/","page":"Vinberg's algorithm","title":"Vinberg's algorithm","text":"With v_0 and v_1 fixed P is uniquely determined for any choice of root lengths and maximal distance v_0r. We choose the first roots r by increasing order of the value fracr v_1r^2 for all possible roots v with v_0 v = 0. For any other root length we continue as stated above.","category":"page"},{"location":"NumberTheory/vinberg/","page":"Vinberg's algorithm","title":"Vinberg's algorithm","text":"For proofs of the statements above and further explanations see [Vin75].","category":"page"},{"location":"NumberTheory/vinberg/#Function","page":"Vinberg's algorithm","title":"Function","text":"","category":"section"},{"location":"NumberTheory/vinberg/","page":"Vinberg's algorithm","title":"Vinberg's algorithm","text":"vinberg_algorithm","category":"page"},{"location":"NumberTheory/vinberg/#vinberg_algorithm","page":"Vinberg's algorithm","title":"vinberg_algorithm","text":"vinberg_algorithm(Q::ZZMatrix, upper_bound; v0::ZZMatrix, root_lengths::Vector{ZZRingElem}, direction_vector::ZZMatrix) -> Vector{ZZMatrix}\n\nReturn the fundamental roots r of a given hyperbolic reflection lattice with standard basis represented by its corresponding Gram matrix Q with squared length contained in root_lengths and by increasing order of the value fracrv_0)^2r^2, stopping at upper_bound. If root_lengths is not defined it takes all possible values of r^2. If v0 lies on a root hyperplane and if there is no given direction_vector it is a random choice which reflection chamber next to v0 will be computed.\n\nArguments\n\nQ: symmetric Z matrix of signature (1 n) – the corresponding Gram matrix\nupper_bound: the upper bound of the value frac(rv_0^2r^2\nv0: primitive row vector with v_0^2 0\nroot_lengths: the possible integer values of r^2\ndirection_vector: row vector v1 with v_0v_1 = 0 and vv_1 neq 0 for all possible roots v with vv_0 = 0\n\n\n\n\n\nvinberg_algorithm(S::ZZLat, upper_bound; v0::ZZMatrix, root_lengths::Vector{ZZRingElem}, direction_vector::ZZMatrix) -> Vector{ZZMatrix}\n\nReturn the fundamental roots r of a given hyperbolic reflection lattice S with standard basis with squared length contained in root_lengths and by increasing order of the value fracrv_0)^2r^2, stopping at upper_bound. If root_lengths is not defined it takes all possible values of r^2. If v0 lies on a root hyperplane and if there is no given direction_vector, then it is a random choice which reflection chamber next to v0 will be computed.\n\nArguments\n\nS: a hyperbolic Z-lattice of signature (10n).\nupper_bound: the upper bound of the value frac(rv_0^2r^2\nv0: primitive row vector with v_0^2 0 given w.r.t. the ambient space\nroot_lengths: the possible integer values of r^2\ndirection_vector: row vector v1 with v_0v_1 = 0 and vv_1 neq 0 for all possible roots v with vv_0 = 0, given w.r.t. the ambient space\ndivisibilities: a dictionary; The keys are the root lengths and the values are the divisibilities for the given root length. If given requires that a fundamental root r has one of the specified divisibilities.\n\n\n\n\n\n","category":"function"},{"location":"NumberTheory/vinberg/#Contact","page":"Vinberg's algorithm","title":"Contact","text":"","category":"section"},{"location":"NumberTheory/vinberg/","page":"Vinberg's algorithm","title":"Vinberg's algorithm","text":"Please direct questions about this part of OSCAR to the following people:","category":"page"},{"location":"NumberTheory/vinberg/","page":"Vinberg's algorithm","title":"Vinberg's algorithm","text":"Simon Brandhorst.\nStevell Muller,","category":"page"},{"location":"NumberTheory/vinberg/","page":"Vinberg's algorithm","title":"Vinberg's algorithm","text":"You can ask questions in the OSCAR Slack.","category":"page"},{"location":"NumberTheory/vinberg/","page":"Vinberg's algorithm","title":"Vinberg's algorithm","text":"Alternatively, you can raise an issue on github.","category":"page"},{"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 [AG10], 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.","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\nLet G = group(L) and let H be the subgroup generated by the pseudo-reflections contained in G. By a theorem of Arzhantsev–Gaifullin [AG10], the Cox ring is graded isomorphic to the invariant ring of the group H[G,G], where [G,G] is the derived subgroup of G. We use ideas from [DK17] 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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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 [Yam18].","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 [Yam18].\n\n\n\n\n\n","category":"method"},{"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 R\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> Rg, (x, y, z) = graded_polynomial_ring(QQ, [: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*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*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\ny*e[1] -> y*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 R\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> Rg, (x, y, z) = graded_polynomial_ring(QQ, [: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> Rg, (x, y, z) = graded_polynomial_ring(QQ, [:x, :y, :z]);\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\ncokernel(F::FreeMod{R}, A::MatElem{R}) where R\n\nReturn the cokernel of A as an object of type SubquoModule with ambient free module F.\n\nExamples\n\njulia> R, (x,y,z) = polynomial_ring(QQ, [:x, :y, :z]);\n\njulia> F = free_module(R, 2)\nFree module of rank 2 over R\n\njulia> A = R[x y; 2*x^2 3*y^2]\n[ x y]\n[2*x^2 3*y^2]\n \njulia> M = cokernel(F, A)\nSubquotient of Submodule with 2 generators\n1 -> e[1]\n2 -> e[2]\nby Submodule with 2 generators\n1 -> x*e[1] + y*e[2]\n2 -> 2*x^2*e[1] + 3*y^2*e[2]\n\njulia> ambient_free_module(M) === F\ntrue\n\n\njulia> Rg, (x, y, z) = graded_polynomial_ring(QQ, [:x, :y, :z]);\n\njulia> F = graded_free_module(Rg, [8,8])\nGraded free module Rg^2([-8]) of rank 2 over Rg\n\njulia> A = Rg[x y; 2*x^2 3*y^2]\n[ x y]\n[2*x^2 3*y^2]\n \njulia> M = cokernel(F, A)\nGraded subquotient of submodule of F generated by\n1 -> e[1]\n2 -> e[2]\nby submodule of F generated by\n1 -> x*e[1] + y*e[2]\n2 -> 2*x^2*e[1] + 3*y^2*e[2]\n\njulia> ambient_free_module(M) === F\ntrue\n\njulia> degrees_of_generators(M)\n2-element Vector{FinGenAbGroupElem}:\n [8]\n [8]\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::FinGenAbGroupElem, task::Symbol=:with_morphism)","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/module_operations/#truncate","page":"Operations on Modules","title":"truncate","text":"truncate(I::ModuleFP, g::FinGenAbGroupElem, 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":"CommutativeAlgebra/ModulesOverMultivariateRings/module_operations/#Twists","page":"Operations on Modules","title":"Twists","text":"","category":"section"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/module_operations/","page":"Operations on Modules","title":"Operations on Modules","text":"In the graded case, we have:","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/module_operations/","page":"Operations on Modules","title":"Operations on Modules","text":"twist(M::ModuleFP{T}, g::FinGenAbGroupElem) where {T<:MPolyDecRingElem}","category":"page"},{"location":"CommutativeAlgebra/ModulesOverMultivariateRings/module_operations/#twist-Union{Tuple{T}, Tuple{ModuleFP{T}, FinGenAbGroupElem}} where T<:MPolyDecRingElem","page":"Operations on Modules","title":"twist","text":"twist(M::ModuleFP{T}, g::FinGenAbGroupElem) where {T<:MPolyDecRingElem}\n\nReturn the twisted module M(g).\n\ntwist(M::ModuleFP{T}, W::Vector{<:IntegerUnion}) where {T<:MPolyDecRingElem}\n\nGiven a module M over a mathbb Z^m-graded polynomial ring and a vector W of m integers, convert W into an element g of the grading group of the ring and proceed as above.\n\ntwist(M::ModuleFP{T}, d::IntegerUnion) where {T<:MPolyDecRingElem}\n\nGiven a module M over a mathbb Z-graded polynomial ring and an integer d, convert d into an element g of the grading group of the ring and proceed as above.\n\nExamples\n\njulia> R, (x, y) = graded_polynomial_ring(QQ, [:x, :y]);\n\njulia> I = ideal(R, [zero(R)])\nIdeal generated by\n 0\n\njulia> M = quotient_ring_as_module(I)\nGraded submodule of R^1\n1 -> e[1]\nrepresented as subquotient with no relations\n\njulia> degree(gen(M, 1))\n[0]\n\njulia> N = twist(M, 2)\nGraded submodule of R^1\n1 -> e[1]\nrepresented as subquotient with no relations\n\njulia> degree(gen(N, 1))\n[-2]\n\n\n\n\n\n\n","category":"method"},{"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.\nWhenever functions expect a ring, field, algebra, etc. as input they should be passed as the first argument, for example, polynomial_ring(QQ, :x).\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...\nInput sanity checks should be enabled by default, they can then be disabled internally if they are known to be true, and manually by users.\nAll user-facing functions that expect some kind of indeterminant name etc. (like polynomial_ring(QQ, )) should accept a VarName = Union{Symbol, Char, String}, and convert it to a symbol for internal handling. Library and test code should (if possible) call such functions with Symbol arguments, as this is the most efficient way.","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.\nA function returning the number of some things should be named number_of_things, alternatively it can be named n_things with an alias to number_of_things. The preferred style should be consistent throughout the corresponding part. For some very common things, like the number of generators, we additionally provide a shorter alias, e.g. ngens for number_of_generators. These aliases should be very short and without underscores.\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/","page":"Developer Style Guide","title":"Developer Style Guide","text":"Before making some suggestions for code formatting rules, a warning: we deliberately are lax about enforcing these rules, as often contributors (esp. new ones) already struggle enough without being forced to also adhere to specific formatting rules. As long as code is sufficiently readable, we may accept it.","category":"page"},{"location":"DeveloperDocumentation/styleguide/","page":"Developer Style Guide","title":"Developer Style Guide","text":"But in the same vein (i.e., to minimize frictions for others working on OSCAR), we ask everyone to generally refrain from reformatting large chunks of code (even if it is to make it adhere to the rules described below), unless this is carefully coordinated with all stakeholders of the affected code.","category":"page"},{"location":"DeveloperDocumentation/styleguide/","page":"Developer Style Guide","title":"Developer Style Guide","text":"Also, ideally don't mix code reformatting with other changes, as this makes it harder to understand what is going on. At the very least, use different commits for the reformatting changes and the actual changes. But in general you shouldn't reformat code unrelated to the changes you are making.","category":"page"},{"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/#JuliaFormatter","page":"Developer Style Guide","title":"JuliaFormatter","text":"","category":"section"},{"location":"DeveloperDocumentation/styleguide/","page":"Developer Style Guide","title":"Developer Style Guide","text":"There is a .JuliaFormatter.toml in our git repository. To format your files, first add JuliaFormatter.jl in Julia and then use","category":"page"},{"location":"DeveloperDocumentation/styleguide/","page":"Developer Style Guide","title":"Developer Style Guide","text":"using JuliaFormatter\nformat_file(\"path/to/file/file.jl\")","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 Unicode printing 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/#Optional-arguments-for-parents-of-return-values","page":"Developer Style Guide","title":"Optional arguments for parents of return values","text":"","category":"section"},{"location":"DeveloperDocumentation/styleguide/","page":"Developer Style Guide","title":"Developer Style Guide","text":"Several objects in OSCAR have parents, e.g. polynomials, group elements, ... Whenever a function creates such objects from an input which does not involve the output's parent, we strongly recommend that the user should have the possibility to pass on this parent as a keyword argument under the name parent. Beyond that you can make more entry points for such parents available for the user's convenience.","category":"page"},{"location":"DeveloperDocumentation/styleguide/","page":"Developer Style Guide","title":"Developer Style Guide","text":"Let's see an example. Say, you want to implement the characteristic polynomial of a matrix. You could do it as follows:","category":"page"},{"location":"DeveloperDocumentation/styleguide/","page":"Developer Style Guide","title":"Developer Style Guide","text":"function characteristic_polynomial(A::MatrixElem)\n kk = base_ring(A)\n P, x = kk[:x]\n AP = change_base_ring(P, A)\n return det(AP - x*one(AP))\nend","category":"page"},{"location":"DeveloperDocumentation/styleguide/","page":"Developer Style Guide","title":"Developer Style Guide","text":"You can see that the polynomial ring P, i.e. the parent of the output, is newly created in the body of the function. In particular, calling this function two times on two different matrices A and B might produce incompatible polynomials p = det(A - x*one(A)) and q = det(B - x*one(B)) with different parents. Calling p + q will result in an error. ","category":"page"},{"location":"DeveloperDocumentation/styleguide/","page":"Developer Style Guide","title":"Developer Style Guide","text":"To solve this, we should have implemented the function differently:","category":"page"},{"location":"DeveloperDocumentation/styleguide/","page":"Developer Style Guide","title":"Developer Style Guide","text":"# Implementation of the recommended keyword argument signature:\nfunction characteristic_polynomial(\n A::MatrixElem;\n parent::AbstractAlgebra.Ring=polynomial_ring(base_ring(A), :t)[1]\n )\n AP = change_base_ring(parent, A)\n x = first(gens(ring))\n return det(AP - x*one(AP))\nend\n\n# Optional second signature to also allow for the specification of the \n# output's parent as the first argument:\nfunction characteristic_polynomial(\n P::PolyRing,\n A::MatrixElem\n )\n coefficient_ring(P) === base_ring(A) || error(\"coefficient rings incompatible\")\n return characteristic_polynomial(A, parent=P)\nend","category":"page"},{"location":"DeveloperDocumentation/styleguide/","page":"Developer Style Guide","title":"Developer Style Guide","text":"In fact this now allows for two different entry points for the parent ring P of the output: First as the required parent keyword argument and second as the first argument of a method of characteristic_polynomial with an extended signature. Note that within the scope of the first method's body the OSCAR function parent is necessarily overwritten by the name of the keyword argument. Hence to call the actual parent of any other object, you must then use Oscar.parent. E.g. to get the MatrixSpace of the matrix A, write Oscar.parent(A).","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 terse. 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# terse\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 terse 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 terse can be anywhere.\ncommas must be enclosed in brackets so that printing tuples stays unambiguous","category":"page"},{"location":"DeveloperDocumentation/styleguide/#Terse-printing","page":"Developer Style Guide","title":"Terse 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 terse 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. If the interface did not change, it is enough to write:","category":"page"},{"location":"DeveloperDocumentation/styleguide/","page":"Developer Style Guide","title":"Developer Style Guide","text":"# Deprecated after CURRENT_RELEASE_VERSION\n@deprecate old_function new_function","category":"page"},{"location":"DeveloperDocumentation/styleguide/","page":"Developer Style Guide","title":"Developer Style Guide","text":"It is possible to transform the arguments 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(arg1::Type1, arg2::Type2, ...) new_function(transform_args_for_new_function(args))","category":"page"},{"location":"DeveloperDocumentation/styleguide/","page":"Developer Style Guide","title":"Developer Style Guide","text":"In simple cases (like changing the order of arguments), you don't need an auxiliary function:","category":"page"},{"location":"DeveloperDocumentation/styleguide/","page":"Developer Style Guide","title":"Developer Style Guide","text":"@deprecate old_function(arg1::Type1, arg2::Type2) new_function(arg2, arg1)","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":"If you renamed a type and want to deprecate the old one, please add a line like","category":"page"},{"location":"DeveloperDocumentation/styleguide/","page":"Developer Style Guide","title":"Developer Style Guide","text":"Base.@deprecate_type OldType NewType","category":"page"},{"location":"DeveloperDocumentation/styleguide/","page":"Developer Style Guide","title":"Developer Style Guide","text":"This makes it still possible to use OldType in signatures and type annotations, but it will throw a deprecation warning (if they are enabled).","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(P::AbsProjectiveScheme, Q::AbsProjectiveScheme, f::Map; check::Bool=true )\nmorphism(P::AbsProjectiveScheme, Q::AbsProjectiveScheme, f::Map, h::SchemeMor; check::Bool=true )\nmorphism(X::AbsProjectiveScheme, Y::AbsProjectiveScheme, a::Vector{<:RingElem})","category":"page"},{"location":"AlgebraicGeometry/Schemes/MorphismsOfProjectiveSchemes/#morphism-Tuple{AbsProjectiveScheme, AbsProjectiveScheme, Map}","page":"Morphisms of projective schemes","title":"morphism","text":"morphism(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-Tuple{AbsProjectiveScheme, AbsProjectiveScheme, Map, SchemeMor}","page":"Morphisms of projective schemes","title":"morphism","text":"morphism(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-Tuple{AbsProjectiveScheme, AbsProjectiveScheme, Vector{<:RingElem}}","page":"Morphisms of projective schemes","title":"morphism","text":"morphism(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) \ncodomain(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)\nbase_ring_morphism(phi::ProjectiveSchemeMor) \nbase_map(phi::ProjectiveSchemeMor)\nmap_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::AbsProjectiveSchemeMorphism)","category":"page"},{"location":"AlgebraicGeometry/Schemes/MorphismsOfProjectiveSchemes/#covered_scheme_morphism-Tuple{AbsProjectiveSchemeMorphism}","page":"Morphisms of projective schemes","title":"covered_scheme_morphism","text":"covered_scheme_morphism(f::AbsProjectiveSchemeMorphism)\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 = proj(P, I);\n\njulia> f = identity_map(Y)\nProjective scheme morphism\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: scheme(-(y//x)^2*(z//x) + 1)\n 2: scheme((x//y)^3 - (z//y))\n 3: scheme((x//z)^3 - (y//z)^2)\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":"Hecke/manual/misc/mset/#Multi-sets-and-sub-set-iterators","page":"Multi-sets and sub-set iterators","title":"Multi-sets and sub-set iterators","text":"","category":"section"},{"location":"Hecke/manual/misc/mset/","page":"Multi-sets and sub-set iterators","title":"Multi-sets and sub-set iterators","text":"CurrentModule = Hecke\nDocTestSetup = quote\n using Hecke\nend","category":"page"},{"location":"Hecke/manual/misc/mset/#Multi-sets","page":"Multi-sets and sub-set iterators","title":"Multi-sets","text":"","category":"section"},{"location":"Hecke/manual/misc/mset/#Type-and-constructors","page":"Multi-sets and sub-set iterators","title":"Type and constructors","text":"","category":"section"},{"location":"Hecke/manual/misc/mset/","page":"Multi-sets and sub-set iterators","title":"Multi-sets and sub-set iterators","text":"Objects of type MSet consists of a dictionary whose keys are the elements in the set, and the values are their respective multiplicity.","category":"page"},{"location":"Hecke/manual/misc/mset/","page":"Multi-sets and sub-set iterators","title":"Multi-sets and sub-set iterators","text":"MSet","category":"page"},{"location":"Hecke/manual/misc/mset/#MSet","page":"Multi-sets and sub-set iterators","title":"MSet","text":"MSet{T} <: AbstractSet{T}\n\nType for a multi-set, i.e. a set where elements are not unique, they (can) have a multiplicity. MSets can be created from any finite iterator.\n\nExamples\n\njulia> MSet([1,1,2,3,4,4,5])\nMSet{Int64} with 7 elements:\n 5\n 4 : 2\n 2\n 3\n 1 : 2\n\n4 : 2 means the element 4 has multiplicity 2, i.e. was included twice.\n\n\n\n\n\n","category":"type"},{"location":"Hecke/manual/misc/mset/","page":"Multi-sets and sub-set iterators","title":"Multi-sets and sub-set iterators","text":"We can create multi-sets from any finite iterator, dictionary or pair of lists with the appropriate conditions.","category":"page"},{"location":"Hecke/manual/misc/mset/","page":"Multi-sets and sub-set iterators","title":"Multi-sets and sub-set iterators","text":"multiset","category":"page"},{"location":"Hecke/manual/misc/mset/#multiset","page":"Multi-sets and sub-set iterators","title":"multiset","text":"multiset(iter) -> MSet{eltype(iter)}\nmultiset(d::Dict{T, Int}) -> MSet{T}\nmultiset{l::Vector{T}, m::Vector{Int}} -> MSet{T}\n\nGiven either:\n\na finite iterator iter;\na dictionary d whose values are positive integers;\na list l and a list of positive integers m of same length as l;\n\nreturn the asscciated multi-set M.\n\nExamples\n\njulia> str = \"A nice sentence\"\n\"A nice sentence\"\n\njulia> multiset(str)\nMSet{Char} with 15 elements:\n 'n' : 3\n 'A'\n 'c' : 2\n 'i'\n 'e' : 4\n 's'\n 't'\n ' ' : 2\n\njulia> multiset(Int[x^3%8 for x = 1:50])\nMSet{Int64} with 50 elements:\n 0 : 25\n 5 : 6\n 7 : 6\n 3 : 6\n 1 : 7\n\njulia> d = Dict(\"a\" => 4, \"b\" => 1, \"c\" =>9)\nDict{String, Int64} with 3 entries:\n \"c\" => 9\n \"b\" => 1\n \"a\" => 4\n\njulia> multiset(d)\nMSet{String} with 14 elements:\n \"c\" : 9\n \"b\"\n \"a\" : 4\n\njulia> multiset([\"a\", \"b\", \"c\"], [4, 1, 9])\nMSet{String} with 14 elements:\n \"c\" : 9\n \"b\"\n \"a\" : 4\n\n\n\n\n\nmultiset(T::Type) -> MSet{T}\n\nCreate an empty multi-set M with elements of type T.\n\nExamples\n\njulia> multiset(QQFieldElem)\nMSet{QQFieldElem}()\n\njulia> multiset()\nMSet{Any}()\n\n\n\n\n\n","category":"function"},{"location":"Hecke/manual/misc/mset/#Functions","page":"Multi-sets and sub-set iterators","title":"Functions","text":"","category":"section"},{"location":"Hecke/manual/misc/mset/","page":"Multi-sets and sub-set iterators","title":"Multi-sets and sub-set iterators","text":"One can iterate over an MSet as on a regular Set. Here is moreover a list of functions defined for collections of objects which are currently available for MSet:","category":"page"},{"location":"Hecke/manual/misc/mset/","page":"Multi-sets and sub-set iterators","title":"Multi-sets and sub-set iterators","text":"==\nall\nany\ncopy\ndelete!\neltype\nfilter\nfilter!\nin\nintersect\nintersect!\nisempty\nissubset\nlength\npop!\npush!\nsetdiff\nsetdiff!\nsimilar\nunique\nunion\nunion!\n...","category":"page"},{"location":"Hecke/manual/misc/mset/","page":"Multi-sets and sub-set iterators","title":"Multi-sets and sub-set iterators","text":"Note that pop! and delete! for MSet are available but have a different behaviour. For an element x in an multi-set M <: MSet, then pop!(M, x) will remove one instance of x in M - in particular multiplicity(M, x) will drop by 1. Much stronger, delete!(M, x) will remove all instances of x in M and so multiplicity(M, x) will be 0.","category":"page"},{"location":"Hecke/manual/misc/mset/","page":"Multi-sets and sub-set iterators","title":"Multi-sets and sub-set iterators","text":"While unique will return the keys of the underlying dictionary, one can access the values (i.e. the multiplicities of the elements in the multi-set) via the following functions:","category":"page"},{"location":"Hecke/manual/misc/mset/","page":"Multi-sets and sub-set iterators","title":"Multi-sets and sub-set iterators","text":"multiplicities(::MSet)\nmultiplicity(::MSet{T}, ::T) where {T}","category":"page"},{"location":"Hecke/manual/misc/mset/#multiplicities-Tuple{MSet}","page":"Multi-sets and sub-set iterators","title":"multiplicities","text":"multiplicities(s::MSet{T}) -> ValueIterator{Dict{T, Int}}\n\nReturn an iterator for the multiplicities of all the elements in s.\n\nExamples\n\njulia> m = multiset([1,1,2,3,4,4,5])\nMSet{Int64} with 7 elements:\n 5\n 4 : 2\n 2\n 3\n 1 : 2\n\njulia> mult_m = multiplicities(m)\nValueIterator for a Dict{Int64, Int64} with 5 entries. Values:\n 1\n 2\n 1\n 1\n 2\n\njulia> collect(mult_m)\n5-element Vector{Int64}:\n 1\n 2\n 1\n 1\n 2\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/misc/mset/#multiplicity-Union{Tuple{T}, Tuple{MSet{T}, T}} where T","page":"Multi-sets and sub-set iterators","title":"multiplicity","text":"multiplicity(s::MSet{T}, x::T) -> Int\n\nReturn the multiplicity of the element x in the multi-set s. If x is not in s, return 0.\n\nExamples\n\njulia> m = multiset([1,1,2,3,4,4,5])\nMSet{Int64} with 7 elements:\n 5\n 4 : 2\n 2\n 3\n 1 : 2\n\njulia> multiplicity(m, 2)\n1\n\njulia> multiplicity(m, 6)\n0\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/misc/mset/","page":"Multi-sets and sub-set iterators","title":"Multi-sets and sub-set iterators","text":"Finally, the sum and difference for MSet are also available. Difference is given by the complements of sets and the sum is given by disjoint union of sets.","category":"page"},{"location":"Hecke/manual/misc/mset/","page":"Multi-sets and sub-set iterators","title":"Multi-sets and sub-set iterators","text":"Base.:(+)(::MSet, ::MSet)\nBase.:(-)(::MSet, ::MSet...)","category":"page"},{"location":"Hecke/manual/misc/mset/#+-Tuple{MSet, MSet}","page":"Multi-sets and sub-set iterators","title":"+","text":"(+)(s::MSet, itrs...) -> MSet\n\nReturn the multi-sets associated to the disjoint union of s and the collections of objects in itrs.\n\nExamples\n\njulia> m = multiset(\"A nice sentence\")\nMSet{Char} with 15 elements:\n 'n' : 3\n 'A'\n 'c' : 2\n 'i'\n 'e' : 4\n 's'\n 't'\n ' ' : 2\n\njulia> n = multiset(\"A very nice sentence\")\nMSet{Char} with 20 elements:\n 'n' : 3\n 'e' : 5\n 'A'\n 'y'\n 'i'\n 'r'\n 's'\n 't'\n ' ' : 3\n 'c' : 2\n 'v'\n\njulia> m + n\nMSet{Char} with 35 elements:\n 'n' : 6\n 'e' : 9\n 'A' : 2\n 's' : 2\n 'i' : 2\n 't' : 2\n 'y'\n 'r'\n ' ' : 5\n 'c' : 4\n 'v'\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/misc/mset/#--Tuple{MSet, Vararg{MSet}}","page":"Multi-sets and sub-set iterators","title":"-","text":"(-)(s::MSet, itrs...) -> MSet\n\nReturn the multi-set associated to the complement in s of the collections in itrs.\n\nAlias for setdiff(s, itrs...).\n\nExamples\n\njulia> m = multiset(\"A very nice sentence\")\nMSet{Char} with 20 elements:\n 'n' : 3\n 'e' : 5\n 'A'\n 'y'\n 'i'\n 'r'\n 's'\n 't'\n ' ' : 3\n 'c' : 2\n 'v'\n\njulia> n = multiset(\"A nice sentence\")\nMSet{Char} with 15 elements:\n 'n' : 3\n 'A'\n 'c' : 2\n 'i'\n 'e' : 4\n 's'\n 't'\n ' ' : 2\n\njulia> n-m\nMSet{Char}()\n\njulia> m-n\nMSet{Char} with 5 elements:\n 'e'\n 'y'\n 'r'\n ' '\n 'v'\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/misc/mset/#Sub-set-iterators","page":"Multi-sets and sub-set iterators","title":"Sub-set iterators","text":"","category":"section"},{"location":"Hecke/manual/misc/mset/#Sub-multi-sets","page":"Multi-sets and sub-set iterators","title":"Sub-multi-sets","text":"","category":"section"},{"location":"Hecke/manual/misc/mset/","page":"Multi-sets and sub-set iterators","title":"Multi-sets and sub-set iterators","text":"subsets(::MSet{Int})","category":"page"},{"location":"Hecke/manual/misc/mset/#subsets-Tuple{MSet{Int64}}","page":"Multi-sets and sub-set iterators","title":"subsets","text":"subsets(s::MSet) -> MSubSetIt{T}\n\nReturn an iterator on all sub-multi-sets of s.\n\n\n\n\n\nsubsets(s::Set) -> SubSetItr{T}\n\nReturn an iterator for all sub-sets of s.\n\n\n\n\n\nsubsets(s::Set, k::Int) -> SubSetSizeItr{T}\n\nReturn an iterator on all sub-sets of size k of s.\n\n\n\n\n\nsubsets(v::Vector{T}, k::Int) where T\n\nReturn a vector of all ordered k-element sub-vectors of v.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/misc/mset/#Sub-sets","page":"Multi-sets and sub-set iterators","title":"Sub-sets","text":"","category":"section"},{"location":"Hecke/manual/misc/mset/","page":"Multi-sets and sub-set iterators","title":"Multi-sets and sub-set iterators","text":"subsets(::Set{Int})","category":"page"},{"location":"Hecke/manual/misc/mset/#subsets-Tuple{Set{Int64}}","page":"Multi-sets and sub-set iterators","title":"subsets","text":"subsets(s::MSet) -> MSubSetIt{T}\n\nReturn an iterator on all sub-multi-sets of s.\n\n\n\n\n\nsubsets(s::Set) -> SubSetItr{T}\n\nReturn an iterator for all sub-sets of s.\n\n\n\n\n\nsubsets(s::Set, k::Int) -> SubSetSizeItr{T}\n\nReturn an iterator on all sub-sets of size k of s.\n\n\n\n\n\nsubsets(v::Vector{T}, k::Int) where T\n\nReturn a vector of all ordered k-element sub-vectors of v.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/misc/mset/#Sub-sets-of-a-given-size","page":"Multi-sets and sub-set iterators","title":"Sub-sets of a given size","text":"","category":"section"},{"location":"Hecke/manual/misc/mset/","page":"Multi-sets and sub-set iterators","title":"Multi-sets and sub-set iterators","text":"subsets(::Set, ::Int)","category":"page"},{"location":"Hecke/manual/misc/mset/#subsets-Tuple{Set, Int64}","page":"Multi-sets and sub-set iterators","title":"subsets","text":"subsets(s::Set, k::Int) -> SubSetSizeItr{T}\n\nReturn an iterator on all sub-sets of size k of s.\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 = Oscar.doctestsetup()","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":"[DES93]\n[Pop93]\n[DS00]","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. Hard coded OSCAR examples for these surfaces 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":"TropicalGeometry/tropicalization/#Tropicalization-of-polynomial-ideals","page":"Tropicalization of polynomial ideals","title":"Tropicalization of polynomial ideals","text":"","category":"section"},{"location":"TropicalGeometry/tropicalization/#Introduction","page":"Tropicalization of polynomial ideals","title":"Introduction","text":"","category":"section"},{"location":"TropicalGeometry/tropicalization/","page":"Tropicalization of polynomial ideals","title":"Tropicalization of polynomial ideals","text":"Tropical varieties can arise as tropicalizations of polynomial ideals. For a general introduction, see","category":"page"},{"location":"TropicalGeometry/tropicalization/","page":"Tropicalization of polynomial ideals","title":"Tropicalization of polynomial ideals","text":"Chapter 3 in [MS15]","category":"page"},{"location":"TropicalGeometry/tropicalization/","page":"Tropicalization of polynomial ideals","title":"Tropicalization of polynomial ideals","text":"For algorithmic details, see","category":"page"},{"location":"TropicalGeometry/tropicalization/","page":"Tropicalization of polynomial ideals","title":"Tropicalization of polynomial ideals","text":"[BJSST07]\n[MR20]","category":"page"},{"location":"TropicalGeometry/tropicalization/#Main-function","page":"Tropicalization of polynomial ideals","title":"Main function","text":"","category":"section"},{"location":"TropicalGeometry/tropicalization/","page":"Tropicalization of polynomial ideals","title":"Tropicalization of polynomial ideals","text":"tropical_variety(I::MPolyIdeal, nu::Union{TropicalSemiringMap,Nothing}=nothing; weighted_polyhedral_complex_only::Bool=false, skip_saturation::Bool=false, skip_primary_decomposition::Bool=false)","category":"page"},{"location":"TropicalGeometry/tropicalization/#tropical_variety","page":"Tropicalization of polynomial ideals","title":"tropical_variety","text":"tropical_variety(I::MPolyIdeal, nu::Union{TropicalSemiringMap,Nothing}=nothing; weighted_polyhedral_complex_only::Bool=false, skip_saturation::Bool=false, skip_primary_decomposition::Bool=false)\n\nReturn the tropicalization of I with respect to nu as a Vector{TropicalVariety}. If nu==nothing, will compute with respect to the trivial valuation and min convention. If weighted_polyhedral_complex_only==true, will not cache any additional information. If skip_saturation==true, will not saturate I with respect to the product of all variables. If skip_primary_decomposition==true, will not decompose I.\n\nwarning: Warning\ntropical_variety is currently under development and only works for ideals that primary decompose into principal, linear, and binomial ideals.\n\nExamples\n\njulia> R,(x,y) = QQ[:x, :y];\n\njulia> I = ideal([(x^2+y)*(x+y^2)*(x+y)]);\n\njulia> tropical_variety(I)\n3-element Vector{TropicalVariety}:\n Min tropical variety\n Min tropical variety\n Min tropical variety\n\n\n\n\n\n\n","category":"function"},{"location":"Hecke/manual/#Manual","page":"Manual","title":"Manual","text":"","category":"section"},{"location":"Hecke/manual/","page":"Manual","title":"Manual","text":"This is the manual","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":"Experimental/BasisLieHighestWeight/introduction/","page":"Introduction","title":"Introduction","text":"CurrentModule = Oscar\nDocTestSetup = Oscar.doctestsetup()","category":"page"},{"location":"Experimental/BasisLieHighestWeight/introduction/#Introduction","page":"Introduction","title":"Introduction","text":"","category":"section"},{"location":"Experimental/BasisLieHighestWeight/introduction/","page":"Introduction","title":"Introduction","text":"This subproject contains the code for the OSCAR book chapter by Ghislain Fourier and Xin Fang on the bases of highest weight modules.","category":"page"},{"location":"Experimental/BasisLieHighestWeight/introduction/#Status","page":"Introduction","title":"Status","text":"","category":"section"},{"location":"Experimental/BasisLieHighestWeight/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. More documentation is to come in the future.","category":"page"},{"location":"Experimental/BasisLieHighestWeight/introduction/#Contact","page":"Introduction","title":"Contact","text":"","category":"section"},{"location":"Experimental/BasisLieHighestWeight/introduction/","page":"Introduction","title":"Introduction","text":"Please direct questions about this part of OSCAR to the following people:","category":"page"},{"location":"Experimental/BasisLieHighestWeight/introduction/","page":"Introduction","title":"Introduction","text":"Ghislain Fourier\nLars Göttgens","category":"page"},{"location":"Experimental/BasisLieHighestWeight/introduction/","page":"Introduction","title":"Introduction","text":"You can ask questions in the OSCAR Slack.","category":"page"},{"location":"Experimental/BasisLieHighestWeight/introduction/","page":"Introduction","title":"Introduction","text":"Alternatively, you can raise an issue on github.","category":"page"},{"location":"AlgebraicGeometry/Schemes/Sheaves/","page":"Sheaves on covered schemes","title":"Sheaves on covered schemes","text":"CurrentModule = Oscar","category":"page"},{"location":"AlgebraicGeometry/Schemes/Sheaves/#Sheaves-on-covered-schemes","page":"Sheaves on covered schemes","title":"Sheaves on covered schemes","text":"","category":"section"},{"location":"AlgebraicGeometry/Schemes/Sheaves/","page":"Sheaves on covered schemes","title":"Sheaves on covered schemes","text":"Oscar supports modeling sheaves by means of a covering by affine charts.","category":"page"},{"location":"AlgebraicGeometry/Schemes/Sheaves/#Presheaves","page":"Sheaves on covered schemes","title":"Presheaves","text":"","category":"section"},{"location":"AlgebraicGeometry/Schemes/Sheaves/","page":"Sheaves on covered schemes","title":"Sheaves on covered schemes","text":"AbsPreSheaf\nPreSheafOnScheme","category":"page"},{"location":"AlgebraicGeometry/Schemes/Sheaves/#AbsPreSheaf","page":"Sheaves on covered schemes","title":"AbsPreSheaf","text":"AbsPreSheaf{SpaceType, OpenType, OutputType, RestrictionType}\n\nAbstract type for a sheaf ℱ on a space X.\n\nSpaceType is a parameter for the type of the space X on which ℱ is defined.\nOpenType is a type (most probably abstract!) for the open sets U X which are admissible as input for ℱ(U).\nOutputType is a type (most probably abstract!) for the values that ℱ takes on admissible open sets U.\nRestrictionType is a parameter for the type of the restriction maps ℱ(V) ℱ(U) for U V X open.\n\nFor any instance F of AbsPreSheaf on a topological space X the following methods are implemented:\n\nF(U) for admissible open subsets U X: This returns the value ℱ(U) of the sheaf F on U. Note that due to technical limitations, not every type of open subset might be admissible.\nrestriction_map(F, U, V) for admissible open subsets V U X: This returns the restriction map ρ ℱ(U) ℱ(V).\n\n\n\n\n\n","category":"type"},{"location":"AlgebraicGeometry/Schemes/Sheaves/#PreSheafOnScheme","page":"Sheaves on covered schemes","title":"PreSheafOnScheme","text":"PreSheafOnScheme\n\nA basic minimal implementation of the interface for AbsPreSheaf; to be used internally.\n\n\n\n\n\n","category":"type"},{"location":"AlgebraicGeometry/Schemes/Sheaves/#Structure-sheaves","page":"Sheaves on covered schemes","title":"Structure sheaves","text":"","category":"section"},{"location":"AlgebraicGeometry/Schemes/Sheaves/","page":"Sheaves on covered schemes","title":"Sheaves on covered schemes","text":"StructureSheafOfRings","category":"page"},{"location":"AlgebraicGeometry/Schemes/Sheaves/#StructureSheafOfRings","page":"Sheaves on covered schemes","title":"StructureSheafOfRings","text":"StructureSheafOfRings <: AbsPreSheaf\n\nOn an AbsCoveredScheme X this returns the sheaf 𝒪 of rings of regular functions on X.\n\nNote that due to technical reasons, the admissible open subsets are restricted to the following:\n\nU::AbsAffineScheme among the basic_patches of the default_covering of X;\nU::PrincipalOpenSubset with ambient_scheme(U) in the basic_patches of the default_covering of X;\nW::AffineSchemeOpenSubscheme with ambient_scheme(W) in the basic_patches of the default_covering of X.\n\nOne can call the restriction maps of 𝒪 across charts, implicitly using the identifications given by the gluings in the default_covering.\n\n\n\n\n\n","category":"type"},{"location":"AlgebraicGeometry/Schemes/Sheaves/#Ideal-sheaves","page":"Sheaves on covered schemes","title":"Ideal sheaves","text":"","category":"section"},{"location":"AlgebraicGeometry/Schemes/Sheaves/","page":"Sheaves on covered schemes","title":"Sheaves on covered schemes","text":"AbsIdealSheaf\nIdealSheaf\nPrimeIdealSheafFromChart","category":"page"},{"location":"AlgebraicGeometry/Schemes/Sheaves/#AbsIdealSheaf","page":"Sheaves on covered schemes","title":"AbsIdealSheaf","text":"AbsIdealSheaf <: AbsPreSheaf\n\nA sheaf of ideals I on an AbsCoveredScheme X.\n\nFor an affine open subset U X call I(U) to obtain an ideal in OO(U) representing I.\n\n\n\n\n\n","category":"type"},{"location":"AlgebraicGeometry/Schemes/Sheaves/#IdealSheaf","page":"Sheaves on covered schemes","title":"IdealSheaf","text":"IdealSheaf <: AbsIdealSheaf\n\nA sheaf of ideals ℐ on an AbsCoveredScheme X which is specified by a collection of concrete ideals on some open covering of X.\n\n\n\n\n\n","category":"type"},{"location":"AlgebraicGeometry/Schemes/Sheaves/#PrimeIdealSheafFromChart","page":"Sheaves on covered schemes","title":"PrimeIdealSheafFromChart","text":"raw PrimeIdealSheafFromChart\n\nType for sheaves of prime ideals P on a covered scheme X constructed from a prime ideal of the coordinate ring of a chart. Essentially this is a scheme theoretic point.\n\nFor U an affine chart of X, the ideal P(U) is computed using the gluings. The implementation is lazy.\n\n\n\n\n\n","category":"type"},{"location":"AlgebraicGeometry/Schemes/Sheaves/#Coherent-sheaves-of-modules","page":"Sheaves on covered schemes","title":"Coherent sheaves of modules","text":"","category":"section"},{"location":"AlgebraicGeometry/Schemes/Sheaves/","page":"Sheaves on covered schemes","title":"Sheaves on covered schemes","text":"SheafOfModules\ntwisting_sheaf(IP::AbsProjectiveScheme{<:Field}, d::Int)\ntautological_bundle(IP::AbsProjectiveScheme{<:Field})\ncotangent_sheaf(X::AbsCoveredScheme)\nfree_module(R::StructureSheafOfRings, n::Int)\nprojectivization(E::AbsCoherentSheaf; var_names::Vector{String}=Vector{String}(), check::Bool=true)","category":"page"},{"location":"AlgebraicGeometry/Schemes/Sheaves/#SheafOfModules","page":"Sheaves on covered schemes","title":"SheafOfModules","text":"SheafOfModules <: AbsPreSheaf\n\nA sheaf of modules ℳ on an AbsCoveredScheme X.\n\nNote that due to technical reasons, the admissible open subsets are restricted to the following:\n\nU::AbsAffineScheme among the basic_patches of the default_covering of X;\nU::PrincipalOpenSubset with ambient_scheme(U) in the basic_patches of the default_covering of X.\n\nOne can call the restriction maps of ℳ across charts implicitly using the identifications given by the gluings in the default_covering.\n\n\n\n\n\n","category":"type"},{"location":"AlgebraicGeometry/Schemes/Sheaves/#twisting_sheaf-Tuple{AbsProjectiveScheme{<:Field}, Int64}","page":"Sheaves on covered schemes","title":"twisting_sheaf","text":"twisting_sheaf(IP::AbsProjectiveScheme{<:Field}, d::Int)\n\nFor a ProjectiveScheme ℙ return the d-th twisting sheaf 𝒪(d) as a CoherentSheaf on ℙ.\n\nExamples\n\njulia> P = projective_space(QQ,3)\nProjective space of dimension 3\n over rational field\nwith homogeneous coordinates [s0, s1, s2, s3]\n\njulia> twisting_sheaf(P, 4)\nCoherent sheaf of modules\n on scheme over QQ covered with 4 patches\n 1: [(s1//s0), (s2//s0), (s3//s0)] affine 3-space\n 2: [(s0//s1), (s2//s1), (s3//s1)] affine 3-space\n 3: [(s0//s2), (s1//s2), (s3//s2)] affine 3-space\n 4: [(s0//s3), (s1//s3), (s2//s3)] affine 3-space\nwith restrictions\n 1: free module of rank 1 over Multivariate polynomial ring in 3 variables over QQ\n 2: free module of rank 1 over Multivariate polynomial ring in 3 variables over QQ\n 3: free module of rank 1 over Multivariate polynomial ring in 3 variables over QQ\n 4: free module of rank 1 over Multivariate polynomial ring in 3 variables over QQ\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/Sheaves/#tautological_bundle-Tuple{AbsProjectiveScheme{<:Field}}","page":"Sheaves on covered schemes","title":"tautological_bundle","text":"tautological_bundle(IP::AbsProjectiveScheme{<:Field})\n\nFor a ProjectiveScheme ℙ return the sheaf 𝒪(-1) as a CoherentSheaf on ℙ.\n\nExamples\n\njulia> P = projective_space(QQ,3)\nProjective space of dimension 3\n over rational field\nwith homogeneous coordinates [s0, s1, s2, s3]\n\njulia> tautological_bundle(P)\nCoherent sheaf of modules\n on scheme over QQ covered with 4 patches\n 1: [(s1//s0), (s2//s0), (s3//s0)] affine 3-space\n 2: [(s0//s1), (s2//s1), (s3//s1)] affine 3-space\n 3: [(s0//s2), (s1//s2), (s3//s2)] affine 3-space\n 4: [(s0//s3), (s1//s3), (s2//s3)] affine 3-space\nwith restrictions\n 1: free module of rank 1 over Multivariate polynomial ring in 3 variables over QQ\n 2: free module of rank 1 over Multivariate polynomial ring in 3 variables over QQ\n 3: free module of rank 1 over Multivariate polynomial ring in 3 variables over QQ\n 4: free module of rank 1 over Multivariate polynomial ring in 3 variables over QQ\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/Sheaves/#cotangent_sheaf-Tuple{AbsCoveredScheme}","page":"Sheaves on covered schemes","title":"cotangent_sheaf","text":"cotangent_sheaf(X::AbsCoveredScheme)\n\nFor an AbsCoveredScheme X, return the sheaf Ω¹(X) of Kaehler-differentials on X as a CoherentSheaf.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/Sheaves/#free_module-Tuple{StructureSheafOfRings, Int64}","page":"Sheaves on covered schemes","title":"free_module","text":"free_module(R::StructureSheafOfRings, n::Int)\n\nReturn the sheaf of free 𝒪-modules 𝒪ⁿ for a structure sheaf of rings 𝒪 = R.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/Sheaves/#projectivization-Tuple{Oscar.AbsCoherentSheaf}","page":"Sheaves on covered schemes","title":"projectivization","text":"projectivization(E::AbsCoherentSheaf;\n var_names::Vector{String}=Vector{String}(),\n check::Bool=true\n )\n\nFor a locally free sheaf E on an AbsCoveredScheme X this produces the associated projectivization ℙ (E) X as a CoveredProjectiveScheme.\n\nA list of names for the variables of the relative homogeneous coordinate rings can be provided with var_names.\n\n!!! note: The sheaf E needs to be locally free so that a trivializing_covering can be computed. The check for this can be turned off by setting check=false.\n\n\n\n\n\n","category":"method"},{"location":"Groups/intro/","page":"Introduction","title":"Introduction","text":"CurrentModule = Oscar\nDocTestSetup = Oscar.doctestsetup()","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":"[Hup67]\n[HEO05]","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)\nPadicFieldElem (PadicField)\nQadicFieldElem (QadicField)\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\nAbsSimpleNumFieldElem (AbsSimpleNumField)\nArb\nArbFieldElem (ArbField)\nAcbFieldElem (AcbField)\nArbPolyRingElem (ArbPolyRing)\nAcbPolyRingElem (AcbPolyRing)\nArbMatrix (ArbMatrixSpace)\nAcbMatrix (AcbMatrixSpace)\nCalcium\nQQBarFieldElem (QQBarField)\nCalciumFieldElem (CalciumField)","category":"page"},{"location":"TropicalGeometry/hypersurface/","page":"Tropical hypersurfaces","title":"Tropical hypersurfaces","text":"CurrentModule = Oscar\nDocTestSetup = Oscar.doctestsetup()","category":"page"},{"location":"TropicalGeometry/hypersurface/#Tropical-hypersurfaces","page":"Tropical hypersurfaces","title":"Tropical hypersurfaces","text":"","category":"section"},{"location":"TropicalGeometry/hypersurface/#Introduction","page":"Tropical hypersurfaces","title":"Introduction","text":"","category":"section"},{"location":"TropicalGeometry/hypersurface/","page":"Tropical hypersurfaces","title":"Tropical hypersurfaces","text":"A tropical hypersurface is a balanced polyhedral complex of codimension one. It is dual to a regular subdivision of a Newton polytope. For more on tropical hypersurfaces, see","category":"page"},{"location":"TropicalGeometry/hypersurface/","page":"Tropical hypersurfaces","title":"Tropical hypersurfaces","text":"Chapter 3.1 in [MS15]\nChapter 1 in [Jos21]","category":"page"},{"location":"TropicalGeometry/hypersurface/#Note:","page":"Tropical hypersurfaces","title":"Note:","text":"","category":"section"},{"location":"TropicalGeometry/hypersurface/","page":"Tropical hypersurfaces","title":"Tropical hypersurfaces","text":"Objects of type TropicalHypersurface need to be embedded, abstract tropical hypersurfaces are currently not supported.\nThe type TropicalHypersurface can be thought of as subtype of TropicalVariety in the sense that it should have all properties and features of the latter.","category":"page"},{"location":"TropicalGeometry/hypersurface/#Constructors","page":"Tropical hypersurfaces","title":"Constructors","text":"","category":"section"},{"location":"TropicalGeometry/hypersurface/","page":"Tropical hypersurfaces","title":"Tropical hypersurfaces","text":"In addition to converting from TropicalVariety, objects of type TropicalHypersurface can be constructed from:","category":"page"},{"location":"TropicalGeometry/hypersurface/","page":"Tropical hypersurfaces","title":"Tropical hypersurfaces","text":"polynomials over a tropical semiring,\npolynomials over a field and a tropical semiring map,\nsubdivision of points and a choice of min- or max-convention.","category":"page"},{"location":"TropicalGeometry/hypersurface/","page":"Tropical hypersurfaces","title":"Tropical hypersurfaces","text":"tropical_hypersurface","category":"page"},{"location":"TropicalGeometry/hypersurface/#tropical_hypersurface","page":"Tropical hypersurfaces","title":"tropical_hypersurface","text":"tropical_hypersurface(f::MPolyRingElem{<:TropicalSemiringElem}, weighted_polyhedral_complex_only::Bool=false)\n\nReturn the tropical hypersurface of the tropical polynomial f. If weighted_polyhedral_complex==true, will not cache any extra information.\n\nExamples\n\njulia> T = tropical_semiring()\nMin tropical semiring\n\njulia> R,(x,y) = T[:x, :y];\n\njulia> f = x+y+1\nx + y + (1)\n\njulia> tropical_hypersurface(f)\nMin tropical hypersurface\n\n\n\n\n\n\ntropical_hypersurface(f::MPolyRingElem, val::TropicalSemiringMap; weighted_polyhedral_complex_only::Bool=false)\n\nReturn the tropical hypersurface of the tropical polynomial that is the image of f under coefficient-wise val. If weighted_polyhedral_complex==true, will not cache any extra information.\n\nExamples\n\njulia> R,(x,y) = QQ[:x, :y];\n\njulia> val = tropical_semiring_map(QQ,2)\nMap into Min tropical semiring encoding the 2-adic valuation on Rational field\n\njulia> f = x+y+2\nx + y + 2\n\njulia> tropical_hypersurface(f,val)\nMin tropical hypersurface\n\n\n\n\n\n\ntropical_hypersurface(Delta::SubdivisionOfPoints, minOrMax::Union{typeof(min),typeof(max)}=min; weighted_polyhedral_complex_only::Bool=false)\n\nConstruct the tropical hypersurface dual to a regular subdivision Delta in convention minOrMax. To be precise, the tropical hypersurface of the tropical polynomial with exponent vectors points(Delta) and coefficients min_weight(Delta) (min-convention) or -min_weight(Delta) (max-convention). If weighted_polyhedral_complex==true, will not cache any extra information.\n\nExamples\n\njulia> Delta = subdivision_of_points([0 0; 1 0; 0 1; 2 0],[0,0,0,1])\nSubdivision of points in ambient dimension 2\n\njulia> tropical_hypersurface(Delta)\nMin tropical hypersurface\n\n\n\n\n\n","category":"function"},{"location":"TropicalGeometry/hypersurface/#Properties","page":"Tropical hypersurfaces","title":"Properties","text":"","category":"section"},{"location":"TropicalGeometry/hypersurface/","page":"Tropical hypersurfaces","title":"Tropical hypersurfaces","text":"In addition to the properties inherited from TropicalVariety, objects of type TropicalHypersurface have the following exclusive properties:","category":"page"},{"location":"TropicalGeometry/hypersurface/","page":"Tropical hypersurfaces","title":"Tropical hypersurfaces","text":"algebraic_polynomial(TropH::TropicalHypersurface)\ntropical_polynomial(TropH::TropicalHypersurface)\ndual_subdivision(TropH::TropicalHypersurface)","category":"page"},{"location":"TropicalGeometry/hypersurface/#algebraic_polynomial-Tuple{TropicalHypersurface}","page":"Tropical hypersurfaces","title":"algebraic_polynomial","text":"algebraic_polynomial(TropH::TropicalHypersurface)\n\nReturn the polynomial over a valued field used to construct TropH. Raises an error if it is not cached.\n\n\n\n\n\n","category":"method"},{"location":"TropicalGeometry/hypersurface/#tropical_polynomial-Tuple{TropicalHypersurface}","page":"Tropical hypersurfaces","title":"tropical_polynomial","text":"tropical_polynomial(TropH::TropicalHypersurface)\n\nReturn the tropical polynomial used to construct TropH. Raises an error if it is not cached.\n\n\n\n\n\n","category":"method"},{"location":"TropicalGeometry/hypersurface/#dual_subdivision-Tuple{TropicalHypersurface}","page":"Tropical hypersurfaces","title":"dual_subdivision","text":"dual_subdivision(TropH::TropicalHypersurface)\n\nReturn the dual subdivision used to construct TropH. Raises an error if it is not cached.\n\nExamples\n\njulia> Delta = subdivision_of_points([0 0; 1 0; 0 1; 2 0],[0,0,0,1])\nSubdivision of points in ambient dimension 2\n\njulia> th = tropical_hypersurface(Delta)\nMin tropical hypersurface\n\njulia> sop = dual_subdivision(th)\nSubdivision of points in ambient dimension 2\n\njulia> points(sop)\n4-element SubObjectIterator{PointVector{QQFieldElem}}:\n [0, 0]\n [1, 0]\n [0, 1]\n [2, 0]\n\njulia> maximal_cells(sop)\n2-element SubObjectIterator{Vector{Int64}}:\n [1, 2, 3]\n [2, 3, 4]\n\n\n\n\n\n","category":"method"},{"location":"TropicalGeometry/hypersurface/#Example","page":"Tropical hypersurfaces","title":"Example","text":"","category":"section"},{"location":"TropicalGeometry/hypersurface/","page":"Tropical hypersurfaces","title":"Tropical hypersurfaces","text":"The following code sets up an example and prints the vertices and rays of the tropical hypersurface (in no particular order).","category":"page"},{"location":"TropicalGeometry/hypersurface/","page":"Tropical hypersurfaces","title":"Tropical hypersurfaces","text":"julia> T = tropical_semiring();\n\njulia> Tx,(x1,x2) = polynomial_ring(T, 2);\n\njulia> g = 1 + 2*x1^2 + 2*x2^2 + 1*x1*x2;\n\njulia> TropH = tropical_hypersurface(g);\n\njulia> vertRays = vertices_and_rays(TropH)\n5-element SubObjectIterator{Union{PointVector{QQFieldElem}, RayVector{QQFieldElem}}}:\n [-1, -1]\n [1, 0]\n [0, 1]\n [-1//2, 1//2]\n [1//2, -1//2]","category":"page"},{"location":"TropicalGeometry/hypersurface/","page":"Tropical hypersurfaces","title":"Tropical hypersurfaces","text":"By broadcasting the typeof() command, we can see, which are vertices, and which are rays.","category":"page"},{"location":"TropicalGeometry/hypersurface/","page":"Tropical hypersurfaces","title":"Tropical hypersurfaces","text":"julia> typeof.(vertRays)\n5-element Vector{DataType}:\n RayVector{QQFieldElem}\n RayVector{QQFieldElem}\n RayVector{QQFieldElem}\n PointVector{QQFieldElem}\n PointVector{QQFieldElem}","category":"page"},{"location":"TropicalGeometry/hypersurface/","page":"Tropical hypersurfaces","title":"Tropical hypersurfaces","text":"The maximal polyhedra of our tropical hypersurface is simply the edges (both bounded and unbounded). The command maximal_polyhedra() gives us a list of these edges (in no particular order).","category":"page"},{"location":"TropicalGeometry/hypersurface/","page":"Tropical hypersurfaces","title":"Tropical hypersurfaces","text":"julia> maxPol = maximal_polyhedra(TropH)\n5-element SubObjectIterator{Polyhedron{QQFieldElem}}:\n Polyhedron in ambient dimension 2\n Polyhedron in ambient dimension 2\n Polyhedron in ambient dimension 2\n Polytope in ambient dimension 2\n Polyhedron in ambient dimension 2","category":"page"},{"location":"TropicalGeometry/hypersurface/","page":"Tropical hypersurfaces","title":"Tropical hypersurfaces","text":"The polyhedrons are the unbounded edges, and the polytopes are the bounded edges.","category":"page"},{"location":"TropicalGeometry/hypersurface/","page":"Tropical hypersurfaces","title":"Tropical hypersurfaces","text":"The incidence matrix of the maximal polyhedra is a list of the relations between the elements of vertices_and_rays(TropH). From these relations, we can draw the hypersurface. However, one should be careful, as there is no distinction between vertices and rays in the incidence matrix.","category":"page"},{"location":"TropicalGeometry/hypersurface/","page":"Tropical hypersurfaces","title":"Tropical hypersurfaces","text":"julia> IncidenceMatrix(maxPol)\n5×5 IncidenceMatrix\n[1, 4]\n[1, 5]\n[3, 4]\n[4, 5]\n[2, 5]","category":"page"},{"location":"TropicalGeometry/hypersurface/","page":"Tropical hypersurfaces","title":"Tropical hypersurfaces","text":"This is made clearer if we ask for the vertices of each of the maximal polyhedra (the bounded edges have a vertex at each end, while the unbounded only have one vertex).","category":"page"},{"location":"TropicalGeometry/hypersurface/","page":"Tropical hypersurfaces","title":"Tropical hypersurfaces","text":"julia> vertices.(maxPol)\n5-element Vector{SubObjectIterator{PointVector{QQFieldElem}}}:\n [[-1//2, 1//2]]\n [[1//2, -1//2]]\n [[-1//2, 1//2]]\n [[-1//2, 1//2], [1//2, -1//2]]\n [[1//2, -1//2]]","category":"page"},{"location":"TropicalGeometry/hypersurface/","page":"Tropical hypersurfaces","title":"Tropical hypersurfaces","text":"Instead of being between two vertices, the unbounded edges are defined by a vertex and a ray. These rays can be seen in the following way.","category":"page"},{"location":"TropicalGeometry/hypersurface/","page":"Tropical hypersurfaces","title":"Tropical hypersurfaces","text":"julia> rays.(maxPol)\n5-element Vector{SubObjectIterator{RayVector{QQFieldElem}}}:\n [[-1, -1]]\n [[-1, -1]]\n [[0, 1]]\n 0-element SubObjectIterator{RayVector{QQFieldElem}}\n [[1, 0]]","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/#Advanced-printing","page":"Miscellaneous","title":"Advanced printing","text":"","category":"section"},{"location":"AbstractAlgebra/misc/#Self-given-names","page":"Miscellaneous","title":"Self-given names","text":"","category":"section"},{"location":"AbstractAlgebra/misc/","page":"Miscellaneous","title":"Miscellaneous","text":"We provide macros @show_name, @show_special and @show_special_elem to change the way certain objects are printed.","category":"page"},{"location":"AbstractAlgebra/misc/","page":"Miscellaneous","title":"Miscellaneous","text":"In compact and terse printing mode, @show_name tries to determine a suitable name to print instead of the object (see AbstractAlgebra.get_name).","category":"page"},{"location":"AbstractAlgebra/misc/","page":"Miscellaneous","title":"Miscellaneous","text":"@show_special checks if an attribute :show is present. If so, it has to be a function taking IO, optionally a MIME-type, and the object. This is then called instead of the usual show function.","category":"page"},{"location":"AbstractAlgebra/misc/","page":"Miscellaneous","title":"Miscellaneous","text":"Similarly, @show_special_elem checks if an attribute :show_elem is present in the object's parent. The semantics are the same as for @show_special.","category":"page"},{"location":"AbstractAlgebra/misc/","page":"Miscellaneous","title":"Miscellaneous","text":"All are supposed to be used within the usual show function, where @show_special_elem is only relevant for element types of algebraic structures.","category":"page"},{"location":"AbstractAlgebra/misc/","page":"Miscellaneous","title":"Miscellaneous","text":"@attributes MyObj\n\nfunction show(io::IO, A::MyObj)\n @show_name(io, A)\n @show_special(io, A)\n\n # ... usual stuff\nend\n\nfunction show(io::IO, mime::MIME\"text/plain\", A::MyObj)\n @show_name(io, A)\n @show_special(io, mime, A)\n\n # ... usual stuff\nend\n\nfunction show(io::IO, A::MyObjElem)\n @show_name(io, A)\n @show_special_elem(io, A)\n\n # ... usual stuff\nend\n\nfunction show(io::IO, mime::MIME\"text/plain\", A::MyObjElem)\n @show_name(io, A)\n @show_special_elem(io, mime, A)\n\n # ... usual stuff\nend","category":"page"},{"location":"AbstractAlgebra/misc/#Documentation","page":"Miscellaneous","title":"Documentation","text":"","category":"section"},{"location":"AbstractAlgebra/misc/","page":"Miscellaneous","title":"Miscellaneous","text":"AbstractAlgebra.@show_special\nAbstractAlgebra.@show_special_elem\nAbstractAlgebra.@show_name\nAbstractAlgebra.get_name\nAbstractAlgebra.set_name!\nAbstractAlgebra.extra_name\nAbstractAlgebra.PrettyPrinting.find_name","category":"page"},{"location":"AbstractAlgebra/misc/#@show_special","page":"Miscellaneous","title":"@show_special","text":"@show_special(io::IO, obj)\n\nIf the obj has a show attribute, this gets called with io and obj and returns from the current scope. Otherwise, does nothing.\n\nobj is required to have attribute storage available.\n\nIt is supposed to be used at the start of show methods as shown in the documentation.\n\n\n\n\n\n@show_special(io::IO, mime, obj)\n\nIf the obj has a show attribute, this gets called with io, mime and obj (if applicable) and io and obj otherwise, and returns from the current scope. Otherwise, does nothing.\n\nobj is required to have attribute storage available.\n\nIt is supposed to be used at the start of show methods as shown in the documentation.\n\n\n\n\n\n","category":"macro"},{"location":"AbstractAlgebra/misc/#@show_special_elem","page":"Miscellaneous","title":"@show_special_elem","text":"@show_special_elem(io::IO, obj)\n\nIf the parent of obj has a show_elem attribute, this gets called with io and obj and returns from the current scope. Otherwise, does nothing.\n\nparent(obj) is required to have attribute storage available.\n\nIt is supposed to be used at the start of show methods as shown in the documentation.\n\n\n\n\n\n@show_special_elem(io::IO, mime, obj)\n\nIf the parent of obj has a show_elem attribute, this gets called with io, mime and obj (if applicable) and io and obj otherwise, and returns from the current scope. Otherwise, does nothing.\n\nparent(obj) is required to have attribute storage available.\n\nIt is supposed to be used at the start of show methods as shown in the documentation.\n\n\n\n\n\n","category":"macro"},{"location":"AbstractAlgebra/misc/#@show_name","page":"Miscellaneous","title":"@show_name","text":"@show_name(io::IO, obj)\n\nIf either is_terse(io) is true or property :compact is set to true for io (see IOContext), print the name get_name(obj) of the object obj to the io stream, then return from the current scope. Otherwise, do nothing.\n\nIt is supposed to be used at the start of show methods as shown in the documentation.\n\n\n\n\n\n","category":"macro"},{"location":"AbstractAlgebra/misc/#get_name","page":"Miscellaneous","title":"get_name","text":"get_name(obj) -> Union{String,Nothing}\n\nReturns the name of the object obj if it is set, or nothing otherwise. This function tries to find a name in the following order:\n\nThe name set by AbstractAlgebra.set_name!.\nThe name of a variable in global (Main module) namespace with value bound to the object obj (see AbstractAlgebra.PrettyPrinting.find_name).\nThe name returned by AbstractAlgebra.extra_name.\n\n\n\n\n\n","category":"function"},{"location":"AbstractAlgebra/misc/#set_name!","page":"Miscellaneous","title":"set_name!","text":"set_name!(obj, name::String; override::Bool=true)\n\nSets the name of the object obj to name. This name is used for printing using AbstractAlgebra.@show_name. If override is false, the name is only set if there is no name already set.\n\nThis function errors if obj does not support attribute storage.\n\n\n\n\n\nset_name!(obj; override::Bool=true)\n\nSets the name of the object obj to the name of a variable in global (Main module) namespace with value bound to the object obj, if such a variable exists (see AbstractAlgebra.PrettyPrinting.find_name). This name is used for printing using AbstractAlgebra.@show_name. If override is false, the name is only set if there is no name already set.\n\nThis function errors if obj does not support attribute storage.\n\n\n\n\n\n","category":"function"},{"location":"AbstractAlgebra/misc/#extra_name","page":"Miscellaneous","title":"extra_name","text":"extra_name(obj) -> Union{String,Nothing}\n\nMay be overloaded to provide a fallback name for the object obj in AbstractAlgebra.get_name. The default implementation returns nothing.\n\n\n\n\n\n","category":"function"},{"location":"AbstractAlgebra/misc/#find_name","page":"Miscellaneous","title":"find_name","text":"find_name(obj, M = Main; all::Bool = false) -> Union{String,Nothing}\n\nReturn name of a variable in M's namespace with value bound to the object obj, or nothing if no such variable exists. If all is true, private and non-exported variables are also searched.\n\nnote: Note\nIf the object is stored in several variables, the first one will be used, but a name returned once is kept until the variable no longer contains this object.\n\nFor this to work in doctests, one should call AbstractAlgebra.set_current_module(@__MODULE__) in the value argument of Documenter.DocMeta.setdocmeta! and keep the default value of M = Main here.\n\nwarning: Warning\nThis function should not be used directly, but rather through AbstractAlgebra.get_name.\n\n\n\n\n\n","category":"function"},{"location":"AbstractAlgebra/misc/#Indentation-and-Decapitalization","page":"Miscellaneous","title":"Indentation and Decapitalization","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-2","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":"AbstractAlgebra/misc/","page":"Miscellaneous","title":"Miscellaneous","text":"AbstractAlgebra.terse\nAbstractAlgebra.is_terse","category":"page"},{"location":"AbstractAlgebra/misc/#terse","page":"Miscellaneous","title":"terse","text":"terse(io::IO) -> IO\n\nReturn a new IO objects derived from io for which \"terse\" printing mode has been enabled.\n\nSee https://docs.oscar-system.org/stable/DeveloperDocumentation/printing_details/ for details.\n\nExamples\n\njulia> AbstractAlgebra.is_terse(stdout)\nfalse\n\njulia> io = AbstractAlgebra.terse(stdout);\n\njulia> AbstractAlgebra.is_terse(io)\ntrue\n\n\n\n\n\n","category":"function"},{"location":"AbstractAlgebra/misc/#is_terse","page":"Miscellaneous","title":"is_terse","text":"is_terse(io::IO) -> Bool\n\nTest whether \"terse\" printing mode is enabled for io.\n\nSee https://docs.oscar-system.org/stable/DeveloperDocumentation/printing_details/ for details.\n\nExamples\n\njulia> AbstractAlgebra.is_terse(stdout)\nfalse\n\njulia> io = AbstractAlgebra.terse(stdout);\n\njulia> AbstractAlgebra.is_terse(io)\ntrue\n\n\n\n\n\n","category":"function"},{"location":"AbstractAlgebra/misc/#Linear-solving-interface-for-developers","page":"Miscellaneous","title":"Linear solving interface for developers","text":"","category":"section"},{"location":"AbstractAlgebra/misc/","page":"Miscellaneous","title":"Miscellaneous","text":"AbstractAlgebra has a generic interface for linear solving and we describe here how one may extend this interface. For the user-facing functionality of linear solving, see Linear Solving.","category":"page"},{"location":"AbstractAlgebra/misc/","page":"Miscellaneous","title":"Miscellaneous","text":"Notice that the functionality is implemented in the module AbstractAlgebra.Solve and the internal functions are not exported from there.","category":"page"},{"location":"AbstractAlgebra/misc/#Matrix-normal-forms","page":"Miscellaneous","title":"Matrix normal forms","text":"","category":"section"},{"location":"AbstractAlgebra/misc/","page":"Miscellaneous","title":"Miscellaneous","text":"To distinguish between different algorithms, we use type traits of abstract type MatrixNormalFormTrait which usually correspond to a certain matrix normal form. The available algorithms/normal forms are","category":"page"},{"location":"AbstractAlgebra/misc/","page":"Miscellaneous","title":"Miscellaneous","text":"HowellFormTrait: uses a Howell form;\nHermiteFormTrait: uses a Hermite normal form;\nRREFTrait: uses a row-reduced echelon form over fields;\nLUTrait: uses a LU factoring of the matrix;\nFFLUTrait: uses a \"fraction-free\" LU factoring of the matrix over fraction fields;\nMatrixInterpolateTrait: uses interpolation of polynomials for fraction fields of polynomial rings.","category":"page"},{"location":"AbstractAlgebra/misc/","page":"Miscellaneous","title":"Miscellaneous","text":"To select a normal form type for rings of type NewRing, implement the function","category":"page"},{"location":"AbstractAlgebra/misc/","page":"Miscellaneous","title":"Miscellaneous","text":"Solve.matrix_normal_form_type(::NewRing) = Bla()","category":"page"},{"location":"AbstractAlgebra/misc/","page":"Miscellaneous","title":"Miscellaneous","text":"where Bla <: MatrixNormalFormTrait. A new type trait can be added via","category":"page"},{"location":"AbstractAlgebra/misc/","page":"Miscellaneous","title":"Miscellaneous","text":"struct NewTrait <: Solve.MatrixNormalFormTrait end","category":"page"},{"location":"AbstractAlgebra/misc/#Internal-solving-functionality","page":"Miscellaneous","title":"Internal solving functionality","text":"","category":"section"},{"location":"AbstractAlgebra/misc/","page":"Miscellaneous","title":"Miscellaneous","text":"If a new ring type NewRing can make use of one of the available MatrixNormalFormTraits, then it suffices to specify this normal form as described above to use the generic solving functionality. (However, for example HermiteFormTrait requires that the function hermite_form_with_transformation is implemented.)","category":"page"},{"location":"AbstractAlgebra/misc/","page":"Miscellaneous","title":"Miscellaneous","text":"For a new trait NewTrait <: MatrixNormalFormTrait, one needs to implement the function","category":"page"},{"location":"AbstractAlgebra/misc/","page":"Miscellaneous","title":"Miscellaneous","text":"Solve._can_solve_internal_no_check(\n ::NewTrait, A::MatElem{T}, b::MatElem{T}, task::Symbol; side::Symbol = :left\n ) where T","category":"page"},{"location":"AbstractAlgebra/misc/","page":"Miscellaneous","title":"Miscellaneous","text":"Inside this function, one can assume that A and b have the same base ring and have compatible dimensions. Further, task and side are set to \"legal\" options. (All this is checked in Solve._can_solve_internal.) This function should then (try to) solve Ax = b (side == :right) or xA = b (side == :left) possibly with kernel. The function must always return a tuple (::Bool, ::MatElem{T}, ::MatElem{T}) consisting of:","category":"page"},{"location":"AbstractAlgebra/misc/","page":"Miscellaneous","title":"Miscellaneous","text":"true/false whether a solution exists or not\nthe solution (or a placeholder if no solution exists or a solution is not requested)\nthe kernel (or a placeholder if the kernel is not requested)","category":"page"},{"location":"AbstractAlgebra/misc/","page":"Miscellaneous","title":"Miscellaneous","text":"The input task may be:","category":"page"},{"location":"AbstractAlgebra/misc/","page":"Miscellaneous","title":"Miscellaneous","text":":only_check: Only test whether there is a solution, the second and third return value are only for type stability;\n:with_solution: Compute a solution, if it exists, the last return value is only for type stability;\n:with_kernel: Compute a solution and a kernel.","category":"page"},{"location":"AbstractAlgebra/misc/","page":"Miscellaneous","title":"Miscellaneous","text":"One should further implement the function","category":"page"},{"location":"AbstractAlgebra/misc/","page":"Miscellaneous","title":"Miscellaneous","text":"kernel(::NewTrait, A::MatElem; side::Symbol = :left)","category":"page"},{"location":"AbstractAlgebra/misc/","page":"Miscellaneous","title":"Miscellaneous","text":"which computes a left (or right) kernel of A.","category":"page"},{"location":"AbstractAlgebra/misc/#Internal-solve-context-functionality","page":"Miscellaneous","title":"Internal solve context functionality","text":"","category":"section"},{"location":"AbstractAlgebra/misc/","page":"Miscellaneous","title":"Miscellaneous","text":"To efficiently solve several linear systems with the same matrix A, we provide the \"solve contexts objects\" of type Solve.SolveCtx. These can be extended for a ring of type NewRing as follows.","category":"page"},{"location":"AbstractAlgebra/misc/#Solve-context-type","page":"Miscellaneous","title":"Solve context type","text":"","category":"section"},{"location":"AbstractAlgebra/misc/","page":"Miscellaneous","title":"Miscellaneous","text":"For a new ring type, one may have to define the type parameters of a SolveCtx object. First of all, one needs to implement the function","category":"page"},{"location":"AbstractAlgebra/misc/","page":"Miscellaneous","title":"Miscellaneous","text":"function Solve.solve_context_type(::NewRing)\n return Solve.solve_context_type(::NormalFormTrait, elem_type(NewRing))\nend","category":"page"},{"location":"AbstractAlgebra/misc/","page":"Miscellaneous","title":"Miscellaneous","text":"to pick a MatrixNormalFormTrait.","category":"page"},{"location":"AbstractAlgebra/misc/","page":"Miscellaneous","title":"Miscellaneous","text":"Usually, nothing else should be necessary. However, if for example the normal form of a matrix does not live over the same ring as the matrix itself, one might also need to implement","category":"page"},{"location":"AbstractAlgebra/misc/","page":"Miscellaneous","title":"Miscellaneous","text":"function Solve.solve_context_type(NF::NormalFormTrait, T::Type{NewRingElem})\n return Solve.SolveCtx{T, typeof(NF), MatType, RedMatType, TranspMatType}\nend","category":"page"},{"location":"AbstractAlgebra/misc/","page":"Miscellaneous","title":"Miscellaneous","text":"where MatType is the dense matrix type over NewRing, RedMatType the type of a matrix in reduced/normal form and TranspMatType the type of the reduced/normal form of the transposed matrix.","category":"page"},{"location":"AbstractAlgebra/misc/#Initialization","page":"Miscellaneous","title":"Initialization","text":"","category":"section"},{"location":"AbstractAlgebra/misc/","page":"Miscellaneous","title":"Miscellaneous","text":"To initialize the solve context functionality for a new normal form NewTrait, one needs to implement the functions","category":"page"},{"location":"AbstractAlgebra/misc/","page":"Miscellaneous","title":"Miscellaneous","text":"Solve._init_reduce(C::SolveCtx{T, NewTrait}) where T\nSolve._init_reduce_transpose(C::SolveCtx{T, NewTrait}) where T","category":"page"},{"location":"AbstractAlgebra/misc/","page":"Miscellaneous","title":"Miscellaneous","text":"These should fill the corresponding fields of the solve context C with a \"reduced matrix\" (that is, a matrix in normal form) of matrix(C), respectively transpose(matrix(C)), and other information necessary to solve a linear system. The fields can be accessed via reduced_matrix, reduced_matrix_of_transpose, etc. New fields may also be added via attributes.","category":"page"},{"location":"AbstractAlgebra/misc/#Internal-solving-functionality-2","page":"Miscellaneous","title":"Internal solving functionality","text":"","category":"section"},{"location":"AbstractAlgebra/misc/","page":"Miscellaneous","title":"Miscellaneous","text":"As above, one finally needs to implement the functions","category":"page"},{"location":"AbstractAlgebra/misc/","page":"Miscellaneous","title":"Miscellaneous","text":"Solve._can_solve_internal_no_check(\n ::NewTrait, C::SolveCtx{T, NewTrait}, b::MatElem{T}, task::Symbol;\n side::Symbol = :left\n ) where T","category":"page"},{"location":"AbstractAlgebra/misc/","page":"Miscellaneous","title":"Miscellaneous","text":"and","category":"page"},{"location":"AbstractAlgebra/misc/","page":"Miscellaneous","title":"Miscellaneous","text":"kernel(::NewTrait, C::SolveCtx{T, NewTrait}; side::Symbol = :left)","category":"page"},{"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":"General/complex/#Omitted-input-sanity-checks","page":"Complex Algorithms in OSCAR","title":"Omitted input sanity checks","text":"","category":"section"},{"location":"General/complex/","page":"Complex Algorithms in OSCAR","title":"Complex Algorithms in OSCAR","text":"Some input sanity checks are omitted on purpose, since they would be too expensive to verify performance wise. We will continue to add to the following list.","category":"page"},{"location":"General/complex/","page":"Complex Algorithms in OSCAR","title":"Complex Algorithms in OSCAR","text":"Checking that the input for subdivision_of_points actually defines a proper polyhedral complex covering the convex hull of the given points.","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 add! 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":"AlgebraicGeometry/Schemes/CoveredSchemeMorphisms/","page":"Morphisms of covered schemes","title":"Morphisms of covered schemes","text":"CurrentModule = Oscar","category":"page"},{"location":"AlgebraicGeometry/Schemes/CoveredSchemeMorphisms/#Morphisms-of-covered-schemes","page":"Morphisms of covered schemes","title":"Morphisms of covered schemes","text":"","category":"section"},{"location":"AlgebraicGeometry/Schemes/CoveredSchemeMorphisms/","page":"Morphisms of covered schemes","title":"Morphisms of covered schemes","text":"Suppose f X to Y is a morphism of AbsCoveredSchemes. Theoretically, and hence also technically, the required information behind f is a list of morphisms of affine schemes f_i U_i to V_F(i) for some pair of Coverings leftU_iright_i in I of X and leftV_jright_j in J of Y and a map of indices F I to J This information is held by a CoveringMorphism:","category":"page"},{"location":"AlgebraicGeometry/Schemes/CoveredSchemeMorphisms/","page":"Morphisms of covered schemes","title":"Morphisms of covered schemes","text":" CoveringMorphism","category":"page"},{"location":"AlgebraicGeometry/Schemes/CoveredSchemeMorphisms/#CoveringMorphism","page":"Morphisms of covered schemes","title":"CoveringMorphism","text":"CoveringMorphism\n\nA morphism f C D of two coverings. For every patch U of C this provides a map f[U'] of type AffineSchemeMorType from U U to some patch codomain(f[U]) in D for some affine patches U covering U.\n\nNote: For two affine patches U₁ U₂ U the codomains of f[U₁] and f[U₂] do not need to coincide! However, given the gluings in C and D, all affine maps have to coincide on their overlaps.\n\n\n\n\n\n","category":"type"},{"location":"AlgebraicGeometry/Schemes/CoveredSchemeMorphisms/","page":"Morphisms of covered schemes","title":"Morphisms of covered schemes","text":"The basic functionality of CoveringMorphisms comprises domain and codomain which both return a Covering, together with ","category":"page"},{"location":"AlgebraicGeometry/Schemes/CoveredSchemeMorphisms/","page":"Morphisms of covered schemes","title":"Morphisms of covered schemes","text":"getindex(f::CoveringMorphism, U::AbsAffineScheme)","category":"page"},{"location":"AlgebraicGeometry/Schemes/CoveredSchemeMorphisms/","page":"Morphisms of covered schemes","title":"Morphisms of covered schemes","text":"which for U = U_i returns the AbsAffineSchemeMor f_i U_i to V_F(i).","category":"page"},{"location":"AlgebraicGeometry/Schemes/CoveredSchemeMorphisms/","page":"Morphisms of covered schemes","title":"Morphisms of covered schemes","text":"Note that, in general, neither the domain nor the codomain of the covering_morphism of f : X \\to Y need to coincide with the default_covering of X, respectively Y. In fact, one will usually need to restrict to a refinement of the default_covering of X in order to realize the covering morphism in the first place. ","category":"page"},{"location":"AlgebraicGeometry/Schemes/CoveredSchemeMorphisms/#The-interface-for-morphisms-of-covered-schemes","page":"Morphisms of covered schemes","title":"The interface for morphisms of covered schemes","text":"","category":"section"},{"location":"AlgebraicGeometry/Schemes/CoveredSchemeMorphisms/","page":"Morphisms of covered schemes","title":"Morphisms of covered schemes","text":"Every AbsCoveredSchemeMorphism f X to Y is required to implement the following minimal interface.","category":"page"},{"location":"AlgebraicGeometry/Schemes/CoveredSchemeMorphisms/","page":"Morphisms of covered schemes","title":"Morphisms of covered schemes","text":"domain(f::AbsCoveredSchemeMorphism) # returns X\ncodomain(f::AbsCoveredSchemeMorphism) # returns Y\ncovering_morphism(f::AbsCoveredSchemeMorphism) # returns the underlying covering morphism {f_i}","category":"page"},{"location":"AlgebraicGeometry/Schemes/CoveredSchemeMorphisms/","page":"Morphisms of covered schemes","title":"Morphisms of covered schemes","text":"For the user's convenience, also the domain and codomain of the underlying covering_morphism are forwarded as domain_covering and codomain_covering, respectively, together with getindex(phi::CoveringMorphism, U::AbsAffineScheme) as getindex(f::AbsCoveredSchemeMorphism, U::AbsAffineScheme).","category":"page"},{"location":"AlgebraicGeometry/Schemes/CoveredSchemeMorphisms/","page":"Morphisms of covered schemes","title":"Morphisms of covered schemes","text":"The minimal concrete type of an AbsCoveredSchemeMorphism which implements this interface, is CoveredSchemeMorphism.","category":"page"},{"location":"AlgebraicGeometry/Schemes/CoveredSchemeMorphisms/#Special-types-of-morphisms-of-covered-schemes","page":"Morphisms of covered schemes","title":"Special types of morphisms of covered schemes","text":"","category":"section"},{"location":"AlgebraicGeometry/Schemes/CoveredSchemeMorphisms/#Closed-embeddings","page":"Morphisms of covered schemes","title":"Closed embeddings","text":"","category":"section"},{"location":"AlgebraicGeometry/Schemes/CoveredSchemeMorphisms/","page":"Morphisms of covered schemes","title":"Morphisms of covered schemes","text":"CoveredClosedEmbedding\nimage_ideal(phi::CoveredClosedEmbedding)","category":"page"},{"location":"AlgebraicGeometry/Schemes/CoveredSchemeMorphisms/#CoveredClosedEmbedding","page":"Morphisms of covered schemes","title":"CoveredClosedEmbedding","text":"CoveredClosedEmbedding <: AbsCoveredSchemeMorphism\n\nType for closed embeddings of covered schemes.\n\nIn addition to the closed embedding it stores the sheaf of ideals defining the image.\n\n\n\n\n\n","category":"type"},{"location":"AlgebraicGeometry/Schemes/CoveredSchemeMorphisms/#image_ideal-Tuple{Oscar.CoveredClosedEmbedding}","page":"Morphisms of covered schemes","title":"image_ideal","text":"image_ideal(phi::CoveredClosedEmbedding)\n\nFor a closed embedding phi colon X to Y return the sheaf of ideals on Y defining the image of phi.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/CoveredSchemeMorphisms/#Composite-morphisms","page":"Morphisms of covered schemes","title":"Composite morphisms","text":"","category":"section"},{"location":"AlgebraicGeometry/Schemes/CoveredSchemeMorphisms/","page":"Morphisms of covered schemes","title":"Morphisms of covered schemes","text":"CompositeCoveredSchemeMorphism","category":"page"},{"location":"AlgebraicGeometry/Schemes/CoveredSchemeMorphisms/#CompositeCoveredSchemeMorphism","page":"Morphisms of covered schemes","title":"CompositeCoveredSchemeMorphism","text":"CompositeCoveredSchemeMorphism{\n DomainType<:AbsCoveredScheme,\n CodomainType<:AbsCoveredScheme,\n BaseMorphismType\n } <: AbsCoveredSchemeMorphism{\n DomainType,\n CodomainType,\n BaseMorphismType,\n CoveredSchemeMorphism\n }\n\nA special concrete type of an AbsCoveredSchemeMorphism of the form f = hᵣ hᵣ₁ h₁ X Y for arbitrary AbsCoveredSchemeMorphisms h₁ X Z₁, h₂ Z₁ Z₂, ..., hᵣ Zᵣ₁ Y.\n\nSince every such morphism hⱼ will in general have an underlying CoveringMorphism with domain and codomain covering actual composition of such a sequence of morphisms will lead to an exponential increase in complexity of these coverings because of the necessary refinements. Nevertheless, the pullback or pushforward of various objects on either X or Y through such a chain of maps is possible stepwise. This type allows one to have one concrete morphism rather than a list of morphisms and to reroute such calculations to iteration over the various maps.\n\nIn addition to the usual functionality of the AbsCoveredSchemeMorphism interface, this concrete type has the getters\n\nmaps(f::CompositeCoveredSchemeMorphism)\n\nto obtain a list of the hⱼ and map(f, j) to obtain the j-th map directly.\n\n\n\n\n\n","category":"type"},{"location":"AlgebraicGeometry/Schemes/CoveredSchemeMorphisms/#Morphisms-from-rational-functions","page":"Morphisms of covered schemes","title":"Morphisms from rational functions","text":"","category":"section"},{"location":"AlgebraicGeometry/Schemes/CoveredSchemeMorphisms/","page":"Morphisms of covered schemes","title":"Morphisms of covered schemes","text":"Suppose X and Y are two irreducible and reduced varieties. Then a morphism f X to Y might be given by means of the following data. Let V subset Y be some dense affine patch with coordinates x_1dotsx_n (i.e. the gens of OO(V)). ","category":"page"},{"location":"AlgebraicGeometry/Schemes/CoveredSchemeMorphisms/","page":"Morphisms of covered schemes","title":"Morphisms of covered schemes","text":"These x_i extend to rational functions v_i on Y and these pull back to rational functions f^* v_i = u_i on X. On every affine patch U subset X there now exists some maximal Zariski-open subset W subset U (which need not be affine), such that all the f^* v_i extend to regular functions on W. Hence, one can realize the morphisms of affine schemes f_j W_j to V for some open covering of W. ","category":"page"},{"location":"AlgebraicGeometry/Schemes/CoveredSchemeMorphisms/","page":"Morphisms of covered schemes","title":"Morphisms of covered schemes","text":"Similarly, for every other non-empty patch V_2 of Y the pullback of gens(OO(V_2)) can be computed from the f^* v_i and extended maximally to some W subset U for every patch U of X. Altogether, this allows to compute a full CoveringMorphism and – at least in theory – an instance of CoveredSchemeMorphism. In practice, however, this computation is usually much too expensive to really be carried out, while the data necessary to compute various pullbacks and/or pushforwards of objects defined on X and Y can be extracted from the f^* v_i more directly. ","category":"page"},{"location":"AlgebraicGeometry/Schemes/CoveredSchemeMorphisms/","page":"Morphisms of covered schemes","title":"Morphisms of covered schemes","text":"A lazy concrete data structure to house this kind of morphism is ","category":"page"},{"location":"AlgebraicGeometry/Schemes/CoveredSchemeMorphisms/","page":"Morphisms of covered schemes","title":"Morphisms of covered schemes","text":"MorphismFromRationalFunctions","category":"page"},{"location":"AlgebraicGeometry/Schemes/CoveredSchemeMorphisms/#MorphismFromRationalFunctions","page":"Morphisms of covered schemes","title":"MorphismFromRationalFunctions","text":"MorphismFromRationalFunctions{DomainType<:AbsCoveredScheme, CodomainType<:AbsCoveredScheme}\n\nA lazy type for a dominant morphism φ X Y of AbsCoveredSchemes which is given by a set of rational functions a₁aₙ in the fraction field of the base_ring of 𝒪(U) for one of the dense open affine_charts U of X. The aᵢ represent the pullbacks of the coordinates (gens) of some affine_chart V of the codomain Y under this map. \n\njulia> IP1 = covered_scheme(projective_space(QQ, [:s, :t]))\nScheme\n over rational field\nwith default covering\n described by patches\n 1: affine 1-space\n 2: affine 1-space\n in the coordinate(s)\n 1: [(t//s)]\n 2: [(s//t)]\n\njulia> IP2 = projective_space(QQ, [:x, :y, :z]);\n\njulia> S = homogeneous_coordinate_ring(IP2);\n\njulia> x, y, z = gens(S);\n\njulia> IPC, inc_IPC = sub(IP2, ideal(S, [x^2 - y*z]));\n\njulia> C = covered_scheme(IPC);\n\njulia> U = first(affine_charts(IP1))\nSpectrum\n of multivariate polynomial ring in 1 variable (t//s)\n over rational field\n\njulia> V = first(affine_charts(C))\nSpectrum\n of quotient\n of multivariate polynomial ring in 2 variables (y//x), (z//x)\n over rational field\n by ideal (-(y//x)*(z//x) + 1)\n\njulia> t = first(gens(OO(U)))\n(t//s)\n\njulia> Phi = MorphismFromRationalFunctions(IP1, C, U, V, [t//one(t), 1//t]);\n\njulia> realizations = Oscar.realize_on_patch(Phi, U);\n\njulia> realizations[3]\nAffine scheme morphism\n from [(t//s)] AA^1\n to [(x//z), (y//z)] scheme((x//z)^2 - (y//z))\ngiven by the pullback function\n (x//z) -> (t//s)\n (y//z) -> (t//s)^2\n\n\n\n\n\n\n","category":"type"},{"location":"AlgebraicGeometry/Schemes/CoveredSchemeMorphisms/","page":"Morphisms of covered schemes","title":"Morphisms of covered schemes","text":"Note that the key idea of this data type is to not use the underlying_morphism together with its covering_morphism, but to find cheaper ways to do computations! The computation of the underlying_morphism is triggered by any call to functions which have not been overwritten with a special method for f::MorphismFromRationalFunctions. However, this computation should be considered as way too expensive besides some small examples. ","category":"page"},{"location":"AlgebraicGeometry/Schemes/CoveredSchemeMorphisms/","page":"Morphisms of covered schemes","title":"Morphisms of covered schemes","text":"For instance, if one wants to pull back a prime ideal sheaf mathcal I on Y along some isomorphism f X to Y, then one only needs to find one realization f_j U_j to V_F(j) of f on affine patches U_j of X and V_F(j) of Y such that mathcal I(V_F(j))neq 0 and f_j^* mathcal I(V_F(j)) neq 0. Then f^* mathcal I can be extended uniquely to all of X from U_j and there is no need to realize the full covering_morphism of f. In order to facilitate such computations as lazy as possible, there are various fine-grained entry points and caching mechanisms to realize f on open subsets:","category":"page"},{"location":"AlgebraicGeometry/Schemes/CoveredSchemeMorphisms/","page":"Morphisms of covered schemes","title":"Morphisms of covered schemes","text":"realize_on_patch(Phi::MorphismFromRationalFunctions, U::AbsAffineScheme)\nrealize_on_open_subset(Phi::MorphismFromRationalFunctions, U::AbsAffineScheme, V::AbsAffineScheme)\nrealization_preview(Phi::MorphismFromRationalFunctions, U::AbsAffineScheme, V::AbsAffineScheme)\nrandom_realization(Phi::MorphismFromRationalFunctions, U::AbsAffineScheme, V::AbsAffineScheme)\ncheap_realization(Phi::MorphismFromRationalFunctions, U::AbsAffineScheme, V::AbsAffineScheme)\nrealize_maximally_on_open_subset(Phi::MorphismFromRationalFunctions, U::AbsAffineScheme, V::AbsAffineScheme)\nrealize(Phi::MorphismFromRationalFunctions)","category":"page"},{"location":"AlgebraicGeometry/Schemes/CoveredSchemeMorphisms/#realize_on_patch-Tuple{MorphismFromRationalFunctions, AbsAffineScheme}","page":"Morphisms of covered schemes","title":"realize_on_patch","text":"realize_on_patch(Phi::MorphismFromRationalFunctions, U::AbsAffineScheme)\n\nFor U in the domain_covering of Phi construct a list of morphisms fₖ Uₖ Vₖ from PrincipalOpenSubsets Uₖ of U to patches Vₖ in the codomain_covering so that altogether the fₖ can be assembled to a CoveringMorphism which realizes Phi.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/CoveredSchemeMorphisms/#realize_on_open_subset-Tuple{MorphismFromRationalFunctions, AbsAffineScheme, AbsAffineScheme}","page":"Morphisms of covered schemes","title":"realize_on_open_subset","text":"realize_on_open_subset(Phi::MorphismFromRationalFunctions, U::AbsAffineScheme, V::AbsAffineScheme)\n\nReturn a morphism f : U' → V from some PrincipalOpenSubset of U to V such that the restriction of Phi to U' is f. Note that U' need not be maximal with this property!\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/CoveredSchemeMorphisms/#realization_preview-Tuple{MorphismFromRationalFunctions, AbsAffineScheme, AbsAffineScheme}","page":"Morphisms of covered schemes","title":"realization_preview","text":"realization_preview(Phi::MorphismFromRationalFunctions, U::AbsAffineScheme, V::AbsAffineScheme)\n\nFor a pair (U, V) of patches in the domain_covering and the codomain_covering of Phi, respectively, this returns a list of elements in the fraction field of the ambient_coordinate_ring of U which represent the pullbacks of gens(OO(V)) under Phi to U.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/CoveredSchemeMorphisms/#random_realization-Tuple{MorphismFromRationalFunctions, AbsAffineScheme, AbsAffineScheme}","page":"Morphisms of covered schemes","title":"random_realization","text":"random_realization(Phi::MorphismFromRationalFunctions, U::AbsAffineScheme, V::AbsAffineScheme)\n\nFor a pair (U, V) of patches in the domain_covering and the codomain_covering of Phi, respectively, this creates a random PrincipalOpenSubset U' on which the restriction f : U' → V of Phi can be realized and returns that restriction. Note that U' need not (and usually will not) be maximal with this property.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/CoveredSchemeMorphisms/#cheap_realization-Tuple{MorphismFromRationalFunctions, AbsAffineScheme, AbsAffineScheme}","page":"Morphisms of covered schemes","title":"cheap_realization","text":"cheap_realization(Phi::MorphismFromRationalFunctions, U::AbsAffineScheme, V::AbsAffineScheme)\n\nFor a pair (U, V) of patches in the domain_covering and the codomain_covering of Phi, respectively, this creates a random PrincipalOpenSubset U' on which the restriction f : U' → V of Phi can be realized and returns that restriction. Note that U' need not (and usually will not) be maximal with this property.\n\nThis method is cheap in the sense that it simply inverts all representatives of the denominators occurring in the realization_preview(Phi, U, V).\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/CoveredSchemeMorphisms/#realize_maximally_on_open_subset-Tuple{MorphismFromRationalFunctions, AbsAffineScheme, AbsAffineScheme}","page":"Morphisms of covered schemes","title":"realize_maximally_on_open_subset","text":"realize_maximally_on_open_subset(Phi::MorphismFromRationalFunctions, U::AbsAffineScheme, V::AbsAffineScheme)\n\nFor a pair (U, V) of patches in the domain_covering and the codomain_covering of Phi, respectively, this returns a list of morphisms fₖ : U'ₖ → V such that the restriction of Phi to U'ₖ and V is fₖ and altogether the U'ₖ cover the maximal open subset U'⊂ U on which the restriction U' → V of Phi can be realized.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/CoveredSchemeMorphisms/#realize-Tuple{MorphismFromRationalFunctions}","page":"Morphisms of covered schemes","title":"realize","text":"realize(Phi::MorphismFromRationalFunctions)\n\nComputes a full realization of Phi as a CoveredSchemeMorphism. Note that this computation is very expensive and usage of this method should be avoided.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/","page":"-","title":"-","text":"---\n# https://vitepress.dev/reference/default-theme-home-page\nlayout: home\n\nhero:\n name: \"Hecke\"\n tagline: Computational number theory for everyone\n actions:\n - theme: alt\n text: Getting Started\n link: /start/\n - theme: alt\n text: Manual\n link: /manual/\n - theme: alt\n text: View on Github\n link: https://github.com/thofma/Hecke.jl\n\nfeatures:\n - title: What is Hecke?\n details: Hecke is a software package for computational algebraic number theory. It is written in julia and makes use of the computer algebra packages Nemo and AbstractAlgebra.\n - title: OSCAR\n details: Hecke is part of the [OSCAR](https://www.oscar-system.org/) system, which covers, in addition to number theory, also commutative algebra, algebraic geometry, group theory and polyhedral geometry.\n---","category":"page"},{"location":"Hecke/#Features","page":"-","title":"Features","text":"","category":"section"},{"location":"Hecke/","page":"-","title":"-","text":"Number fields (absolute, relative, simple and non-simple)\nOrders and ideals in number fields\nClass and unit group computations of orders\nLattice enumeration\nSparse linear algebra\nClass field theory\nAbelian groups\nAssociative algebras\nIdeals and orders in (semsimple) associative algebras\nLocally free class groups of orders in semisimple algebras\nQuadratic and Hermitian forms and lattices","category":"page"},{"location":"Hecke/#Citing-Hecke","page":"-","title":"Citing Hecke","text":"","category":"section"},{"location":"Hecke/","page":"-","title":"-","text":"If your research depends on computations done with Hecke, please consider giving us a formal citation:","category":"page"},{"location":"Hecke/","page":"-","title":"-","text":"Claus Fieker, William Hart, Tommy Hofmann and Fredrik Johansson, Nemo/Hecke: Computer Algebra and Number Theory Packages for the Julia Programming Language. In: Proceedings of ISSAC '17, pages 157–164, New York, NY, USA, 2017. ACM.","category":"page"},{"location":"Hecke/","page":"-","title":"-","text":"@inproceedings{nemo,\n author = {Fieker, Claus and Hart, William and Hofmann, Tommy and Johansson, Fredrik},\n title = {Nemo/Hecke: Computer Algebra and Number Theory Packages for the Julia Programming Language},\n booktitle = {Proceedings of the 2017 ACM on International Symposium on Symbolic and Algebraic Computation},\n series = {ISSAC '17},\n year = {2017},\n pages = {157--164},\n numpages = {8},\n url = {https://doi.acm.org/10.1145/3087604.3087611},\n doi = {10.1145/3087604.3087611},\n publisher = {ACM},\n address = {New York, NY, USA},\n}","category":"page"},{"location":"Hecke/#Acknowledgement","page":"-","title":"Acknowledgement","text":"","category":"section"},{"location":"Hecke/","page":"-","title":"-","text":"Hecke is part of the OSCAR project and the development is supported by the Deutsche Forschungsgemeinschaft DFG within the Collaborative Research Center TRR 195.","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 [CLS11]\nNormalToricVariety is the type for toric varieties associated to a polyhedral fan Sigma, denoted by X_Sigma in [CLS11]","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/#Equality-of-Normal-Toric-Varieties","page":"Normal Toric Varieties","title":"Equality of Normal Toric Varieties","text":"","category":"section"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/","page":"Normal Toric Varieties","title":"Normal Toric Varieties","text":"warning: Warning\nEquality of normal toric varieties is computationally very demanding. We have therefore made special design decisions for the == method.","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/","page":"Normal Toric Varieties","title":"Normal Toric Varieties","text":"In OSCAR, the == operator is reserved to check if two normal toric varieties are identical, meaning their underlying polyhedral fans are the same. However, this check is computationally challenging due to several reasons:","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/","page":"Normal Toric Varieties","title":"Normal Toric Varieties","text":"The ray generators might be scaled.\nThe ray generators might be stored in different orders.\nThe maximal (polyhedral) cones of the polyhedral fan might be stored in different orders.\nIf we fall back on polyhedral fan equality, lineality of the cones must also be considered.","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/","page":"Normal Toric Varieties","title":"Normal Toric Varieties","text":"To avoid this computational bottleneck, we have specially designed the == method. It checks if the memory locations of the two objects in question are identical. If so, our == method returns true. Otherwise, it raise an error.","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/","page":"Normal Toric Varieties","title":"Normal Toric Varieties","text":"Note that triple equality === (i.e. the check of equal the memory locations) is always supported for normal toric varieties. We recommend using it.","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/","page":"Normal Toric Varieties","title":"Normal Toric Varieties","text":"However, if you truly need to check for two normal toric varieties to be mathematically identical, then you will need to add a custom method. This method could look as follows:","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/","page":"Normal Toric Varieties","title":"Normal Toric Varieties","text":"function slow_equal(tv1::NormalToricVariety, tv2::NormalToricVariety)\n tv1 === tv2 && return true\n ambient_dim(tv1) == ambient_dim(tv2) || return false\n f_vector(tv1) == f_vector(tv2) || return false\n return Set(maximal_cones(tv1)) == Set(maximal_cones(tv2))\nend","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/","page":"Normal Toric Varieties","title":"Normal Toric Varieties","text":"Please note that this method slow_equal is not performant, that we currently (summer 2024) have no intentions in adding this function to OSCAR nor to make improvements to its performance. Rather, expect this method to be slow, potentially painfully so.","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/#Constructors","page":"Normal Toric Varieties","title":"Constructors","text":"","category":"section"},{"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)\nnormal_toric_variety(C::Cone)\naffine_normal_toric_variety(v::NormalToricVariety)","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)\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 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)\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 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)\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 toric variety\n\njulia> affineVariety = affine_normal_toric_variety(v)\nNormal 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","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/#normal_toric_variety","page":"Normal Toric Varieties","title":"normal_toric_variety","text":"normal_toric_variety(C::Cone)\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 toric variety\n\n\n\n\n\nnormal_toric_variety(max_cones::IncidenceMatrix, rays::AbstractCollection[RayVector]; non_redundant::Bool = false)\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 = incidence_matrix([[1, 2], [2, 3], [3, 4], [4, 1]])\n4×4 IncidenceMatrix\n[1, 2]\n[2, 3]\n[3, 4]\n[1, 4]\n\njulia> normal_toric_variety(max_cones, ray_generators)\nNormal toric variety\n\njulia> normal_toric_variety(max_cones, ray_generators; non_redundant = true)\nNormal toric variety\n\n\n\n\n\nnormal_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)\nPolytope 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\nnormal_toric_variety(P::Polyhedron)\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)\nPolytope in ambient dimension 2\n\njulia> ntv = normal_toric_variety(square)\nNormal toric variety\n\n\n\n\n\n","category":"function"},{"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":"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/","page":"Normal Toric Varieties","title":"Normal Toric Varieties","text":"affine_space(::Type{NormalToricVariety}, d::Int)\ndel_pezzo_surface(::Type{NormalToricVariety}, b::Int)\nhirzebruch_surface(::Type{NormalToricVariety}, r::Int)\nprojective_space(::Type{NormalToricVariety}, d::Int)\nweighted_projective_space(::Type{NormalToricVariety}, w::Vector{T}) 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)\n\nConstruct the (toric) affine space of dimension d.\n\nExamples\n\njulia> affine_space(NormalToricVariety, 2)\nNormal 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)\n\nConstructs the del Pezzo surface with b blowups for b at most 3.\n\nExamples\n\njulia> del_pezzo_surface(NormalToricVariety, 3)\nNormal toric variety\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)\n\nConstruct the r-th Hirzebruch surface.\n\nExamples\n\njulia> hirzebruch_surface(NormalToricVariety, 5)\nNormal toric variety\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)\n\nConstruct the projective space of dimension d.\n\nExamples\n\njulia> projective_space(NormalToricVariety, 2)\nNormal toric variety\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}) 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 toric variety\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)\nnormal_toric_varieties_from_star_triangulations(P::Polyhedron)","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)\n\nReturn 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)\n\nReturn 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 generated by\n x1*x4\n\njulia> stanley_reisner_ideal(v2)\nIdeal generated by\n 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) [Wit88] 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 [FJR17], which describes this as GIT construction [CLS11].","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)\nnormal_toric_varieties_from_glsm(charges::ZZMatrix)","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/#normal_toric_variety_from_glsm-Tuple{ZZMatrix}","page":"Normal Toric Varieties","title":"normal_toric_variety_from_glsm","text":"normal_toric_variety_from_glsm(charges::ZZMatrix)\n\nReturn 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\nnormal_toric_variety_from_glsm(charges::Vector{Vector{Int}})\nnormal_toric_variety_from_glsm(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)\n\nReturn 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\nnormal_toric_varieties_from_glsm(charges::Vector{Vector{Int}})\nnormal_toric_varieties_from_glsm(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":"Base.:*(v::NormalToricVarietyType, w::NormalToricVarietyType)\nprojectivization(E::ToricLineBundle...)\ntotal_space(E::ToricLineBundle...)","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/#*-Tuple{Union{AffineNormalToricVariety, CyclicQuotientSingularity, NormalToricVariety}, Union{AffineNormalToricVariety, CyclicQuotientSingularity, NormalToricVariety}}","page":"Normal Toric Varieties","title":"*","text":"Base.:*(v::NormalToricVarietyType, w::NormalToricVarietyType)\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::NormalToricVarietyType, 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::NormalToricVarietyType)).\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 toric variety\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/#projectivization-Tuple{Vararg{ToricLineBundle}}","page":"Normal Toric Varieties","title":"projectivization","text":"projectivization(E::ToricLineBundle...)\n\nThis function computes the projectivization of a direct sum of line bundles or divisors. Please see [OM78] for more background information.\n\nExamples\n\nLet us construct the projective bundles X=mathbbP(mathcalO_mathbbP^1oplusmathcalO_mathbbP^1(1)) and Y=mathbbP(mathcalO_mathbbP^1oplusmathcalO_mathbbP^1(2)).\n\njulia> P1 = projective_space(NormalToricVariety, 1);\n\njulia> D0 = toric_divisor(P1, [0,0]);\n\njulia> D1 = toric_divisor(P1, [1,0]);\n\njulia> X = projectivization(D0, D1)\nNormal toric variety\n\njulia> L0 = toric_line_bundle(P1, [0]);\n\njulia> L1 = toric_line_bundle(P1, [2]);\n\njulia> Y = projectivization(L0, L1)\nNormal toric variety\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/#total_space-Tuple{Vararg{ToricLineBundle}}","page":"Normal Toric Varieties","title":"total_space","text":"total_space(E::ToricLineBundle...)\n\nThis function computes the total space of a direct sum of line bundles or divisors. Please see [OM78] for more background information.\n\nExamples\n\nLet us construct the toric Calabi-Yau varieties given by the total space of mathcalO_mathbbP^1(2)oplusmathcalO_mathbbP^1(-4) and omega_mathbbP^2.\n\njulia> P1 = projective_space(NormalToricVariety, 1);\n\njulia> L1 = toric_line_bundle(P1, [2]);\n\njulia> L2 = toric_line_bundle(P1, [-4]);\n\njulia> X = total_space(L1, L2)\nNormal toric variety\n\njulia> degree(canonical_bundle(X))\n0\n\njulia> P2 = projective_space(NormalToricVariety, 2);\n\njulia> D = canonical_divisor(P2);\n\njulia> Y = total_space(D)\nNormal toric variety\n\njulia> degree(canonical_bundle(Y))\n0\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::NormalToricVarietyType)\nis_affine(v::NormalToricVarietyType)\nis_complete(v::NormalToricVarietyType)\nis_fano(v::NormalToricVarietyType)\nis_gorenstein(v::NormalToricVarietyType)\nis_simplicial(v::NormalToricVarietyType)\nis_smooth(v::NormalToricVarietyType)\nis_normal(v::NormalToricVarietyType)\nis_orbifold(v::NormalToricVarietyType)\nis_projective(v::NormalToricVarietyType)\nis_projective_space(v::NormalToricVarietyType)\nis_q_gorenstein(v::NormalToricVarietyType)","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/#has_torusfactor-Tuple{Union{AffineNormalToricVariety, CyclicQuotientSingularity, NormalToricVariety}}","page":"Normal Toric Varieties","title":"has_torusfactor","text":"has_torusfactor(v::NormalToricVarietyType)\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{Union{AffineNormalToricVariety, CyclicQuotientSingularity, NormalToricVariety}}","page":"Normal Toric Varieties","title":"is_affine","text":"is_affine(v::NormalToricVarietyType)\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{Union{AffineNormalToricVariety, CyclicQuotientSingularity, NormalToricVariety}}","page":"Normal Toric Varieties","title":"is_complete","text":"is_complete(v::NormalToricVarietyType)\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{Union{AffineNormalToricVariety, CyclicQuotientSingularity, NormalToricVariety}}","page":"Normal Toric Varieties","title":"is_fano","text":"is_fano(v::NormalToricVarietyType)\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{Union{AffineNormalToricVariety, CyclicQuotientSingularity, NormalToricVariety}}","page":"Normal Toric Varieties","title":"is_gorenstein","text":"is_gorenstein(v::NormalToricVarietyType)\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{Union{AffineNormalToricVariety, CyclicQuotientSingularity, NormalToricVariety}}","page":"Normal Toric Varieties","title":"is_simplicial","text":"is_simplicial(v::NormalToricVarietyType)\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{Union{AffineNormalToricVariety, CyclicQuotientSingularity, NormalToricVariety}}","page":"Normal Toric Varieties","title":"is_smooth","text":"is_smooth(v::NormalToricVarietyType)\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{Union{AffineNormalToricVariety, CyclicQuotientSingularity, NormalToricVariety}}","page":"Normal Toric Varieties","title":"is_normal","text":"is_normal(v::NormalToricVarietyType)\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{Union{AffineNormalToricVariety, CyclicQuotientSingularity, NormalToricVariety}}","page":"Normal Toric Varieties","title":"is_orbifold","text":"is_orbifold(v::NormalToricVarietyType)\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{Union{AffineNormalToricVariety, CyclicQuotientSingularity, NormalToricVariety}}","page":"Normal Toric Varieties","title":"is_projective","text":"is_projective(v::NormalToricVarietyType)\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{Union{AffineNormalToricVariety, CyclicQuotientSingularity, NormalToricVariety}}","page":"Normal Toric Varieties","title":"is_projective_space","text":"is_projective_space(v::NormalToricVarietyType)\n\nDecides if the normal toric varieties v is a projective space.\n\nExamples\n\njulia> F5 = hirzebruch_surface(NormalToricVariety, 5)\nNormal toric variety\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{Union{AffineNormalToricVariety, CyclicQuotientSingularity, NormalToricVariety}}","page":"Normal Toric Varieties","title":"is_q_gorenstein","text":"is_q_gorenstein(v::NormalToricVarietyType)\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::NormalToricVarietyType )","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/#affine_open_covering-Tuple{Union{AffineNormalToricVariety, CyclicQuotientSingularity, NormalToricVariety}}","page":"Normal Toric Varieties","title":"affine_open_covering","text":"affine_open_covering(v::NormalToricVarietyType)\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 toric variety\n\njulia> affine_open_covering(p2)\n3-element Vector{AffineNormalToricVariety}:\n Normal toric variety\n Normal toric variety\n Normal 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::NormalToricVarietyType)\ncharacter_lattice(v::NormalToricVarietyType)\nclass_group(v::NormalToricVarietyType)\nmap_from_torusinvariant_cartier_divisor_group_to_torusinvariant_weil_divisor_group(v::NormalToricVarietyType)\nmap_from_torusinvariant_cartier_divisor_group_to_picard_group(v::NormalToricVarietyType)\nmap_from_character_lattice_to_torusinvariant_weil_divisor_group(v::NormalToricVarietyType)\nmap_from_torusinvariant_weil_divisor_group_to_class_group(v::NormalToricVarietyType)\npicard_group(v::NormalToricVarietyType)\ntorusinvariant_weil_divisor_group(v::NormalToricVarietyType)\ntorusinvariant_prime_divisors(v::NormalToricVarietyType)","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/#torusinvariant_cartier_divisor_group-Tuple{Union{AffineNormalToricVariety, CyclicQuotientSingularity, NormalToricVariety}}","page":"Normal Toric Varieties","title":"torusinvariant_cartier_divisor_group","text":"torusinvariant_cartier_divisor_group(v::NormalToricVarietyType)\n\nReturn the Cartier divisor group of an abstract normal toric variety v.\n\nExamples\n\njulia> p2 = projective_space(NormalToricVariety, 2)\nNormal toric variety\n\njulia> torusinvariant_cartier_divisor_group(p2)\nZ^3\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/#character_lattice-Tuple{Union{AffineNormalToricVariety, CyclicQuotientSingularity, NormalToricVariety}}","page":"Normal Toric Varieties","title":"character_lattice","text":"character_lattice(v::NormalToricVarietyType)\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)\nZ^2\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/#class_group-Tuple{Union{AffineNormalToricVariety, CyclicQuotientSingularity, NormalToricVariety}}","page":"Normal Toric Varieties","title":"class_group","text":"class_group(v::NormalToricVarietyType)\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)\nZ\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/#map_from_torusinvariant_cartier_divisor_group_to_torusinvariant_weil_divisor_group-Tuple{Union{AffineNormalToricVariety, CyclicQuotientSingularity, NormalToricVariety}}","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::NormalToricVarietyType)\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 toric variety\n\njulia> map_from_torusinvariant_cartier_divisor_group_to_torusinvariant_weil_divisor_group(p2)\nMap\n from Z^3\n to Z^3\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/#map_from_torusinvariant_cartier_divisor_group_to_picard_group-Tuple{Union{AffineNormalToricVariety, CyclicQuotientSingularity, NormalToricVariety}}","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::NormalToricVarietyType)\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 toric variety\n\njulia> map_from_torusinvariant_cartier_divisor_group_to_picard_group(p2)\nMap\n from Z^3\n to Z\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/#map_from_character_lattice_to_torusinvariant_weil_divisor_group-Tuple{Union{AffineNormalToricVariety, CyclicQuotientSingularity, NormalToricVariety}}","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::NormalToricVarietyType)\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\n from Z^2\n to Z^3\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/#map_from_torusinvariant_weil_divisor_group_to_class_group-Tuple{Union{AffineNormalToricVariety, CyclicQuotientSingularity, NormalToricVariety}}","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::NormalToricVarietyType)\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\n from Z^3\n to Z\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/#picard_group-Tuple{Union{AffineNormalToricVariety, CyclicQuotientSingularity, NormalToricVariety}}","page":"Normal Toric Varieties","title":"picard_group","text":"picard_group(v::NormalToricVarietyType)\n\nReturn the Picard group of an abstract normal toric variety v.\n\nExamples\n\njulia> p2 = projective_space(NormalToricVariety, 2)\nNormal toric variety\n\njulia> picard_group(p2)\nZ\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/#torusinvariant_weil_divisor_group-Tuple{Union{AffineNormalToricVariety, CyclicQuotientSingularity, NormalToricVariety}}","page":"Normal Toric Varieties","title":"torusinvariant_weil_divisor_group","text":"torusinvariant_weil_divisor_group(v::NormalToricVarietyType)\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)\nZ^3\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/#torusinvariant_prime_divisors-Tuple{Union{AffineNormalToricVariety, CyclicQuotientSingularity, NormalToricVariety}}","page":"Normal Toric Varieties","title":"torusinvariant_prime_divisors","text":"torusinvariant_prime_divisors(v::NormalToricVarietyType)\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/#Gorenstein-and-Picard-index","page":"Normal Toric Varieties","title":"Gorenstein and Picard index","text":"","category":"section"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/","page":"Normal Toric Varieties","title":"Normal Toric Varieties","text":"gorenstein_index(v::NormalToricVarietyType)\npicard_index(v::NormalToricVarietyType)","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/#gorenstein_index-Tuple{Union{AffineNormalToricVariety, CyclicQuotientSingularity, NormalToricVariety}}","page":"Normal Toric Varieties","title":"gorenstein_index","text":"gorenstein_index(v::NormalToricVarietyType)\n\nReturn the Gorenstein index of a mathbbQ-Gorenstein normal toric variety v. This is the smallest positive integer l such that -l K is Cartier, where K is a canonical divisor on v. See exercise 8.3.10 and 8.3.11 in [CLS11] for more details.\n\nExamples\n\njulia> gorenstein_index(weighted_projective_space(NormalToricVariety, [2,3,5]))\n3\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/#picard_index-Tuple{Union{AffineNormalToricVariety, CyclicQuotientSingularity, NormalToricVariety}}","page":"Normal Toric Varieties","title":"picard_index","text":"picard_index(v::NormalToricVarietyType)\n\nReturn the index of the Picard group in the class group of a simplicial normal toric variety v. Here, the Picard group embeds as the group of Cartier divisor classes into the class group via map_from_picard_group_to_class_group. See [HHS11] for more details.\n\nExamples\n\njulia> picard_index(weighted_projective_space(NormalToricVariety, [2,3,5]))\n30\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::NormalToricVarietyType)\ncone(v::AffineNormalToricVariety)\nweight_cone(v::AffineNormalToricVariety)\nhilbert_basis(v::AffineNormalToricVariety)\nmori_cone(v::NormalToricVariety)\nnef_cone(v::NormalToricVariety)","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/#polyhedral_fan-Tuple{Union{AffineNormalToricVariety, CyclicQuotientSingularity, NormalToricVariety}}","page":"Normal Toric Varieties","title":"polyhedral_fan","text":"polyhedral_fan(v::NormalToricVarietyType)\n\nReturn the fan of an abstract normal toric variety v.\n\nExamples\n\njulia> p2 = projective_space(NormalToricVariety, 2)\nNormal toric variety\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/#weight_cone-Tuple{AffineNormalToricVariety}","page":"Normal Toric Varieties","title":"weight_cone","text":"weight_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 toric variety\n\njulia> weight_cone(antv)\nPolyhedral cone in ambient dimension 2\n\njulia> polarize(cone(antv)) == weight_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 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 toric variety\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 toric variety\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::NormalToricVarietyType)\ndim_of_torusfactor(v::NormalToricVarietyType)\neuler_characteristic(v::NormalToricVarietyType)\nbetti_number(v::NormalToricVarietyType, i::Int)","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/#dim-Tuple{Union{AffineNormalToricVariety, CyclicQuotientSingularity, NormalToricVariety}}","page":"Normal Toric Varieties","title":"dim","text":"dim(v::NormalToricVarietyType)\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{Union{AffineNormalToricVariety, CyclicQuotientSingularity, NormalToricVariety}}","page":"Normal Toric Varieties","title":"dim_of_torusfactor","text":"dim_of_torusfactor(v::NormalToricVarietyType)\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{Union{AffineNormalToricVariety, CyclicQuotientSingularity, NormalToricVariety}}","page":"Normal Toric Varieties","title":"euler_characteristic","text":"euler_characteristic(v::NormalToricVarietyType)\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{Union{AffineNormalToricVariety, CyclicQuotientSingularity, NormalToricVariety}, Int64}","page":"Normal Toric Varieties","title":"betti_number","text":"betti_number(v::NormalToricVarietyType, 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 [CLS11]. 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 toric variety\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 [CLS11]),\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::NormalToricVarietyType) 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::NormalToricVarietyType, coordinate_names::AbstractVector{<:VarName})\nset_coordinate_names_of_torus(v::NormalToricVarietyType, coordinate_names::AbstractVector{<:VarName})","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/#set_coordinate_names-Tuple{Union{AffineNormalToricVariety, CyclicQuotientSingularity, NormalToricVariety}, AbstractVector{<:Union{Char, AbstractString, Symbol}}}","page":"Normal Toric Varieties","title":"set_coordinate_names","text":"set_coordinate_names(v::NormalToricVarietyType, coordinate_names::AbstractVector{<:VarName})\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::NormalToricVarietyType)).\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\njulia> set_coordinate_names(antv, [\"v\"])\n\njulia> coordinate_names(antv)\n1-element Vector{String}:\n \"v\"\n\njulia> set_coordinate_names(antv, ['w'])\n\njulia> coordinate_names(antv)\n1-element Vector{String}:\n \"w\"\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/#set_coordinate_names_of_torus-Tuple{Union{AffineNormalToricVariety, CyclicQuotientSingularity, NormalToricVariety}, AbstractVector{<:Union{Char, AbstractString, Symbol}}}","page":"Normal Toric Varieties","title":"set_coordinate_names_of_torus","text":"set_coordinate_names_of_torus(v::NormalToricVarietyType, coordinate_names::AbstractVector{<:VarName})\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::NormalToricVarietyType)\ncoordinate_names_of_torus(v::NormalToricVarietyType)","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/#coordinate_names-Tuple{Union{AffineNormalToricVariety, CyclicQuotientSingularity, NormalToricVariety}}","page":"Normal Toric Varieties","title":"coordinate_names","text":"coordinate_names(v::NormalToricVarietyType)\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{Union{AffineNormalToricVariety, CyclicQuotientSingularity, NormalToricVariety}}","page":"Normal Toric Varieties","title":"coordinate_names_of_torus","text":"coordinate_names_of_torus(v::NormalToricVarietyType)\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::NormalToricVarietyType)\nirrelevant_ideal(v::NormalToricVarietyType)\nideal_of_linear_relations(v::NormalToricVarietyType)\nstanley_reisner_ideal(v::NormalToricVarietyType)\ntoric_ideal(antv::AffineNormalToricVariety)\ncoordinate_ring_of_torus(v::NormalToricVarietyType)","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/#cox_ring-Tuple{Union{AffineNormalToricVariety, CyclicQuotientSingularity, NormalToricVariety}}","page":"Normal Toric Varieties","title":"cox_ring","text":"cox_ring(v::NormalToricVarietyType)\n\nComputes the Cox ring of the normal toric variety v. Note that [CLS11] refers to this ring as the \"total coordinate ring\". For uniformity with schemes, we also support the function coordinate_ring to refer to the Cox 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\njulia> cox_ring(p2) == coordinate_ring(p2)\ntrue\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/#irrelevant_ideal-Tuple{Union{AffineNormalToricVariety, CyclicQuotientSingularity, NormalToricVariety}}","page":"Normal Toric Varieties","title":"irrelevant_ideal","text":"irrelevant_ideal(v::NormalToricVarietyType)\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{Union{AffineNormalToricVariety, CyclicQuotientSingularity, NormalToricVariety}}","page":"Normal Toric Varieties","title":"ideal_of_linear_relations","text":"ideal_of_linear_relations(v::NormalToricVarietyType)\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{Union{AffineNormalToricVariety, CyclicQuotientSingularity, NormalToricVariety}}","page":"Normal Toric Varieties","title":"stanley_reisner_ideal","text":"stanley_reisner_ideal(v::NormalToricVarietyType)\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 toric variety\n\njulia> toric_ideal(antv)\nIdeal generated by\n -x1*x2 + x3*x4\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/#coordinate_ring_of_torus-Tuple{Union{AffineNormalToricVariety, CyclicQuotientSingularity, NormalToricVariety}}","page":"Normal Toric Varieties","title":"coordinate_ring_of_torus","text":"coordinate_ring_of_torus(v::NormalToricVarietyType)\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 y1, y2, y1_, y2_\n over rational field\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::NormalToricVarietyType)","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/#is_finalized-Tuple{Union{AffineNormalToricVariety, CyclicQuotientSingularity, NormalToricVariety}}","page":"Normal Toric Varieties","title":"is_finalized","text":"is_finalized(v::NormalToricVarietyType)\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::NormalToricVarietyType)\nirrelevant_ideal(R::MPolyRing, v::NormalToricVarietyType)\nideal_of_linear_relations(R::MPolyRing, v::NormalToricVarietyType)\nstanley_reisner_ideal(R::MPolyRing, v::NormalToricVarietyType)\ntoric_ideal(R::MPolyRing, antv::AffineNormalToricVariety)\ncoordinate_ring_of_torus(R::MPolyRing, v::NormalToricVarietyType)","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/#cox_ring-Tuple{MPolyRing, Union{AffineNormalToricVariety, CyclicQuotientSingularity, NormalToricVariety}}","page":"Normal Toric Varieties","title":"cox_ring","text":"cox_ring(R::MPolyRing, v::NormalToricVarietyType)\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 [CLS11] 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, Union{AffineNormalToricVariety, CyclicQuotientSingularity, NormalToricVariety}}","page":"Normal Toric Varieties","title":"irrelevant_ideal","text":"irrelevant_ideal(R::MPolyRing, v::NormalToricVarietyType)\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, Union{AffineNormalToricVariety, CyclicQuotientSingularity, NormalToricVariety}}","page":"Normal Toric Varieties","title":"ideal_of_linear_relations","text":"ideal_of_linear_relations(R::MPolyRing, v::NormalToricVarietyType)\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, Union{AffineNormalToricVariety, CyclicQuotientSingularity, NormalToricVariety}}","page":"Normal Toric Varieties","title":"stanley_reisner_ideal","text":"stanley_reisner_ideal(R::MPolyRing, v::NormalToricVarietyType)\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 toric variety\n\njulia> R, _ = polynomial_ring(QQ, 4);\n\njulia> toric_ideal(R, antv)\nIdeal generated by\n -x1*x2 + x3*x4\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/#coordinate_ring_of_torus-Tuple{MPolyRing, Union{AffineNormalToricVariety, CyclicQuotientSingularity, NormalToricVariety}}","page":"Normal Toric Varieties","title":"coordinate_ring_of_torus","text":"coordinate_ring_of_torus(R::MPolyRing, v::NormalToricVarietyType)\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::NormalToricVarietyType, character::Vector{ZZRingElem})\ncharacter_to_rational_function(R::MPolyRing, v::NormalToricVarietyType, character::Vector{ZZRingElem})","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/NormalToricVarieties/#character_to_rational_function-Tuple{Union{AffineNormalToricVariety, CyclicQuotientSingularity, NormalToricVariety}, Vector{ZZRingElem}}","page":"Normal Toric Varieties","title":"character_to_rational_function","text":"character_to_rational_function(v::NormalToricVarietyType, 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, Union{AffineNormalToricVariety, CyclicQuotientSingularity, NormalToricVariety}, Vector{ZZRingElem}}","page":"Normal Toric Varieties","title":"character_to_rational_function","text":"character_to_rational_function(R::MPolyRing, v::NormalToricVarietyType, 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 generated by\n -x1*x2 + x4^2\n 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 generated by\n x2*x3 - x4^2\n -x1*x3 + x2^2*x4\n -x1*x4 + x2^3\n -x1*x3^2 + x2*x4^3\n -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":"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 padic_field function.","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 PadicFieldElem 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":"padic_field","category":"page"},{"location":"Nemo/padic/#padic_field","page":"Padics","title":"padic_field","text":"padic_field(p::Integer; precision::Int=64, cached::Bool=true, check::Bool=true)\npadic_field(p::ZZRingElem; precision::Int=64, cached::Bool=true, check::Bool=true)\n\nReturn the p-adic field for the given prime p. The default absolute precision of elements of the field may be set with precision.\n\n\n\n\n\n","category":"function"},{"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":"julia> R = padic_field(7, precision = 30)\nField of 7-adic numbers\n\njulia> S = padic_field(ZZ(65537), precision = 30)\nField of 65537-adic numbers\n\njulia> a = R()\nO(7^30)\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/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(::PadicField, ::Integer)\nO(::PadicField, ::ZZRingElem)\nO(::PadicField, ::QQFieldElem)","category":"page"},{"location":"Nemo/padic/#O-Tuple{PadicField, Integer}","page":"Padics","title":"O","text":"O(R::PadicField, 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{PadicField, ZZRingElem}","page":"Padics","title":"O","text":"O(R::PadicField, 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{PadicField, QQFieldElem}","page":"Padics","title":"O","text":"O(R::PadicField, 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":"julia> R = padic_field(7, precision = 30)\nField of 7-adic numbers\n\njulia> S = padic_field(ZZ(65537), precision = 30)\nField of 65537-adic numbers\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/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 ZZRingElems or Julia BigInts, 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(::PadicField)","category":"page"},{"location":"Nemo/padic/#prime-Tuple{PadicField}","page":"Padics","title":"prime","text":"prime(R::PadicField)\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(::PadicFieldElem)","category":"page"},{"location":"Nemo/padic/#precision-Tuple{PadicFieldElem}","page":"Padics","title":"precision","text":"precision(a::PadicFieldElem)\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(::PadicFieldElem)","category":"page"},{"location":"Nemo/padic/#valuation-Tuple{PadicFieldElem}","page":"Padics","title":"valuation","text":"valuation(a::PadicFieldElem)\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, ::PadicFieldElem)\nlift(::QQField, ::PadicFieldElem)","category":"page"},{"location":"Nemo/padic/#lift-Tuple{ZZRing, PadicFieldElem}","page":"Padics","title":"lift","text":"lift(R::ZZRing, a::PadicFieldElem)\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, PadicFieldElem}","page":"Padics","title":"lift","text":"lift(R::QQField, a::PadicFieldElem)\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":"julia> R = padic_field(7, precision = 30)\nField of 7-adic numbers\n\njulia> a = 1 + 2*7 + 4*7^2 + O(R, 7^3)\n7^0 + 2*7^1 + 4*7^2 + O(7^3)\n\njulia> b = 7^2 + 3*7^3 + O(R, 7^5)\n7^2 + 3*7^3 + O(7^5)\n\njulia> c = R(2)\n2*7^0 + O(7^30)\n\njulia> k = precision(a)\n3\n\njulia> m = prime(R)\n7\n\njulia> n = valuation(b)\n2\n\njulia> p = lift(ZZ, a)\n211\n\njulia> q = lift(QQ, divexact(a, b))\n337//49","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(::PadicFieldElem)","category":"page"},{"location":"Nemo/padic/#sqrt-Tuple{PadicFieldElem}","page":"Padics","title":"sqrt","text":"Base.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\nsqrt(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\n","category":"method"},{"location":"Nemo/padic/","page":"Padics","title":"Padics","text":"Examples","category":"page"},{"location":"Nemo/padic/","page":"Padics","title":"Padics","text":"julia> R = padic_field(7, precision = 30)\nField of 7-adic numbers\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)\n3*7^0 + 5*7^1 + 7^2 + 7^3 + O(7^5)\n\njulia> f = sqrt(c)\n7^1 + 7^2 + O(7^3)\n\njulia> g = sqrt(R(121))\n3*7^0 + 5*7^1 + 6*7^2 + 6*7^3 + 6*7^4 + 6*7^5 + 6*7^6 + 6*7^7 + 6*7^8 + 6*7^9 + 6*7^10 + 6*7^11 + 6*7^12 + 6*7^13 + 6*7^14 + 6*7^15 + 6*7^16 + 6*7^17 + 6*7^18 + 6*7^19 + 6*7^20 + 6*7^21 + 6*7^22 + 6*7^23 + 6*7^24 + 6*7^25 + 6*7^26 + 6*7^27 + 6*7^28 + 6*7^29 + O(7^30)\n\njulia> g^2 == R(121)\ntrue","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(::PadicFieldElem)","category":"page"},{"location":"Nemo/padic/#exp-Tuple{PadicFieldElem}","page":"Padics","title":"exp","text":"exp(a::PadicFieldElem)\n\nReturn the p-adic exponential of a, assuming the p-adic exponential function converges at a.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/padic/","page":"Padics","title":"Padics","text":"log(::PadicFieldElem)","category":"page"},{"location":"Nemo/padic/#log-Tuple{PadicFieldElem}","page":"Padics","title":"log","text":"log(a::PadicFieldElem)\n\nReturn the p-adic logarithm of a, assuming the p-adic logarithm converges at a.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/padic/","page":"Padics","title":"Padics","text":"teichmuller(::PadicFieldElem)","category":"page"},{"location":"Nemo/padic/#teichmuller-Tuple{PadicFieldElem}","page":"Padics","title":"teichmuller","text":"teichmuller(a::PadicFieldElem)\n\nReturn the Teichmuller lift of the p-adic value a. We require the valuation of a to be non-negative. 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":"julia> R = padic_field(7, precision = 30)\nField of 7-adic numbers\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))\nO(7^30)\n\njulia> f = teichmuller(b)\n2*7^0 + 4*7^1 + 6*7^2 + O(7^3)","category":"page"},{"location":"DeveloperDocumentation/caching/","page":"Caching parent objects in OSCAR","title":"Caching parent objects in OSCAR","text":"CurrentModule = Oscar\nDocTestSetup = Oscar.doctestsetup()","category":"page"},{"location":"DeveloperDocumentation/caching/#Caching-parent-objects-in-OSCAR","page":"Caching parent objects in OSCAR","title":"Caching parent objects in OSCAR","text":"","category":"section"},{"location":"DeveloperDocumentation/caching/","page":"Caching parent objects in OSCAR","title":"Caching parent objects in OSCAR","text":"Many functions in OSCAR that construct parent objects (such as rings, modules, groups, etc.) have an optional keyword argument cached::Bool. If set to true then the object is put into a cache, and when the construction function is later called again with identical inputs, then the cached object is returned instead of creating a new object. In contrast when cached is set to false then each time a new object is returned.","category":"page"},{"location":"DeveloperDocumentation/caching/","page":"Caching parent objects in OSCAR","title":"Caching parent objects in OSCAR","text":"Example:","category":"page"},{"location":"DeveloperDocumentation/caching/","page":"Caching parent objects in OSCAR","title":"Caching parent objects in OSCAR","text":"julia> R1, = polynomial_ring(QQ, :x; cached = true);\n\njulia> R2, = polynomial_ring(QQ, :x; cached = true);\n\njulia> R1 === R2 # identical as both were created with `cached = true`\ntrue\n\njulia> R3, = polynomial_ring(QQ, :x; cached = false);\n\njulia> R1 === R3 # not identical as R3 was created with `cached = false`\nfalse\n\njulia> R4, = polynomial_ring(QQ, :y; cached = true);\n\njulia> R1 === R4 # not identical despite `cached = true` due to differing variable names\nfalse","category":"page"},{"location":"DeveloperDocumentation/caching/#Why-cache-parent-objects?","page":"Caching parent objects in OSCAR","title":"Why cache parent objects?","text":"","category":"section"},{"location":"DeveloperDocumentation/caching/","page":"Caching parent objects in OSCAR","title":"Caching parent objects in OSCAR","text":"The main reason for supporting caching of parent objects is user convenience: experience shows that most mathematicians (espescially those who are not also programmers; but it really affects all) are surprised if, say, QQ[:x] == Q[:x] produces false.","category":"page"},{"location":"DeveloperDocumentation/caching/","page":"Caching parent objects in OSCAR","title":"Caching parent objects in OSCAR","text":"For interactive use, it is often simply convenient: e.g. in the following example, we use map_coefficients to map polynomials over the integers to polynomials over a finite field, and the results can be added – this is only possible because the new polynomials have the same parent, thanks to caching.","category":"page"},{"location":"DeveloperDocumentation/caching/","page":"Caching parent objects in OSCAR","title":"Caching parent objects in OSCAR","text":"julia> Zx, x = ZZ[:x]\n(Univariate polynomial ring in x over ZZ, x)\n\njulia> F = GF(2);\n\njulia> map_coefficients(F, x^2) + map_coefficients(F, x)\nx^2 + x","category":"page"},{"location":"DeveloperDocumentation/caching/","page":"Caching parent objects in OSCAR","title":"Caching parent objects in OSCAR","text":"Caching parents also has downsides. E.g. all those cached objects take up memory which in some cases can add up to significant amounts.","category":"page"},{"location":"DeveloperDocumentation/caching/#Rules-for-implementations","page":"Caching parent objects in OSCAR","title":"Rules for implementations","text":"","category":"section"},{"location":"DeveloperDocumentation/caching/","page":"Caching parent objects in OSCAR","title":"Caching parent objects in OSCAR","text":"In the following we describe some rules related to caching for people implementing parent constructor functions","category":"page"},{"location":"DeveloperDocumentation/caching/","page":"Caching parent objects in OSCAR","title":"Caching parent objects in OSCAR","text":"Don't use caching in code inside OSCAR (caching is for end users!)\ni.e., code inside OSCAR by default should always construct rings with cached = false.\nIn other words: internal code should not rely on caching being active. Usually the need for using cached parents can be overcome by allowing callers to pass in a parent object as an additional function argument. One may still provide a default value for that as a user convenience, but these default parents then should be created with cached=false.\nRationale: this avoids clogging the system with cached objects the user never asked for. It also eliminates sources of bugs: a cached ring may have attributes assigned that modify its behavior in a way that it is completely unexpected in code dealing with \"newly created\" ring\nAll end-user facing constructors should have a cached::Bool keyword argument with a default value, regardless of whether caching is actually supported or not.\nif caching is supported, then cached should default to true\nif caching is not supported, then cached should default to false\nRationale: this allows us to comply pro-actively with the first rule: when creating a parent object, you always pass in cached = false. If not all constructors support this, we can't comply with it. Even if a constructor does not support caching right now: this might change in the future. So by allowing the cached argument in all cases, we can write future-proof code.\nCaches must not overflow\nthe simplest solution to achieve this is to use an AbstractAlgebra.CacheDictType instances (which really is an alias for WeakValueDict) together with get_cached! which automatically removes objects from caches if nothing outside the cache references it anymore\nAlternatively one may offer a manual way for users to \"flush\" caches, but beware the problems this can cause when code relies on parents being cached – yet another reason for rule 1.","category":"page"},{"location":"DeveloperDocumentation/caching/","page":"Caching parent objects in OSCAR","title":"Caching parent objects in OSCAR","text":"For convenience, Hecke also defines these \"standard rings\" for use in functions like cyclotomic_polynomial","category":"page"},{"location":"DeveloperDocumentation/caching/","page":"Caching parent objects in OSCAR","title":"Caching parent objects in OSCAR","text":"module Globals\n using Hecke\n const Qx, _ = polynomial_ring(FlintQQ, :x, cached = false)\n const Zx, _ = polynomial_ring(FlintZZ, :x, cached = false)\n const Zxy, _ = polynomial_ring(FlintZZ, [:x, :y], cached = false)\nend","category":"page"},{"location":"DeveloperDocumentation/caching/","page":"Caching parent objects in OSCAR","title":"Caching parent objects in OSCAR","text":"You can use these in your own code as well, or imitate this pattern if convenient.","category":"page"},{"location":"DeveloperDocumentation/caching/","page":"Caching parent objects in OSCAR","title":"Caching parent objects in OSCAR","text":"As always, if in doubt what to do, please ask.","category":"page"},{"location":"Groups/matgroup/","page":"Matrix groups","title":"Matrix groups","text":"CurrentModule = Oscar\nDocTestSetup = Oscar.doctestsetup()","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{RE}) where RE <: RingElem\ndegree(G::MatrixGroup)\ncentralizer(G::MatrixGroup{T}, x::MatrixGroupElem{T}) where T <: FinFieldElem\nmap_entries(f, G::MatrixGroup)","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-Union{Tuple{MatrixGroup{RE, T} where T<:MatElem{RE}}, Tuple{RE}} where RE<:RingElem","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/#map_entries-Tuple{Any, MatrixGroup}","page":"Matrix groups","title":"map_entries","text":"map_entries(f, G::MatrixGroup)\n\nReturn the matrix group obtained by applying f element-wise to each generator of G.\n\nf can be a ring or a field, a suitable map, or a Julia function.\n\nExamples\n\njulia> mat = matrix(ZZ, 2, 2, [1, 1, 0, 1]);\n\njulia> G = matrix_group(mat);\n\njulia> G2 = map_entries(x -> -x, G)\nMatrix group of degree 2\n over integer ring\n\njulia> is_finite(G2)\nfalse\n\njulia> order(map_entries(GF(3), G))\n3\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":"number_of_rows(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","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","page":"Matrix groups","title":"Utilities for matrices","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::AbstractVector{T}) where {T <: NCRingElement}\nlower_triangular_matrix(L::AbstractVector{T}) where {T <: NCRingElement}\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-Union{Tuple{AbstractVector{T}}, Tuple{T}} where T<:NCRingElement","page":"Matrix groups","title":"upper_triangular_matrix","text":"upper_triangular_matrix(L::AbstractVector{T}) where {T <: NCRingElement}\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":"Groups/matgroup/#lower_triangular_matrix-Union{Tuple{AbstractVector{T}}, Tuple{T}} where T<:NCRingElement","page":"Matrix groups","title":"lower_triangular_matrix","text":"lower_triangular_matrix(L::AbstractVector{T}) where {T <: NCRingElement}\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":"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 R must be either a finite field or a residue ring or ZZ.\n\nExamples\n\njulia> F = GF(7)\nPrime field of characteristic 7\n\njulia> H = general_linear_group(2, F)\nGL(2,7)\n\njulia> gens(H)\n2-element Vector{MatrixGroupElem{FqFieldElem, FqMatrix}}:\n [3 0; 0 1]\n [6 1; 6 0]\n\njulia> order(general_linear_group(2, residue_ring(ZZ, 6)[1]))\n288\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 R must be either a finite field or a residue ring or ZZ.\n\nExamples\n\njulia> F = GF(7)\nPrime field of characteristic 7\n\njulia> H = special_linear_group(2, F)\nSL(2,7)\n\njulia> gens(H)\n2-element Vector{MatrixGroupElem{FqFieldElem, FqMatrix}}:\n [3 0; 0 5]\n [6 1; 6 0]\n\njulia> order(special_linear_group(2, residue_ring(ZZ, 6)[1]))\n144\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 R must be either a finite field or a residue ring of prime power order.\n\nExamples\n\njulia> F = GF(7)\nPrime field of characteristic 7\n\njulia> H = symplectic_group(2, F)\nSp(2,7)\n\njulia> gens(H)\n2-element Vector{MatrixGroupElem{FqFieldElem, FqMatrix}}:\n [3 0; 0 5]\n [6 1; 6 0]\n\njulia> order(symplectic_group(2, residue_ring(ZZ, 4)[1]))\n48\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 R must be either a finite field or a residue ring of odd prime power order.\n\nExamples\n\njulia> F = GF(7)\nPrime field of characteristic 7\n\njulia> H = orthogonal_group(1, 2, F)\nGO+(2,7)\n\njulia> gens(H)\n2-element Vector{MatrixGroupElem{FqFieldElem, FqMatrix}}:\n [3 0; 0 5]\n [0 1; 1 0]\n\njulia> order(orthogonal_group(-1, 2, residue_ring(ZZ, 9)[1]))\n24\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 R must be either a finite field or a residue ring of odd prime power order.\n\nExamples\n\njulia> F = GF(7)\nPrime field of characteristic 7\n\njulia> H = special_orthogonal_group(1, 2, F)\nSO+(2,7)\n\njulia> gens(H)\n3-element Vector{MatrixGroupElem{FqFieldElem, FqMatrix}}:\n [3 0; 0 5]\n [5 0; 0 3]\n [1 0; 0 1]\n\njulia> order(special_orthogonal_group(-1, 2, residue_ring(ZZ, 9)[1]))\n12\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 R must be either a finite field or a residue ring of odd prime power order.\n\nExamples\n\njulia> F = GF(7)\nPrime field of characteristic 7\n\njulia> H = omega_group(1, 2, F)\nOmega+(2,7)\n\njulia> gens(H)\n1-element Vector{MatrixGroupElem{FqFieldElem, FqMatrix}}:\n [2 0; 0 4]\n\njulia> order(omega_group(0, 3, residue_ring(ZZ, 9)[1]))\n324\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{FqFieldElem, FqMatrix}}:\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{FqFieldElem, FqMatrix}}:\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":"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":"TropicalGeometry/semiring/#Tropical-semirings,-matrices,-and-polynomials","page":"Tropical semirings, matrices, and polynomials","title":"Tropical semirings, matrices, and polynomials","text":"","category":"section"},{"location":"TropicalGeometry/semiring/#Introduction","page":"Tropical semirings, matrices, and polynomials","title":"Introduction","text":"","category":"section"},{"location":"TropicalGeometry/semiring/","page":"Tropical semirings, matrices, and polynomials","title":"Tropical semirings, matrices, and polynomials","text":"In OSCAR, the tropical semiring is either","category":"page"},{"location":"TropicalGeometry/semiring/","page":"Tropical semirings, matrices, and polynomials","title":"Tropical semirings, matrices, and polynomials","text":"the min-plus semiring (mathbbQcup+inftyoplusodot) with aoplus b=min(ab) and aodot b=a+b,\nthe max-plus semiring (mathbbQcup-inftyoplusodot) with aoplus b=max(ab) and aodot b=a+b.","category":"page"},{"location":"TropicalGeometry/semiring/","page":"Tropical semirings, matrices, and polynomials","title":"Tropical semirings, matrices, and polynomials","text":"Whereas tropical semirings in [MS15] and [Jos21] are extensions of the real numbers, tropical semirings in OSCAR are an extension of the rational numbers to avoid precision issues.","category":"page"},{"location":"TropicalGeometry/semiring/#Constructor","page":"Tropical semirings, matrices, and polynomials","title":"Constructor","text":"","category":"section"},{"location":"TropicalGeometry/semiring/","page":"Tropical semirings, matrices, and polynomials","title":"Tropical semirings, matrices, and polynomials","text":"Objects of type TropicalSemiring, as well as matrices and polynomials thereover, can be constructed as follows:","category":"page"},{"location":"TropicalGeometry/semiring/","page":"Tropical semirings, matrices, and polynomials","title":"Tropical semirings, matrices, and polynomials","text":"tropical_semiring()","category":"page"},{"location":"TropicalGeometry/semiring/#tropical_semiring-Tuple{}","page":"Tropical semirings, matrices, and polynomials","title":"tropical_semiring","text":"tropical_semiring(M::Union{typeof(min),typeof(max)}=min)\n\nReturn the min-plus (default) or max-plus semiring.\n\nwarning: Warning\n+, *, /, and ^ are used for tropical addition, tropical multipliciation, tropical division, and tropical exponentiation, respectively.\nThere is no additive inverse or subtraction in the tropical semiring. Negating a tropical number or subtracting two tropical numbers will raise an error.\nZeroes of tropical semirings are printed as infty or -infty instead of their proper unicode characters. To enabled unicode in the current and future sessions, run allow_unicode(true).\n\nExamples (basic arithmetic)\n\njulia> T = tropical_semiring() # = tropical_semiring(min)\nMin tropical semiring\n\njulia> T = tropical_semiring(max)\nMax tropical semiring\n\njulia> 0*T(3) + 1*T(1)^2 + zero(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 = tropical_semiring()\nMin tropical semiring\n\njulia> Tx,(x1,x2) = polynomial_ring(T,2)\n(Multivariate polynomial ring in 2 variables over min tropical semiring, AbstractAlgebra.Generic.MPoly{TropicalSemiringElem{typeof(min)}}[x1, x2])\n\njulia> f = x1 + -1*x2 + 0\nx1 + (-1)*x2 + (0)\n\njulia> evaluate(f,T.([-1//2,1//2])) # warning: omitting T() gives an error\n(-1//2)\n\nExamples (matrices)\n\njulia> T = tropical_semiring()\nMin tropical semiring\n\njulia> A = identity_matrix(T, 2) # = tropical identity matrix\n[ (0) infty]\n[infty (0)]\n\njulia> 2*A\n[ (2) infty]\n[infty (2)]\n\njulia> A*A\n[ (0) infty]\n[infty (0)]\n\njulia> det(A)\n(0)\n\njulia> minors(A,1)\n4-element Vector{TropicalSemiringElem{typeof(min)}}:\n (0)\n infty\n infty\n (0)\n\n\n\n\n\n","category":"method"},{"location":"TropicalGeometry/semiring/#Properties","page":"Tropical semirings, matrices, and polynomials","title":"Properties","text":"","category":"section"},{"location":"TropicalGeometry/semiring/","page":"Tropical semirings, matrices, and polynomials","title":"Tropical semirings, matrices, and polynomials","text":"Objects of type TropicalSemiring have the following properties:","category":"page"},{"location":"TropicalGeometry/semiring/","page":"Tropical semirings, matrices, and polynomials","title":"Tropical semirings, matrices, and polynomials","text":"convention(T::TropicalSemiring{typeof(min)})","category":"page"},{"location":"TropicalGeometry/semiring/#convention-Tuple{TropicalSemiring{typeof(min)}}","page":"Tropical semirings, matrices, and polynomials","title":"convention","text":"convention(T::TropicalSemiring)\n\nReturn min if T is the min tropical semiring, return max if T is the max tropical semiring. Works similarly for tropical numbers, tropical vectors and matrices, and tropical polynomials.\n\nExamples\n\njulia> T = tropical_semiring(min)\nMin tropical semiring\n\njulia> convention(T)\nmin (generic function with 27 methods)\n\njulia> T = tropical_semiring(max)\nMax tropical semiring\n\njulia> convention(T)\nmax (generic function with 27 methods)\n\n\n\n\n\n","category":"method"},{"location":"TropicalGeometry/semiring/#Related-functions","page":"Tropical semirings, matrices, and polynomials","title":"Related functions","text":"","category":"section"},{"location":"TropicalGeometry/semiring/","page":"Tropical semirings, matrices, and polynomials","title":"Tropical semirings, matrices, and polynomials","text":"Other functions related to TropicalSemiring, matrices, and polynomials thereover include:","category":"page"},{"location":"TropicalGeometry/semiring/","page":"Tropical semirings, matrices, and polynomials","title":"Tropical semirings, matrices, and polynomials","text":"det(A::AbstractAlgebra.Generic.MatSpaceElem{<: Oscar.TropicalSemiringElem})\ntropical_polynomial(f::MPolyRingElem, nu::TropicalSemiringMap)","category":"page"},{"location":"TropicalGeometry/semiring/#det-Tuple{AbstractAlgebra.Generic.MatSpaceElem{<:TropicalSemiringElem}}","page":"Tropical semirings, matrices, and polynomials","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> A = R[x 1; 1 x^2];\n\njulia> d = det(A)\nx^3 - 1\n\n\n\n\n\ndet(A::MatrixElem{<: TropicalSemiringElem})\n\nReturn the tropical determinant of A. That is, this function evaluates the tropicalization of the ordinary determinant considered as a multivariate polynomial at A.\n\nThat computation is equivalent to solving a linear assignment problem from combinatorial optimization. The implementation employs the Hungarian method, which is polynomial time. See Chapter 3 in [Jos21].\n\nnote: Note\nThis function effectively overwrites the det command for tropical matrices. This means that functions like minors will use the tropical determinant when used on a tropical matrix.\n\nExamples\n\njulia> A = matrix(tropical_semiring(),[1 2; 3 4])\n[(1) (2)]\n[(3) (4)]\n\njulia> det(A)\n(5)\n\n\n\n\n\n","category":"method"},{"location":"TropicalGeometry/semiring/#tropical_polynomial-Tuple{MPolyRingElem, TropicalSemiringMap}","page":"Tropical semirings, matrices, and polynomials","title":"tropical_polynomial","text":"tropical_polynomial(f::Union{<:MPolyRingElem,<:PolyRingElem},nu::TropicalSemiringMap)\n\nGiven a polynomial f and a tropical semiring map nu, return 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> nu = tropical_semiring_map(QQ,7)\nMap into Min tropical semiring encoding the 7-adic valuation on Rational field\n\njulia> f = 7*x+y+49\n7*x + y + 49\n\njulia> tropical_polynomial(f,nu)\n(1)*x + y + (2)\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/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/manual/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/manual/elliptic_curves/finite_fields/#Random-points","page":"Elliptic curves over finite fields","title":"Random points","text":"","category":"section"},{"location":"Hecke/manual/elliptic_curves/finite_fields/","page":"Elliptic curves over finite fields","title":"Elliptic curves over finite fields","text":" rand(E::EllipticCurve{<: FinFieldElem})","category":"page"},{"location":"Hecke/manual/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/manual/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/manual/elliptic_curves/finite_fields/#Cardinality-and-orders","page":"Elliptic curves over finite fields","title":"Cardinality and orders","text":"","category":"section"},{"location":"Hecke/manual/elliptic_curves/finite_fields/","page":"Elliptic curves over finite fields","title":"Elliptic curves over finite fields","text":"order(::EllipticCurve{<:FinFieldElem})\norder(::EllipticCurvePoint{<:FinFieldElem})","category":"page"},{"location":"Hecke/manual/elliptic_curves/finite_fields/#order-Tuple{EllipticCurve{<:FinFieldElem}}","page":"Elliptic curves over finite fields","title":"order","text":"order(::Type{T} = BigInt, G::Group) where T\n\nReturn the order of G as an instance of T. If G is of infinite order, an InfiniteOrderError exception will be thrown. Use is_finite(G) to avoid this kind of exception. If the order does not fit into type T, an InexactError exception will be thrown.\n\n\n\n\n\norder(::Type{T} = BigInt, g::GroupElem) where T\n\nReturn the order of g as an instance of T. If g is of infinite order, an InfiniteOrderError exception will be thrown. Use is_finite_order(G) to avoid this kind of exception. If the order does not fit into type T, an InexactError exception will be thrown.\n\n\n\n\n\norder(E::EllipticCurve{<: 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\norder(::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(::Type{T}, W::WeylGroup) where {T} -> T\n\nReturns the order of W.\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/elliptic_curves/finite_fields/#order-Tuple{EllipticCurvePoint{<:FinFieldElem}}","page":"Elliptic curves over finite fields","title":"order","text":"order(::Type{T} = BigInt, G::Group) where T\n\nReturn the order of G as an instance of T. If G is of infinite order, an InfiniteOrderError exception will be thrown. Use is_finite(G) to avoid this kind of exception. If the order does not fit into type T, an InexactError exception will be thrown.\n\n\n\n\n\norder(::Type{T} = BigInt, g::GroupElem) where T\n\nReturn the order of g as an instance of T. If g is of infinite order, an InfiniteOrderError exception will be thrown. Use is_finite_order(G) to avoid this kind of exception. If the order does not fit into type T, an InexactError exception will be thrown.\n\n\n\n\n\norder(P::EllipticCurvePoint, [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\norder(::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(::Type{T}, W::WeylGroup) where {T} -> T\n\nReturns the order of W.\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/elliptic_curves/finite_fields/#Frobenius","page":"Elliptic curves over finite fields","title":"Frobenius","text":"","category":"section"},{"location":"Hecke/manual/elliptic_curves/finite_fields/","page":"Elliptic curves over finite fields","title":"Elliptic curves over finite fields","text":"trace_of_frobenius(::EllipticCurve{<:FinFieldElem})\ntrace_of_frobenius(::EllipticCurve{<:FinFieldElem}, ::Int)","category":"page"},{"location":"Hecke/manual/elliptic_curves/finite_fields/#trace_of_frobenius-Tuple{EllipticCurve{<:FinFieldElem}}","page":"Elliptic curves over finite fields","title":"trace_of_frobenius","text":"trace_of_frobenius(E::EllipticCurve{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/manual/elliptic_curves/finite_fields/#trace_of_frobenius-Tuple{EllipticCurve{<:FinFieldElem}, Int64}","page":"Elliptic curves over finite fields","title":"trace_of_frobenius","text":"trace_of_frobenius(E::EllipticCurve{<: 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/manual/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/manual/elliptic_curves/finite_fields/","page":"Elliptic curves over finite fields","title":"Elliptic curves over finite fields","text":"gens(::EllipticCurve{T}) where {T <: FinFieldElem}\nabelian_group(::EllipticCurve{<:FinFieldElem})","category":"page"},{"location":"Hecke/manual/elliptic_curves/finite_fields/#gens-Union{Tuple{EllipticCurve{T}}, Tuple{T}} where T<:FinFieldElem","page":"Elliptic curves over finite fields","title":"gens","text":"gens(E::EllipticCurve{<:FinFieldElem}) -> Vector{EllipticCurvePoint}\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{EllipticCurvePoint{FqFieldElem}}:\n Point (16*o + 42 : 88*o + 97 : 1) of Elliptic curve with equation\ny^2 = x^3 + x + 2\n Point (88*o + 23 : 94*o + 22 : 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{EllipticCurvePoint{FqFieldElem}}:\n Point (85 : 58 : 1) of Elliptic curve with equation\ny^2 = x^3 + x + 2\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/elliptic_curves/finite_fields/#abelian_group-Tuple{EllipticCurve{<:FinFieldElem}}","page":"Elliptic curves over finite fields","title":"abelian_group","text":"abelian_group(E::EllipticCurve{<:FinFieldElem}) -> FinGenAbGroup, 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\nZ/2 x Z/5200\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/elliptic_curves/finite_fields/#Discrete-logarithm","page":"Elliptic curves over finite fields","title":"Discrete logarithm","text":"","category":"section"},{"location":"Hecke/manual/elliptic_curves/finite_fields/","page":"Elliptic curves over finite fields","title":"Elliptic curves over finite fields","text":"disc_log(::EllipticCurvePoint, ::EllipticCurvePoint)","category":"page"},{"location":"Hecke/manual/elliptic_curves/finite_fields/#disc_log-Tuple{EllipticCurvePoint, EllipticCurvePoint}","page":"Elliptic curves over finite fields","title":"disc_log","text":"disc_log(P::EllipticCurvePoint, Q::EllipticCurvePoint, [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":"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":"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":"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 ZZ.","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 = ZZ","category":"page"},{"location":"Nemo/integer/","page":"Integers","title":"Integers","text":"so that integers can be constructed using ZZ instead of ZZ. 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 non-negative 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":"is_divisible_by(::ZZRingElem, ::Int)\nis_divisible_by(::ZZRingElem, ::ZZRingElem)","category":"page"},{"location":"Nemo/integer/#is_divisible_by-Tuple{ZZRingElem, Int64}","page":"Integers","title":"is_divisible_by","text":"is_divisible_by(x::ZZRingElem, y::ZZRingElem)\n\nReturn true if x is divisible by y, otherwise return false.\n\n\n\n\n\n","category":"method"},{"location":"Nemo/integer/#is_divisible_by-Tuple{ZZRingElem, ZZRingElem}","page":"Integers","title":"is_divisible_by","text":"is_divisible_by(x::ZZRingElem, y::ZZRingElem)\n\nReturn true if x is divisible by y, otherwise return false.\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::T) where T <: RingElement -> Fac{T}\n\nReturn a factorization of a into irreducible elements, as a Fac{T}. The irreducible elements in the factorization are pairwise coprime.\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::RingElement, n::Integer)\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\nExamples\n\njulia> R, x = ZZ[:x];\n\njulia> rising_factorial(x, 1)\nx\n\njulia> rising_factorial(x, 2)\nx^2 + x\n\njulia> rising_factorial(4, 2)\n20\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\nReturn 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":"number_of_digits(::ZZRingElem, ::Integer)","category":"page"},{"location":"Nemo/integer/#number_of_digits-Tuple{ZZRingElem, Integer}","page":"Integers","title":"number_of_digits","text":"number_of_digits(x::ZZRingElem, b::Integer)\n\nReturn the number of digits of x in the base b (default is b = 10).\n\nExamples\n\njulia> number_of_digits(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/tutorials/#Tutorials","page":"Tutorials","title":"Tutorials","text":"","category":"section"},{"location":"Groups/recog/","page":"Group recognition","title":"Group recognition","text":"CurrentModule = Oscar\nDocTestSetup = Oscar.doctestsetup()","category":"page"},{"location":"Groups/recog/#Group-recognition","page":"Group recognition","title":"Group recognition","text":"","category":"section"},{"location":"Groups/recog/","page":"Group recognition","title":"Group recognition","text":"The idea of constructive group recognition is to compute a recognition tree for a given (permutation or matrix) group, which describes the structure of this group in a recursive way: Each non-leaf node of the tree describes an epimorphism such that the kernel and the image belong to the two subtrees of the node. Each leaf node describes a group for which efficient methods are available that allow one to decide whether a group element is an element of this group, and if yes to write the element as a word in terms of suitable generators.","category":"page"},{"location":"Groups/recog/","page":"Group recognition","title":"Group recognition","text":"The recognition tree has enough information to decide whether a group element is an element of the given group, and if yes to write the element as a word in terms of suitable generators of the given group.","category":"page"},{"location":"Groups/recog/","page":"Group recognition","title":"Group recognition","text":"recognize\nis_ready\nnice_gens\nstraight_line_program(tree::GroupRecognitionTree, g::GAPGroupElem)","category":"page"},{"location":"Groups/recog/#recognize","page":"Group recognition","title":"recognize","text":"recognize(G::Union{PermGroup, MatrixGroup})\n\nReturn a GroupRecognitionTree object that describes the structure of G in a recursive way. If the recognition was successful (see is_ready) then the result provides a membership test that is usually more efficient than the membership test without the recognition information.\n\nExamples\n\njulia> recognize(symmetric_group(5))\nRecognition tree: MovesOnlySmallPoints Size=120\n\njulia> g = general_linear_group(4, 9);\n\njulia> s = sub(g, [rand(g), rand(g)])[1];\n\njulia> rec = recognize(s); is_ready(rec)\ntrue\n\njulia> rand(s) in rec\ntrue\n\n\n\n\n\n","category":"function"},{"location":"Groups/recog/#is_ready","page":"Group recognition","title":"is_ready","text":"is_ready(tree::GroupRecognitionTree)\n\nReturn true if the recognition procedure for the group of tree was successful, and false otherwise.\n\nExamples\n\njulia> rec = recognize(GL(4, 2)); is_ready(rec)\ntrue\n\n\n\n\n\n","category":"function"},{"location":"Groups/recog/#nice_gens","page":"Group recognition","title":"nice_gens","text":"nice_gens(tree::GroupRecognitionTree)\n\nReturn the vector of generators of the group of tree w.r.t. which the straight line programs for group elements computed by straight_line_program are written.\n\nExamples\n\njulia> rec = recognize(GL(4, 2)); is_ready(rec)\ntrue\n\njulia> x = rand(group(rec));\n\njulia> slp = straight_line_program(rec, x);\n\njulia> evaluate(slp, nice_gens(rec)) == x\ntrue\n\n\n\n\n\n","category":"function"},{"location":"Groups/recog/#straight_line_program-Tuple{Oscar.GroupRecognitionTree, GAPGroupElem}","page":"Group recognition","title":"straight_line_program","text":"straight_line_program(tree::GroupRecognitionTree, g::GAPGroupElem)\n\nReturn a straight line program for the element g of the group of tree. The inputs of this program correspond to nice_gens(tree), see nice_gens for an example.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/ToricSchemes/","page":"Toric Schemes","title":"Toric Schemes","text":"CurrentModule = Oscar","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/ToricSchemes/#Toric-Schemes","page":"Toric Schemes","title":"Toric Schemes","text":"","category":"section"},{"location":"AlgebraicGeometry/ToricVarieties/ToricSchemes/","page":"Toric Schemes","title":"Toric Schemes","text":"Toric varieties are special instances of schemes. As such, all scheme functionality is available to toric varieties.","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/ToricSchemes/#Content","page":"Toric Schemes","title":"Content","text":"","category":"section"},{"location":"AlgebraicGeometry/ToricVarieties/ToricSchemes/","page":"Toric Schemes","title":"Toric Schemes","text":"We aim for a seamless transition among toric varieties and covered schemes.","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/ToricSchemes/","page":"Toric Schemes","title":"Toric Schemes","text":"One advantage is that we can hope for improved performance of scheme functionality by using toric backends when applicable. In addition, one can apply powerful scheme computations to toric settings, thus extending the available toolkit significantly.","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/ToricSchemes/","page":"Toric Schemes","title":"Toric Schemes","text":"The user can extract the scheme corresponding to a toric variety as follows:","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/ToricSchemes/","page":"Toric Schemes","title":"Toric Schemes","text":"underlying_scheme(X::AffineNormalToricVariety)\nunderlying_scheme(X::NormalToricVariety)","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/ToricSchemes/#underlying_scheme-Tuple{AffineNormalToricVariety}","page":"Toric Schemes","title":"underlying_scheme","text":"underlying_scheme(X::AffineNormalToricVariety)\n\nFor an affine toric 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> C = positive_hull([1 0; 0 1])\nPolyhedral cone in ambient dimension 2\n\njulia> antv = affine_normal_toric_variety(C)\nNormal toric variety\n\njulia> Oscar.underlying_scheme(antv)\nSpectrum\n of quotient\n of multivariate polynomial ring in 2 variables x1, x2\n over rational field\n by ideal (0)\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/ToricSchemes/#underlying_scheme-Tuple{NormalToricVariety}","page":"Toric Schemes","title":"underlying_scheme","text":"underlying_scheme(X::NormalToricVariety)\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 toric variety\n\njulia> Oscar.underlying_scheme(P2)\nScheme\n over rational field\nwith default covering\n described by patches\n 1: normal toric variety\n 2: normal toric variety\n 3: normal toric variety\n in the coordinate(s)\n 1: [x_1_1, x_2_1]\n 2: [x_1_2, x_2_2]\n 3: [x_1_3, x_2_3]\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/ToricSchemes/","page":"Toric Schemes","title":"Toric Schemes","text":"We also provide functionality to forget the toric structure completely. In this sense, the following methods return the underlying covered scheme, but this scheme does not remember being a toric variety.","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/ToricSchemes/","page":"Toric Schemes","title":"Toric Schemes","text":"forget_toric_structure(X::AffineNormalToricVariety)\nforget_toric_structure(X::NormalToricVariety)","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/ToricSchemes/#forget_toric_structure-Tuple{AffineNormalToricVariety}","page":"Toric Schemes","title":"forget_toric_structure","text":"forget_toric_structure(X::AffineNormalToricVariety)\n\nReturn a pair (Y, iso) where Y is a scheme without toric structure, together with an isomorphism iso : Y → X.\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 toric variety\n\njulia> forget_toric_structure(antv)\n(scheme(0), Hom: scheme(0) -> normal toric variety)\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/ToricSchemes/#forget_toric_structure-Tuple{NormalToricVariety}","page":"Toric Schemes","title":"forget_toric_structure","text":"forget_toric_structure(X::NormalToricVariety)\n\nReturn a pair (Y, iso) where Y is a scheme without toric structure, together with an isomorphism iso : Y → X.\n\nExamples\n\njulia> P2 = projective_space(NormalToricVariety, 2)\nNormal toric variety\n\njulia> forget_toric_structure(P2)\n(Scheme over QQ covered with 3 patches, Hom: scheme over QQ covered with 3 patches -> normal toric variety)\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/ToricVarieties/ToricSchemes/#Contact","page":"Toric Schemes","title":"Contact","text":"","category":"section"},{"location":"AlgebraicGeometry/ToricVarieties/ToricSchemes/","page":"Toric Schemes","title":"Toric Schemes","text":"Please direct questions about this part of OSCAR to the following people:","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/ToricSchemes/","page":"Toric Schemes","title":"Toric Schemes","text":"Martin Bies,\nMatthias Zach.","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/ToricSchemes/","page":"Toric Schemes","title":"Toric Schemes","text":"You can ask questions in the OSCAR Slack.","category":"page"},{"location":"AlgebraicGeometry/ToricVarieties/ToricSchemes/","page":"Toric Schemes","title":"Toric Schemes","text":"Alternatively, you can raise an issue on github.","category":"page"},{"location":"Hecke/manual/number_fields/complex_embeddings/","page":"Complex embedding","title":"Complex embedding","text":"CurrentModule = Hecke\nDocTestSetup = quote\n using Hecke\n end","category":"page"},{"location":"Hecke/manual/number_fields/complex_embeddings/#Complex-embedding","page":"Complex embedding","title":"Complex embedding","text":"","category":"section"},{"location":"Hecke/manual/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/manual/number_fields/complex_embeddings/#Construction-of-complex-embeddings","page":"Complex embedding","title":"Construction of complex embeddings","text":"","category":"section"},{"location":"Hecke/manual/number_fields/complex_embeddings/","page":"Complex embedding","title":"Complex embedding","text":"complex_embeddings(::NumField)\nreal_embeddings(::NumField)","category":"page"},{"location":"Hecke/manual/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{AbsSimpleNumFieldEmbedding}:\n Complex embedding corresponding to 0.00 + 1.73 * i of imaginary quadratic field\n Complex embedding corresponding to 0.00 - 1.73 * i of imaginary quadratic field\n\njulia> complex_embeddings(K, conjugates = false)\n1-element Vector{AbsSimpleNumFieldEmbedding}:\n Complex embedding corresponding to 0.00 + 1.73 * i of imaginary quadratic field\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/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{AbsSimpleNumFieldEmbedding}:\n Complex embedding corresponding to -1.73 of real quadratic field\n Complex embedding corresponding to 1.73 of real quadratic field\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/number_fields/complex_embeddings/#Properties","page":"Complex embedding","title":"Properties","text":"","category":"section"},{"location":"Hecke/manual/number_fields/complex_embeddings/","page":"Complex embedding","title":"Complex embedding","text":"number_field(::NumFieldEmb)\nis_real(::NumFieldEmb)\nis_imaginary(::NumFieldEmb)","category":"page"},{"location":"Hecke/manual/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/manual/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/manual/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/manual/number_fields/complex_embeddings/#Conjugated-embedding","page":"Complex embedding","title":"Conjugated embedding","text":"","category":"section"},{"location":"Hecke/manual/number_fields/complex_embeddings/","page":"Complex embedding","title":"Complex embedding","text":"conj(::NumFieldEmb)","category":"page"},{"location":"Hecke/manual/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/manual/number_fields/complex_embeddings/#Evaluating-elements-at-complex-embeddings","page":"Complex embedding","title":"Evaluating elements at complex embeddings","text":"","category":"section"},{"location":"Hecke/manual/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/manual/number_fields/complex_embeddings/","page":"Complex embedding","title":"Complex embedding","text":" (f::NumFieldEmb)(x::NumFieldElem, prec::Int = 32) -> AcbFieldElem","category":"page"},{"location":"Hecke/manual/number_fields/complex_embeddings/","page":"Complex embedding","title":"Complex embedding","text":"Note that the return type will be a complex ball of type AcbFieldElem. 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/manual/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/manual/number_fields/complex_embeddings/","page":"Complex embedding","title":"Complex embedding","text":"evaluation_function(e::NumFieldEmb, prec::Int)","category":"page"},{"location":"Hecke/manual/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/manual/number_fields/complex_embeddings/#Logarithmic-embedding","page":"Complex embedding","title":"Logarithmic embedding","text":"","category":"section"},{"location":"Hecke/manual/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/manual/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)\nComplex embedding corresponding to 1.41\n of real quadratic field defined by x^2 - 2\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/manual/number_fields/complex_embeddings/#Restriction","page":"Complex embedding","title":"Restriction","text":"","category":"section"},{"location":"Hecke/manual/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/manual/number_fields/complex_embeddings/","page":"Complex embedding","title":"Complex embedding","text":"restrict(::NumFieldEmb, ::NumField)\nrestrict(::NumFieldEmb, ::NumFieldHom)","category":"page"},{"location":"Hecke/manual/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 real quadratic field defined by x^2 - 3\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/number_fields/complex_embeddings/#restrict-Tuple{Hecke.NumFieldEmb, NumFieldHom}","page":"Complex embedding","title":"restrict","text":"restrict(f::NumFieldEmb, g::NumFieldHom)\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 = cyclotomic_field(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/manual/number_fields/complex_embeddings/#Extension","page":"Complex embedding","title":"Extension","text":"","category":"section"},{"location":"Hecke/manual/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/manual/number_fields/complex_embeddings/","page":"Complex embedding","title":"Complex embedding","text":"extend(::NumFieldEmb, ::NumFieldHom)","category":"page"},{"location":"Hecke/manual/number_fields/complex_embeddings/#extend-Tuple{Hecke.NumFieldEmb, NumFieldHom}","page":"Complex embedding","title":"extend","text":"extend(e::NumFieldEmb, f::NumFieldHom)\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 = cyclotomic_field(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{AbsSimpleNumFieldEmbedding}:\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/manual/number_fields/complex_embeddings/#positivity_and_signs2","page":"Complex embedding","title":"Positivity & Signs","text":"","category":"section"},{"location":"Hecke/manual/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/manual/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/manual/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{AbsSimpleNumFieldEmbedding, 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/manual/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/manual/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/manual/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/manual/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/manual/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/manual/number_fields/complex_embeddings/#Example","page":"Complex embedding","title":"Example","text":"","category":"section"},{"location":"Hecke/manual/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/manual/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{AbsNonSimpleNumFieldEmbedding}:\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 imaginary quadratic field defined by x^2 + 1\n\njulia> restrict(emb[3], i)\nComplex embedding corresponding to -1.00 * i\n of imaginary quadratic field defined by x^2 + 1","category":"page"},{"location":"Hecke/start/#Getting-started","page":"Getting started","title":"Getting started","text":"","category":"section"},{"location":"Hecke/start/","page":"Getting started","title":"Getting started","text":"To use Hecke, a julia version of 1.0 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/start/","page":"Getting started","title":"Getting started","text":"julia> using Pkg\n\njulia> Pkg.add(\"Hecke\")","category":"page"},{"location":"Hecke/start/","page":"Getting started","title":"Getting started","text":"Here is a quick example of using Hecke to define a number field and compute its class group::","category":"page"},{"location":"Hecke/start/","page":"Getting started","title":"Getting started","text":"using Hecke\nQx, x = QQ[\"x\"];\nf = x^2 - 2*3*5*7;\nK, a = number_field(f, \"a\");\nOK = maximal_order(K);\nC, mC = class_group(OK);\nC","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)\nbase_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 of type 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 of type 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":"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":"Hecke/manual/quad_forms/genusherm/#Genera-for-hermitian-lattices","page":"Genera for hermitian lattices","title":"Genera for hermitian lattices","text":"","category":"section"},{"location":"Hecke/manual/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/manual/quad_forms/genusherm/#Local-genus-symbols","page":"Genera for hermitian lattices","title":"Local genus symbols","text":"","category":"section"},{"location":"Hecke/manual/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/manual/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/manual/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/manual/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/manual/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/manual/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/manual/quad_forms/genusherm/","page":"Genera for hermitian lattices","title":"Genera for hermitian lattices","text":"if mathfrak p is bad,","category":"page"},{"location":"Hecke/manual/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/manual/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/manual/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/manual/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/manual/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/manual/quad_forms/genusherm/#Creation-of-local-genus-symbols","page":"Genera for hermitian lattices","title":"Creation of local genus symbols","text":"","category":"section"},{"location":"Hecke/manual/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/manual/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/manual/quad_forms/genusherm/","page":"Genera for hermitian lattices","title":"Genera for hermitian lattices","text":" genus(HermLat, E::NumField, p::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}, data::Vector; type::Symbol = :det,\n check::Bool = false)\n -> HermLocalGenus","category":"page"},{"location":"Hecke/manual/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/manual/quad_forms/genusherm/","page":"Genera for hermitian lattices","title":"Genera for hermitian lattices","text":" genus(L::HermLat, p::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}) -> HermLocalGenus","category":"page"},{"location":"Hecke/manual/quad_forms/genusherm/#Examples","page":"Genera for hermitian lattices","title":"Examples","text":"","category":"section"},{"location":"Hecke/manual/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/manual/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.RelSimpleNumFieldElem{AbsSimpleNumFieldElem}}[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/manual/quad_forms/genusherm/","page":"Genera for hermitian lattices","title":"Genera for hermitian lattices","text":"","category":"page"},{"location":"Hecke/manual/quad_forms/genusherm/#Attributes","page":"Genera for hermitian lattices","title":"Attributes","text":"","category":"section"},{"location":"Hecke/manual/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/manual/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/manual/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/manual/quad_forms/genusherm/#prime-Tuple{HermLocalGenus}","page":"Genera for hermitian lattices","title":"prime","text":"prime(g::HermLocalGenus) -> AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}\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/manual/quad_forms/genusherm/#Examples-2","page":"Genera for hermitian lattices","title":"Examples","text":"","category":"section"},{"location":"Hecke/manual/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/manual/quad_forms/genusherm/","page":"Genera for hermitian lattices","title":"Genera for hermitian lattices","text":"","category":"page"},{"location":"Hecke/manual/quad_forms/genusherm/#Invariants","page":"Genera for hermitian lattices","title":"Invariants","text":"","category":"section"},{"location":"Hecke/manual/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)\nnorm(::HermLocalGenus)\nnorms(::HermLocalGenus)","category":"page"},{"location":"Hecke/manual/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/manual/quad_forms/genusherm/#scale-Tuple{HermLocalGenus}","page":"Genera for hermitian lattices","title":"scale","text":"scale(g::HermLocalGenus) -> AbsSimpleNumFieldOrderFractionalIdeal\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/manual/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/manual/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/manual/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/manual/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/manual/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/manual/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/manual/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/manual/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/manual/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/manual/quad_forms/genusherm/#norm-Tuple{HermLocalGenus, Int64}","page":"Genera for hermitian lattices","title":"norm","text":"norm(g::HermLocalGenus, i::Int) -> 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 mathfrak p-valuation of the norm of the ith Jordan block of g.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/quad_forms/genusherm/#norm-Tuple{HermLocalGenus}","page":"Genera for hermitian lattices","title":"norm","text":"norm(g::HermLocalGenus) -> AbsSimpleNumFieldOrderFractionalIdeal\n\nReturn the norm of g, i.e. the norm of any of its representatives.\n\nGiven a local genus symbol g of hermitian lattices over EK at a prime ideal mathfrak p of mathcal O_K, it norm is computed as the norm of the Jordan block of minimum mathfrak p-valuation.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/quad_forms/genusherm/#norms-Tuple{HermLocalGenus}","page":"Genera for hermitian lattices","title":"norms","text":"norms(g::HermLocalGenus) -> Vector{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 mathfrak p-valuations of the norms of the Jordan blocks of g.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/quad_forms/genusherm/#Examples-3","page":"Genera for hermitian lattices","title":"Examples","text":"","category":"section"},{"location":"Hecke/manual/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.RelSimpleNumFieldElem{AbsSimpleNumFieldElem}}[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/manual/quad_forms/genusherm/","page":"Genera for hermitian lattices","title":"Genera for hermitian lattices","text":"","category":"page"},{"location":"Hecke/manual/quad_forms/genusherm/#Predicates","page":"Genera for hermitian lattices","title":"Predicates","text":"","category":"section"},{"location":"Hecke/manual/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/manual/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/manual/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/manual/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/manual/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/manual/quad_forms/genusherm/#Examples-4","page":"Genera for hermitian lattices","title":"Examples","text":"","category":"section"},{"location":"Hecke/manual/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/manual/quad_forms/genusherm/","page":"Genera for hermitian lattices","title":"Genera for hermitian lattices","text":"","category":"page"},{"location":"Hecke/manual/quad_forms/genusherm/#Local-uniformizer","page":"Genera for hermitian lattices","title":"Local uniformizer","text":"","category":"section"},{"location":"Hecke/manual/quad_forms/genusherm/","page":"Genera for hermitian lattices","title":"Genera for hermitian lattices","text":"uniformizer(::HermLocalGenus)","category":"page"},{"location":"Hecke/manual/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/manual/quad_forms/genusherm/#Example","page":"Genera for hermitian lattices","title":"Example","text":"","category":"section"},{"location":"Hecke/manual/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/manual/quad_forms/genusherm/","page":"Genera for hermitian lattices","title":"Genera for hermitian lattices","text":"","category":"page"},{"location":"Hecke/manual/quad_forms/genusherm/#Determinant-representatives","page":"Genera for hermitian lattices","title":"Determinant representatives","text":"","category":"section"},{"location":"Hecke/manual/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/manual/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/manual/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/manual/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/manual/quad_forms/genusherm/#Examples-5","page":"Genera for hermitian lattices","title":"Examples","text":"","category":"section"},{"location":"Hecke/manual/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/manual/quad_forms/genusherm/","page":"Genera for hermitian lattices","title":"Genera for hermitian lattices","text":"","category":"page"},{"location":"Hecke/manual/quad_forms/genusherm/#Gram-matrices","page":"Genera for hermitian lattices","title":"Gram matrices","text":"","category":"section"},{"location":"Hecke/manual/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/manual/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/manual/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/manual/quad_forms/genusherm/#Examples-6","page":"Genera for hermitian lattices","title":"Examples","text":"","category":"section"},{"location":"Hecke/manual/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.RelSimpleNumFieldElem{AbsSimpleNumFieldElem}}[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/manual/quad_forms/genusherm/","page":"Genera for hermitian lattices","title":"Genera for hermitian lattices","text":"","category":"page"},{"location":"Hecke/manual/quad_forms/genusherm/","page":"Genera for hermitian lattices","title":"Genera for hermitian lattices","text":"","category":"page"},{"location":"Hecke/manual/quad_forms/genusherm/#Global-genus-symbols","page":"Genera for hermitian lattices","title":"Global genus symbols","text":"","category":"section"},{"location":"Hecke/manual/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/manual/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/manual/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/manual/quad_forms/genusherm/#Creation-of-global-genus-symbols","page":"Genera for hermitian lattices","title":"Creation of global genus symbols","text":"","category":"section"},{"location":"Hecke/manual/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/manual/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/manual/quad_forms/genusherm/","page":"Genera for hermitian lattices","title":"Genera for hermitian lattices","text":" genus(S::Vector{HermLocalGenus}, signatures) -> HermGenus","category":"page"},{"location":"Hecke/manual/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/manual/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/manual/quad_forms/genusherm/","page":"Genera for hermitian lattices","title":"Genera for hermitian lattices","text":" genus(L::HermLat) -> HermGenus","category":"page"},{"location":"Hecke/manual/quad_forms/genusherm/#Examples-7","page":"Genera for hermitian lattices","title":"Examples","text":"","category":"section"},{"location":"Hecke/manual/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/manual/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.RelSimpleNumFieldElem{AbsSimpleNumFieldElem}}[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/manual/quad_forms/genusherm/","page":"Genera for hermitian lattices","title":"Genera for hermitian lattices","text":"","category":"page"},{"location":"Hecke/manual/quad_forms/genusherm/#Attributes-2","page":"Genera for hermitian lattices","title":"Attributes","text":"","category":"section"},{"location":"Hecke/manual/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)\nscale(::HermGenus)\nnorm(::HermGenus)","category":"page"},{"location":"Hecke/manual/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/manual/quad_forms/genusherm/#primes-Tuple{HermGenus}","page":"Genera for hermitian lattices","title":"primes","text":"primes(G::HermGenus) -> Vector{AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}}\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/manual/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/manual/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/manual/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/manual/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/manual/quad_forms/genusherm/#scale-Tuple{HermGenus}","page":"Genera for hermitian lattices","title":"scale","text":"scale(G::HermGenus) -> AbsSimpleNumFieldOrderFractionalIdeal\n\nReturn the scale ideal of any hermitian lattice with global genus symbol G.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/quad_forms/genusherm/#norm-Tuple{HermGenus}","page":"Genera for hermitian lattices","title":"norm","text":"norm(G::HermGenus) -> AbsSimpleNumFieldOrderFractionalIdeal\n\nReturn the norm ideal of any hermitian lattice with global genus symbol G.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/quad_forms/genusherm/#Examples-8","page":"Genera for hermitian lattices","title":"Examples","text":"","category":"section"},{"location":"Hecke/manual/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.RelSimpleNumFieldElem{AbsSimpleNumFieldElem}}[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/manual/quad_forms/genusherm/","page":"Genera for hermitian lattices","title":"Genera for hermitian lattices","text":"","category":"page"},{"location":"Hecke/manual/quad_forms/genusherm/#Mass","page":"Genera for hermitian lattices","title":"Mass","text":"","category":"section"},{"location":"Hecke/manual/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/manual/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/manual/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/manual/quad_forms/genusherm/","page":"Genera for hermitian lattices","title":"Genera for hermitian lattices","text":"mass(::HermLat)","category":"page"},{"location":"Hecke/manual/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/manual/quad_forms/genusherm/#Example-2","page":"Genera for hermitian lattices","title":"Example","text":"","category":"section"},{"location":"Hecke/manual/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.RelSimpleNumFieldElem{AbsSimpleNumFieldElem}}[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/manual/quad_forms/genusherm/","page":"Genera for hermitian lattices","title":"Genera for hermitian lattices","text":"","category":"page"},{"location":"Hecke/manual/quad_forms/genusherm/","page":"Genera for hermitian lattices","title":"Genera for hermitian lattices","text":"","category":"page"},{"location":"Hecke/manual/quad_forms/genusherm/#Representatives-of-a-genus","page":"Genera for hermitian lattices","title":"Representatives of a genus","text":"","category":"section"},{"location":"Hecke/manual/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/manual/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/manual/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/manual/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/manual/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/manual/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/manual/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/manual/quad_forms/genusherm/#Examples-9","page":"Genera for hermitian lattices","title":"Examples","text":"","category":"section"},{"location":"Hecke/manual/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/manual/quad_forms/genusherm/","page":"Genera for hermitian lattices","title":"Genera for hermitian lattices","text":"","category":"page"},{"location":"Hecke/manual/quad_forms/genusherm/#Sum-of-genera","page":"Genera for hermitian lattices","title":"Sum of genera","text":"","category":"section"},{"location":"Hecke/manual/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/manual/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/manual/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/manual/quad_forms/genusherm/#Examples-10","page":"Genera for hermitian lattices","title":"Examples","text":"","category":"section"},{"location":"Hecke/manual/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.RelSimpleNumFieldElem{AbsSimpleNumFieldElem}}[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/manual/quad_forms/genusherm/","page":"Genera for hermitian lattices","title":"Genera for hermitian lattices","text":"","category":"page"},{"location":"Hecke/manual/quad_forms/genusherm/#Enumeration-of-genera","page":"Genera for hermitian lattices","title":"Enumeration of genera","text":"","category":"section"},{"location":"Hecke/manual/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.RelSimpleNumField, ::Int, ::Dict{InfPlc, Int}, ::Union{Hecke.RelNumFieldOrderIdeal, Hecke.RelNumFieldOrderFractionalIdeal})","category":"page"},{"location":"Hecke/manual/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::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}, 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/manual/quad_forms/genusherm/#hermitian_genera-Tuple{Hecke.RelSimpleNumField, Int64, Dict{InfPlc, Int64}, Union{Hecke.RelNumFieldOrderFractionalIdeal, Hecke.RelNumFieldOrderIdeal}}","page":"Genera for hermitian lattices","title":"hermitian_genera","text":"hermitian_genera(E::NumField, rank::Int,\n signatures::Dict{InfPlc, Int},\n determinant::Union{Hecke.RelNumFieldOrderIdeal, Hecke.RelNumFieldOrderFractionalIdeal};\n min_scale::Union{Hecke.RelNumFieldOrderIdeal, Hecke.RelNumFieldOrderFractionalIdeal} = is_integral(determinant) ? inv(1*order(determinant)) : determinant,\n max_scale::Union{Hecke.RelNumFieldOrderIdeal, Hecke.RelNumFieldOrderFractionalIdeal} = 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/manual/quad_forms/genusherm/#Examples-11","page":"Genera for hermitian lattices","title":"Examples","text":"","category":"section"},{"location":"Hecke/manual/quad_forms/genusherm/","page":"Genera for hermitian lattices","title":"Genera for hermitian lattices","text":"using Hecke # hide\nK, a = cyclotomic_real_subfield(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/manual/quad_forms/genusherm/#Rescaling","page":"Genera for hermitian lattices","title":"Rescaling","text":"","category":"section"},{"location":"Hecke/manual/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/manual/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/manual/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":"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 = free_module(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 = free_module(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 = free_module(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 = free_module(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 = free_module(ZZ, 2)\nN = matrix(ZZ, 2, 2, BigInt[1, 0, 0, 1])\nf = ModuleIsomorphism(M, M, N)\n\ng = inv(f)","category":"page"},{"location":"Hecke/howto/#How-to-guides","page":"How-to guides","title":"How-to guides","text":"","category":"section"},{"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 = Rlangle x yrangle S, (x, y) = free_associative_algebra(R, [:x, :y])\nS = K(x) S, x = rational_function_field(K, :x)\nS = K(x y) S, (x, y) = rational_function_field(K, [:x, :y])\nS = Rx (to precision n) S, x = power_series_ring(R, n, :x)\nS = Rx y (to precision n) S, (x, y) = power_series_ring(R, n, [:x, :y])\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 = R((x y)) (to precision n) S, (x, y) = laurent_polynomial_ring(R, n, [:x, :y])\nPuiseux series ring to precision n S, x = puiseux_series_ring(R, n, :x)\nPuiseux series field to precision n S, x = puiseux_series_field(K, n, :x)\nS = K(x)(y)(f) S, y = function_field(f, :y) with fin K(x)t\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)","category":"page"},{"location":"AbstractAlgebra/constructors/#Parent-objects-with-variable-names","page":"Constructing mathematical objects in AbstractAlgebra.jl","title":"Parent objects with variable names","text":"","category":"section"},{"location":"AbstractAlgebra/constructors/","page":"Constructing mathematical objects in AbstractAlgebra.jl","title":"Constructing mathematical objects in AbstractAlgebra.jl","text":"The multivariate parent object constructors (polynomial_ring, power_series_ring, free_associative_algebra, laurent_polynomial_ring, and rational_function_field) share a common interface for specifying the variable names, which is provided by @varnames_interface.","category":"page"},{"location":"AbstractAlgebra/constructors/","page":"Constructing mathematical objects in AbstractAlgebra.jl","title":"Constructing mathematical objects in AbstractAlgebra.jl","text":"AbstractAlgebra.@varnames_interface\nAbstractAlgebra.variable_names\nAbstractAlgebra.reshape_to_varnames","category":"page"},{"location":"AbstractAlgebra/constructors/#@varnames_interface","page":"Constructing mathematical objects in AbstractAlgebra.jl","title":"@varnames_interface","text":"@varnames_interface [M.]f(args..., varnames) macros=:yes n=n range=1:n\n\nAdd methods X, vars = f(args..., varnames...) and macro X = @f(args..., varnames...) to current scope.\n\nCreated methods\n\nX, gens::Vector{T} = f(args..., varnames::Vector{Symbol})\n\nBase method, called by everything else defined below. If a module M is specified, this is implemented as a call to M.f. Otherwise, a method f with this signature must already exist.\n\n\n\nX, gens... = f(args..., varnames...; kv...)\nX, gens... = f(args..., varnames::Tuple; kv...)\n\nCompute X and gens via the base method. Then reshape gens into the shape defined by varnames according to variable_names.\n\nThe vararg varnames... method needs at least one argument to avoid confusion. Moreover a single VarName argument will be dispatched to use a univariate method of f if it exists (e.g. polynomial_ring(R, :x)). If you need those cases, use the Tuple method.\n\nKeyword arguments are passed on to the base method.\n\n\n\nX, x::Vector{T} = f(args..., n::Int, s::VarName = :x; kv...)\n\nShorthand for X, x = f(args..., \"$s#\" => 1:n; kv...). The name of the argument n can be changed via the n option. The range 1:n is given via the range option.\n\nSetting n=:no disables creation of this method.\n\n\n\nX = @f(args..., varnames...; kv...)\nX = @f(args..., varnames::Tuple; kv...)\nX = @f(args..., n::Int, s::VarName = :x; kv...)\nX = @f(args..., varname::VarName; kv...)\n\nThese macros behave like their f(args..., varnames; kv...) counterparts but also introduce the indexed varnames into the current scope. The first version needs at least one varnames argument to avoid confusion. The last version calls the univariate base method if it exists (e.g. polynomial_ring(R, varname)).\n\nSetting macros=:no disables macro creation.\n\nwarning: Warning\nTurning varnames into a vector of symbols happens by evaluating variable_names(varnames) in the global scope of the current module. For interactive usage in the REPL this is fine, but in general you have no access to local variables and should not use any side effects in varnames.\n\nExamples\n\njulia> f(a, s::Vector{Symbol}) = a, String.(s)\nf (generic function with 1 method)\n\njulia> AbstractAlgebra.@varnames_interface f(a, s)\n@f (macro with 1 method)\n\njulia> f\nf (generic function with 5 methods)\n\njulia> f(\"hello\", [:x, :y, :z])\n(\"hello\", [\"x\", \"y\", \"z\"])\n\njulia> f(\"numbered\", 3)\n(\"numbered\", [\"x1\", \"x2\", \"x3\"])\n\njulia> f(\"hello\", :x => (1:1, 1:2), :y => 1:2, [:z])\n(\"hello\", [\"x[1, 1]\" \"x[1, 2]\"], [\"y[1]\", \"y[2]\"], [\"z\"])\n\njulia> f(\"projective\", [\"x$i$j\" for i in 0:1, j in 0:1], [:y0, :y1], [:z])\n(\"projective\", [\"x00\" \"x01\"; \"x10\" \"x11\"], [\"y0\", \"y1\"], [\"z\"])\n\njulia> f(\"fun inputs\", 'a':'g', Symbol.('x':'z', [0 1]))\n(\"fun inputs\", [\"a\", \"b\", \"c\", \"d\", \"e\", \"f\", \"g\"], [\"x0\" \"x1\"; \"y0\" \"y1\"; \"z0\" \"z1\"])\n\njulia> @f(\"hello\", \"x#\" => (1:1, 1:2), \"y#\" => (1:2), [:z])\n\"hello\"\n\njulia> (x11, x12, y1, y2, z)\n(\"x11\", \"x12\", \"y1\", \"y2\", \"z\")\n\njulia> g(a, s::Vector{Symbol}; kv...) = (a, kv...), String.(s)\ng (generic function with 1 method)\n\njulia> AbstractAlgebra.@varnames_interface g(a, s)\n@g (macro with 1 method)\n\njulia> @g(\"parameters\", [:x, :y], a=1, b=2; c=3)\n(\"parameters\", :c => 3, :a => 1, :b => 2)\n\n\n\n\n\n","category":"macro"},{"location":"AbstractAlgebra/constructors/#variable_names","page":"Constructing mathematical objects in AbstractAlgebra.jl","title":"variable_names","text":"variable_names(a...) -> Vector{Symbol}\nvariable_names(a::Tuple) -> Vector{Symbol}\n\nCreate a vector of variable names from a variable name specification.\n\nEach argument can be either an Array of VarNames, or of the form s::VarName => iter, or of the form s::VarName => (iter...). Here iter is supposed to be any iterable, typically a range like 1:5. The :s => iter specification is shorthand for [\"s[$i]\" for i in iter]. Similarly :s => (iter1, iter2) is shorthand for [\"s[$i,$j]\" for i in iter1, j in iter2], and likewise for three and more iterables.\n\nAs an alternative \"s#\" => iter is shorthand for [\"s$i\" for i in iter]. This also works for multiple iterators in that\"s#\" => (iter1, iter2) is shorthand for [\"s$i$j\" for i in iter1, j in iter2].\n\nExamples\n\njulia> AbstractAlgebra.variable_names([:x, :y])\n2-element Vector{Symbol}:\n :x\n :y\n\njulia> AbstractAlgebra.variable_names(:x => (0:0, 0:1), :y => 0:1, [:z])\n5-element Vector{Symbol}:\n Symbol(\"x[0, 0]\")\n Symbol(\"x[0, 1]\")\n Symbol(\"y[0]\")\n Symbol(\"y[1]\")\n :z\n\njulia> AbstractAlgebra.variable_names(\"x#\" => (0:0, 0:1), \"y#\" => 0:1)\n4-element Vector{Symbol}:\n :x00\n :x01\n :y0\n :y1\n\njulia> AbstractAlgebra.variable_names(\"x#\" => 9:11)\n3-element Vector{Symbol}:\n :x9\n :x10\n :x11\n\njulia> AbstractAlgebra.variable_names([\"x$i$i\" for i in 1:3])\n3-element Vector{Symbol}:\n :x11\n :x22\n :x33\n\njulia> AbstractAlgebra.variable_names('a':'c', ['z'])\n4-element Vector{Symbol}:\n :a\n :b\n :c\n :z\n\n\n\n\n\n","category":"function"},{"location":"AbstractAlgebra/constructors/#reshape_to_varnames","page":"Constructing mathematical objects in AbstractAlgebra.jl","title":"reshape_to_varnames","text":"reshape_to_varnames(vec::Vector{T}, varnames...) :: Tuple{Array{<:Any, T}}\nreshape_to_varnames(vec::Vector{T}, varnames::Tuple) :: Tuple{Array{<:Any, T}}\n\nTurn vec into the shape of varnames. Reverse flattening from variable_names.\n\nExamples\n\njulia> s = ([:a, :b], \"x#\" => (1:1, 1:2), \"y#\" => 1:2, [:z]);\n\njulia> AbstractAlgebra.reshape_to_varnames(AbstractAlgebra.variable_names(s...), s...)\n([:a, :b], [:x11 :x12], [:y1, :y2], [:z])\n\njulia> R, v = polynomial_ring(ZZ, AbstractAlgebra.variable_names(s...))\n(Multivariate polynomial ring in 7 variables over integers, AbstractAlgebra.Generic.MPoly{BigInt}[a, b, x11, x12, y1, y2, z])\n\njulia> (a, b), x, y, z = AbstractAlgebra.reshape_to_varnames(v, s...)\n(AbstractAlgebra.Generic.MPoly{BigInt}[a, b], AbstractAlgebra.Generic.MPoly{BigInt}[x11 x12], AbstractAlgebra.Generic.MPoly{BigInt}[y1, y2], AbstractAlgebra.Generic.MPoly{BigInt}[z])\n\njulia> R, (a, b), x, y, z = polynomial_ring(ZZ, s...)\n(Multivariate polynomial ring in 7 variables over integers, AbstractAlgebra.Generic.MPoly{BigInt}[a, b], AbstractAlgebra.Generic.MPoly{BigInt}[x11 x12], AbstractAlgebra.Generic.MPoly{BigInt}[y1, y2], AbstractAlgebra.Generic.MPoly{BigInt}[z])\n\n\n\n\n\n","category":"function"},{"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. [Wei18] 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 = ambient_space(tm)\nA family of spaces of dimension d = 5\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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=\"\", model_parameters::Dict{String,<:Any} = Dict{String,Any}(), base_space::FTheorySpace = affine_space(NormalToricVariety, 0), model_sections::Dict{String, <:Any} = Dict{String,Any}(), defining_classes::Dict{String, <:Any} = Dict{String,Any}(), completeness_check::Bool = true)","category":"page"},{"location":"Experimental/FTheoryTools/literature/#literature_model-Tuple{}","page":"Literature constructions","title":"literature_model","text":"literature_model(; doi::String=\"\", arxiv_id::String=\"\", version::String=\"\", equation::String=\"\", model_parameters::Dict{String,<:Any} = Dict{String,Any}(), base_space::FTheorySpace = affine_space(NormalToricVariety, 0), model_sections::Dict{String, <:Any} = Dict{String,Any}(), defining_classes::Dict{String, <:Any} = Dict{String,Any}(), completeness_check::Bool = true)\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 parameters can be provided using the optional argument model_parameters, which should be a dictionary such as Dict(\"k\" => 5).\n\nFurther, some literature models require the specification of one or more divisor classes that define the model. This information can be provided using the optional argument defining_classes, which should be a dictionary such as Dict(\"w\" => w), where w is a divisor, such as that provided by torusinvariant_prime_divisors.\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)\nA family of spaces of dimension d = 5\n\njulia> coordinate_ring(v)\nMultivariate polynomial ring in 8 variables w, a1, a21, a32, ..., z\n over rational field\n\nIt is also possible to construct a literature model over a particular base. Currently, this feature is only supported for toric base spaces.\n\njulia> B3 = projective_space(NormalToricVariety, 3)\nNormal toric variety\n\njulia> w = torusinvariant_prime_divisors(B3)[1]\nTorus-invariant, prime divisor on a normal toric variety\n\njulia> t2 = literature_model(arxiv_id = \"1109.3454\", equation = \"3.1\", base_space = B3, defining_classes = Dict(\"w\" => w), completeness_check = false)\nConstruction over concrete base may lead to singularity enhancement. Consider computing singular_loci. However, this may take time!\n\nGlobal Tate model over a concrete base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)\n\njulia> length(singular_loci(t2))\n2\n\nOf course, this is also possible for Weierstrass models.\n\njulia> B2 = projective_space(NormalToricVariety, 2)\nNormal toric variety\n\njulia> b = torusinvariant_prime_divisors(B2)[1]\nTorus-invariant, prime divisor on a normal toric variety\n\njulia> w = literature_model(arxiv_id = \"1208.2695\", equation = \"B.19\", base_space = B2, defining_classes = Dict(\"b\" => b), completeness_check = false)\nConstruction over concrete base may lead to singularity enhancement. Consider computing singular_loci. However, this may take time!\n\nWeierstrass model over a concrete base -- U(1) Weierstrass model based on arXiv paper 1208.2695 Eq. (B.19)\n\njulia> length(singular_loci(w))\n1\n\nFor convenience, we also support a simplified constructor. Instead of the meta data of the article, this constructor accepts an integer, which specifies the position of this model in our database.\n\njulia> B2 = projective_space(NormalToricVariety, 2)\nNormal toric variety\n\njulia> b = torusinvariant_prime_divisors(B2)[1]\nTorus-invariant, prime divisor on a normal toric variety\n\njulia> w = literature_model(3, base_space = B2, defining_classes = Dict(\"b\" => b), completeness_check = false)\nConstruction over concrete base may lead to singularity enhancement. Consider computing singular_loci. However, this may take time!\n\nWeierstrass model over a concrete base -- U(1) Weierstrass model based on arXiv paper 1208.2695 Eq. (B.19)\n\njulia> length(singular_loci(w))\n1\n\nSimilarly, also hypersurface models are supported:\n\njulia> h = literature_model(arxiv_id = \"1208.2695\", equation = \"B.5\")\nAssuming that the first row of the given grading is the grading under Kbar\n\nHypersurface model over a not fully specified base\n\njulia> explicit_model_sections(h)\nDict{String, MPolyRingElem} with 5 entries:\n \"c2\" => c2\n \"c1\" => c1\n \"c3\" => c3\n \"b\" => b\n \"c0\" => c0\n\njulia> B2 = projective_space(NormalToricVariety, 2)\nNormal toric variety\n\njulia> b = torusinvariant_prime_divisors(B2)[1]\nTorus-invariant, prime divisor on a normal toric variety\n\njulia> h2 = literature_model(arxiv_id = \"1208.2695\", equation = \"B.5\", base_space = B2, defining_classes = Dict(\"b\" => b))\nConstruction over concrete base may lead to singularity enhancement. Consider computing singular_loci. However, this may take time!\n\nHypersurface model over a concrete base\n\njulia> hypersurface_equation_parametrization(h2)\nb*w*v^2 - c0*u^4 - c1*u^3*v - c2*u^2*v^2 - c3*u*v^3 + w^2\n\nIn principle, we can even create the model with the largest number of F-theory vacua. This happens by executing the line h = literature_model(arxiv_id = \"1511.03209\"). However, this line will currently run for a long time on a normal personal computer (likely about half an hour or even more), due to the massive complexity of computing the Tate sections of this global Tate model.\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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 referencing meta data:","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_name(m::AbstractFTheoryModel)\njournal_pages(m::AbstractFTheoryModel)\njournal_report_numbers(m::AbstractFTheoryModel)\njournal_volume(m::AbstractFTheoryModel)\njournal_year(m::AbstractFTheoryModel)\nliterature_identifier(m::AbstractFTheoryModel)\nmodel_parameters(m::AbstractFTheoryModel)\npaper_authors(m::AbstractFTheoryModel)\npaper_buzzwords(m::AbstractFTheoryModel)\npaper_description(m::AbstractFTheoryModel)\npaper_title(m::AbstractFTheoryModel)\nbirational_literature_models(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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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 of any associated_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 associated_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(11) Tate model with parameter values (k = 5) based on arXiv paper 1212.2949 Eq. (3.2)\n\njulia> associated_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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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{QQMPolyRingElem}}:\n [0, 0, 1]\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/literature/#journal_name-Tuple{AbstractFTheoryModel}","page":"Literature constructions","title":"journal_name","text":"journal_name(m::AbstractFTheoryModel)\n\nReturn the journal_name of the published paper in which the given model was introduced. If no journal_name 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_name(m)\n\"Nucl. Phys. B\"\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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(11) 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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/literature/#birational_literature_models-Tuple{AbstractFTheoryModel}","page":"Literature constructions","title":"birational_literature_models","text":"birational_literature_models(m::AbstractFTheoryModel)\n\nReturn a list of the unique identifiers of birational_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 birational_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> birational_literature_models(m)\n1-element Vector{String}:\n \"1507_05954-1\"\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/literature/","page":"Literature constructions","title":"Literature constructions","text":"Such meta data can be modified with setters. For instance, there is a function set_description(m::AbstractFTheoryModel, description::String), which takes the model in question as the first argument and the desired description - provided as string - as the second argument. Such a setter function exists for all of the above. If appropriate, we also offer a method that adds a new value. For instance, we have a function add_paper_buzzword(m::AbstractFTheoryModel, addition::String).","category":"page"},{"location":"Experimental/FTheoryTools/literature/","page":"Literature constructions","title":"Literature constructions","text":"In addition, the following attributes are available to access advanced model information:","category":"page"},{"location":"Experimental/FTheoryTools/literature/","page":"Literature constructions","title":"Literature constructions","text":"resolutions(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/#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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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{QQMPolyRingElem}}}}:\n [[[0, 0, 1], [0, 0, 1], [0, 1], [0, 1], [0, 1], [a32, -a43]]]\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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{QQMPolyRingElem}}}:\n [[1, 1, 0], [1, 1, w], [1, 1], [1, 1], [1, 1], [1, 1]]\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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{QQMPolyRingElem}}}}:\n [[[0, 0, 1], [0, 0, 1], [0, 0, 1], [0, 0, 1], [0, 0, 1], [a32, -a43]]]\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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{QQMPolyRingElem}}}:\n [[1, 1, 0], [1, 1, w], [1, 1, w], [1, 1, w], [1, 1, w], [1, 1]]\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/literature/","page":"Literature constructions","title":"Literature constructions","text":"One can 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_name(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_birational_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),\nhas_zero_section_coordinates(m::AbstractFTheoryModel),\nhas_gauge_algebra(m::AbstractFTheoryModel),\nhas_global_gauge_quotients(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\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\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\njulia> B3 = projective_space(NormalToricVariety, 3)\nNormal toric variety\n\njulia> w = torusinvariant_prime_divisors(B3)[1]\nTorus-invariant, prime divisor on a normal toric variety\n\njulia> t = literature_model(arxiv_id = \"1109.3454\", equation = \"3.1\", base_space = B3, defining_classes = Dict(\"w\" => w), completeness_check = false)\nConstruction over concrete base may lead to singularity enhancement. Consider computing singular_loci. However, this may take time!\n\nGlobal Tate model over a concrete base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)\n\njulia> t2 = resolve(t, 1)\nPartially resolved global Tate model over a concrete base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)\n\njulia> cox_ring(ambient_space(t2))\nMultivariate polynomial ring in 12 variables over QQ graded by\n x1 -> [1 0 0 0 0 0 0]\n x2 -> [0 1 0 0 0 0 0]\n x3 -> [0 1 0 0 0 0 0]\n x4 -> [0 1 0 0 0 0 0]\n x -> [0 0 1 0 0 0 0]\n y -> [0 0 0 1 0 0 0]\n z -> [0 0 0 0 1 0 0]\n e1 -> [0 0 0 0 0 1 0]\n e4 -> [0 0 0 0 0 0 1]\n e2 -> [-1 -3 -1 1 -1 -1 0]\n e3 -> [0 4 1 -1 1 0 -1]\n s -> [2 6 -1 0 2 1 1]\n\njulia> w2 = 2 * torusinvariant_prime_divisors(B3)[1]\nTorus-invariant, non-prime divisor on a normal toric variety\n\njulia> t3 = literature_model(arxiv_id = \"1109.3454\", equation = \"3.1\", base_space = B3, defining_classes = Dict(\"w\" => w2), completeness_check = false)\nConstruction over concrete base may lead to singularity enhancement. Consider computing singular_loci. However, this may take time!\n\nGlobal Tate model over a concrete base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)\n\njulia> t4 = resolve(t3, 1)\nPartially resolved global Tate model over a concrete base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1)\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/literature/#The-Quadrillion-F-Theory-Standard-Models","page":"Literature constructions","title":"The Quadrillion F-Theory Standard Models","text":"","category":"section"},{"location":"Experimental/FTheoryTools/literature/","page":"Literature constructions","title":"Literature constructions","text":"A yet more special instance of literature models are the Quadrillion F-theory Standard Models (F-theory QSMs) [CHLLT19]. Those hypersurface models come in 708 different families.","category":"page"},{"location":"Experimental/FTheoryTools/literature/","page":"Literature constructions","title":"Literature constructions","text":"The base geometry of an F-theory QSM is obtained from triangulating one of 708 reflexive 3-dimensional polytopes. The models, whose bases are obtained from triangulations of the same polytope form a family. The following information on the polytope in question and its triangulations is available within our database:","category":"page"},{"location":"Experimental/FTheoryTools/literature/","page":"Literature constructions","title":"Literature constructions","text":"vertices(m::AbstractFTheoryModel)\npolytope_index(m::AbstractFTheoryModel)\nhas_quick_triangulation(m::AbstractFTheoryModel)\nmax_lattice_pts_in_facet(m::AbstractFTheoryModel)\nestimated_number_of_triangulations(m::AbstractFTheoryModel)","category":"page"},{"location":"Experimental/FTheoryTools/literature/#vertices-Tuple{AbstractFTheoryModel}","page":"Literature constructions","title":"vertices","text":"vertices(m::AbstractFTheoryModel)\n\nThis method returns the vertices of the polytope the the base of the F-theory QSM is build from. Note that those vertices are normalized according to the Polymake standard to rational numbers.\n\njulia> qsm_model = literature_model(arxiv_id = \"1903.00009\", model_parameters = Dict(\"k\" => 4))\nHypersurface model over a concrete base\n\njulia> vertices(qsm_model)\n4-element Vector{Vector{QQFieldElem}}:\n [-1, -1, -1]\n [1, -1//2, -1//2]\n [-1, 2, -1]\n [-1, -1, 5]\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/literature/#polytope_index-Tuple{AbstractFTheoryModel}","page":"Literature constructions","title":"polytope_index","text":"polytope_index(m::AbstractFTheoryModel)\n\nOf the 3-dimensional reflexive polytope that the base of this F-theory model is build from, this method returns the index within the Kreuzer-Skarke list.\n\njulia> qsm_model = literature_model(arxiv_id = \"1903.00009\", model_parameters = Dict(\"k\" => 4))\nHypersurface model over a concrete base\n\njulia> polytope_index(qsm_model)\n4\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/literature/#has_quick_triangulation-Tuple{AbstractFTheoryModel}","page":"Literature constructions","title":"has_quick_triangulation","text":"has_quick_triangulation(m::AbstractFTheoryModel)\n\nFor a 3-dimensional reflexive polytope in the Kreuzer-Skarke list, the list of full (sometimes also called fine), regular, star triangulations can be extremely large. Consequently, one may wonder if the triangulations can be enumerated in a somewhat reasonable time (say 5 minutes on a personal computer). This method tries to provide an answer to this. It returns true if one should expect a timly response to the atttempt to enumerate all (full, regular, star) triangulations. Otherwise, this method returns false.\n\njulia> qsm_model = literature_model(arxiv_id = \"1903.00009\", model_parameters = Dict(\"k\" => 4))\nHypersurface model over a concrete base\n\njulia> has_quick_triangulation(qsm_model)\ntrue\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/literature/#max_lattice_pts_in_facet-Tuple{AbstractFTheoryModel}","page":"Literature constructions","title":"max_lattice_pts_in_facet","text":"max_lattice_pts_in_facet(m::AbstractFTheoryModel)\n\nIn order to enumerate the number of full, regular, star triangulations of a 3-dimensional reflexive polytope, it is possible to first find the corresponding triangulations of all facets of the polytope [HT17]. A first indication for the complexity of this triangulation task is the maximum number of lattice points in a facet of the polytope in question. This method returns this maximal number of lattice points.\n\njulia> qsm_model = literature_model(arxiv_id = \"1903.00009\", model_parameters = Dict(\"k\" => 4))\nHypersurface model over a concrete base\n\njulia> max_lattice_pts_in_facet(qsm_model)\n16\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/literature/#estimated_number_of_triangulations-Tuple{AbstractFTheoryModel}","page":"Literature constructions","title":"estimated_number_of_triangulations","text":"estimated_number_of_triangulations(m::AbstractFTheoryModel)\n\nThis method returns an estimate for the number of full, regular, star triangulations of the 3-dimensional reflexive polytope, those triangulations define the possible base spaces of the F-theory QSM in question.\n\njulia> qsm_model = literature_model(arxiv_id = \"1903.00009\", model_parameters = Dict(\"k\" => 4))\nHypersurface model over a concrete base\n\njulia> estimated_number_of_triangulations(qsm_model)\n212533333333\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/literature/","page":"Literature constructions","title":"Literature constructions","text":"Beyond the polytope and its triangulations, a number of other integers are of key importance. The following are supported in our database.","category":"page"},{"location":"Experimental/FTheoryTools/literature/","page":"Literature constructions","title":"Literature constructions","text":"kbar3(m::AbstractFTheoryModel)\nhodge_h11(m::AbstractFTheoryModel)\nhodge_h12(m::AbstractFTheoryModel)\nhodge_h13(m::AbstractFTheoryModel)\nhodge_h22(m::AbstractFTheoryModel)","category":"page"},{"location":"Experimental/FTheoryTools/literature/#kbar3-Tuple{AbstractFTheoryModel}","page":"Literature constructions","title":"kbar3","text":"kbar3(m::AbstractFTheoryModel)\n\nLet Kbar denote the anticanonical class of the 3-dimensional base space of the F-theory QSM. Of ample importance is the triple intersection number of Kbar, i.e. Kbar * Kbar * Kbar. This method returns this intersection number.\n\njulia> qsm_model = literature_model(arxiv_id = \"1903.00009\", model_parameters = Dict(\"k\" => 4))\nHypersurface model over a concrete base\n\njulia> kbar3(qsm_model)\n6\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/literature/#hodge_h11-Tuple{AbstractFTheoryModel}","page":"Literature constructions","title":"hodge_h11","text":"hodge_h11(m::AbstractFTheoryModel)\n\nThis methods return the Hodge number h11 of the elliptically fibered 4-fold that defined the F-theory QSM in question.\n\njulia> qsm_model = literature_model(arxiv_id = \"1903.00009\", model_parameters = Dict(\"k\" => 4))\nHypersurface model over a concrete base\n\njulia> hodge_h11(qsm_model)\n31\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/literature/#hodge_h12-Tuple{AbstractFTheoryModel}","page":"Literature constructions","title":"hodge_h12","text":"hodge_h12(m::AbstractFTheoryModel)\n\nThis methods return the Hodge number h12 of the elliptically fibered 4-fold that defined the F-theory QSM in question.\n\njulia> qsm_model = literature_model(arxiv_id = \"1903.00009\", model_parameters = Dict(\"k\" => 4))\nHypersurface model over a concrete base\n\njulia> hodge_h12(qsm_model)\n10\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/literature/#hodge_h13-Tuple{AbstractFTheoryModel}","page":"Literature constructions","title":"hodge_h13","text":"hodge_h13(m::AbstractFTheoryModel)\n\nThis methods return the Hodge number h13 of the elliptically fibered 4-fold that defined the F-theory QSM in question.\n\njulia> qsm_model = literature_model(arxiv_id = \"1903.00009\", model_parameters = Dict(\"k\" => 4))\nHypersurface model over a concrete base\n\njulia> hodge_h13(qsm_model)\n34\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/literature/#hodge_h22-Tuple{AbstractFTheoryModel}","page":"Literature constructions","title":"hodge_h22","text":"hodge_h22(m::AbstractFTheoryModel)\n\nThis methods return the Hodge number h22 of the elliptically fibered 4-fold that defined the F-theory QSM in question.\n\njulia> qsm_model = literature_model(arxiv_id = \"1903.00009\", model_parameters = Dict(\"k\" => 4))\nHypersurface model over a concrete base\n\njulia> hodge_h22(qsm_model)\n284\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/literature/","page":"Literature constructions","title":"Literature constructions","text":"More recently, a research program estimated the exact massless spectra of the F-theory QSMs (cf. [Bie24]). These studies require yet more information about the F-theory QSM geometries, which are supported by our database.","category":"page"},{"location":"Experimental/FTheoryTools/literature/","page":"Literature constructions","title":"Literature constructions","text":"First, recall that (currently), the base of an F-theory QSM is a 3-dimensional toric variety B3. Let s in H^0(B3, Kbar_B3), then V(s) is a K3-surface. Moreover, let xi be the coordinates of the Cox ring of B3. Then V(xi) is a divisor in B3. Consequently, Ci = V(xi) cap V(s) is a divisor in the K3-surface V(s). For the root bundle counting program, these curves Ci are of ample importance (cf. [Bie24]). We support the following information on these curves:","category":"page"},{"location":"Experimental/FTheoryTools/literature/","page":"Literature constructions","title":"Literature constructions","text":"genera_of_ci_curves(m::AbstractFTheoryModel)\ndegrees_of_kbar_restrictions_to_ci_curves(m::AbstractFTheoryModel)\ntopological_intersection_numbers_among_ci_curves(m::AbstractFTheoryModel)\nindices_of_trivial_ci_curves(m::AbstractFTheoryModel)\ntopological_intersection_numbers_among_nontrivial_ci_curves(m::AbstractFTheoryModel)","category":"page"},{"location":"Experimental/FTheoryTools/literature/#genera_of_ci_curves-Tuple{AbstractFTheoryModel}","page":"Literature constructions","title":"genera_of_ci_curves","text":"genera_of_ci_curves(m::AbstractFTheoryModel)\n\nThis methods return the genera of the Ci curves. Recall that Ci = V(xi, s), where xi is a homogeneous coordinate of the 3-dimensional toric base space B3 of the QSM hypersurface model in question, and s is a generic section of the anticanonical bundle of B3. Consequently, we may use the coordinates xi as labels for the curves Ci.\n\njulia> qsm_model = literature_model(arxiv_id = \"1903.00009\", model_parameters = Dict(\"k\" => 4))\nHypersurface model over a concrete base\n\njulia> my_key = collect(keys(genera_of_ci_curves(qsm_model)))[1]\nx7\n\njulia> genera_of_ci_curves(qsm_model)[my_key]\n0\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/literature/#degrees_of_kbar_restrictions_to_ci_curves-Tuple{AbstractFTheoryModel}","page":"Literature constructions","title":"degrees_of_kbar_restrictions_to_ci_curves","text":"degrees_of_kbar_restrictions_to_ci_curves(m::AbstractFTheoryModel)\n\nThe anticanonical divisor of the 3-dimensional toric base space B3 of the QSM hypersurface model in question can be restricted to the Ci curves. The result of this operation is a line bundle. This method returns the degree of this line bundle for every Ci curve.\n\njulia> qsm_model = literature_model(arxiv_id = \"1903.00009\", model_parameters = Dict(\"k\" => 4))\nHypersurface model over a concrete base\n\njulia> my_key = collect(keys(degrees_of_kbar_restrictions_to_ci_curves(qsm_model)))[1]\nx7\n\njulia> degrees_of_kbar_restrictions_to_ci_curves(qsm_model)[my_key]\n0\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/literature/#topological_intersection_numbers_among_ci_curves-Tuple{AbstractFTheoryModel}","page":"Literature constructions","title":"topological_intersection_numbers_among_ci_curves","text":"topological_intersection_numbers_among_ci_curves(m::AbstractFTheoryModel)\n\nThe topological intersection numbers among Ci curves are also of ample importance. This method returns those intersection numbers in the form of a matrix.\n\njulia> qsm_model = literature_model(arxiv_id = \"1903.00009\", model_parameters = Dict(\"k\" => 4))\nHypersurface model over a concrete base\n\njulia> n_rows(topological_intersection_numbers_among_ci_curves(qsm_model))\n29\n\njulia> n_columns(topological_intersection_numbers_among_ci_curves(qsm_model))\n29\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/literature/#indices_of_trivial_ci_curves-Tuple{AbstractFTheoryModel}","page":"Literature constructions","title":"indices_of_trivial_ci_curves","text":"indices_of_trivial_ci_curves(m::AbstractFTheoryModel)\n\nSome of the Ci curves are trivial, in that V(xi, s) is the empty set. This method returns the vector of all indices of trivial Ci curves. That is, should V(x23, s) be the empty set, then 23 will be included in the returned list.\n\njulia> qsm_model = literature_model(arxiv_id = \"1903.00009\", model_parameters = Dict(\"k\" => 4))\nHypersurface model over a concrete base\n\njulia> indices_of_trivial_ci_curves(qsm_model)\n10-element Vector{Int64}:\n 23\n 22\n 18\n 19\n 20\n 26\n 10\n 11\n 12\n 15\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/literature/#topological_intersection_numbers_among_nontrivial_ci_curves-Tuple{AbstractFTheoryModel}","page":"Literature constructions","title":"topological_intersection_numbers_among_nontrivial_ci_curves","text":"topological_intersection_numbers_among_nontrivial_ci_curves(m::AbstractFTheoryModel)\n\nThe topological intersection numbers among the non-trivial Ci curves are used frequently. This method returns those intersection numbers in the form of a matrix.\n\njulia> qsm_model = literature_model(arxiv_id = \"1903.00009\", model_parameters = Dict(\"k\" => 4))\nHypersurface model over a concrete base\n\njulia> n_rows(topological_intersection_numbers_among_nontrivial_ci_curves(qsm_model))\n19\n\njulia> n_columns(topological_intersection_numbers_among_nontrivial_ci_curves(qsm_model))\n19\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/literature/","page":"Literature constructions","title":"Literature constructions","text":"The collection of the Ci-curves form a nodal curve. To every nodal curve one can associate a (dual) graph. In this graph, every irreducible component of the nodal curve becomes a node/vertex of the dual graph, and every nodal singularity of the nodal curve turns into an edge of the dual graph. In the case at hand, this is rather simple.","category":"page"},{"location":"Experimental/FTheoryTools/literature/","page":"Literature constructions","title":"Literature constructions","text":"The Ci-curves turn into the irreducible components of the nodel curve. Certainly, we only need to focus on the non-trivial Ci-curves. A non-trivial Ci-curve can split into multiple irreducible components. This is taken into acccount when the nodes/vertices of the dual graph are constructed.","category":"page"},{"location":"Experimental/FTheoryTools/literature/","page":"Literature constructions","title":"Literature constructions","text":"The topological intersection numbers among the Ci-curves (or rather, their irreducible components) tells us how many nodal singularities link the Ci-curves (or rather, their irreducible components) in question. Hence, if the topological intersection numbers is zero, there is no edge between the corresponding nodes. Otherwise, if the topological intersection number is positive - say n -, then there are exactly n edges between the nodes in question.","category":"page"},{"location":"Experimental/FTheoryTools/literature/","page":"Literature constructions","title":"Literature constructions","text":"The following functions access/create the so-obtained dual graph:","category":"page"},{"location":"Experimental/FTheoryTools/literature/","page":"Literature constructions","title":"Literature constructions","text":"dual_graph(m::AbstractFTheoryModel)\ncomponents_of_dual_graph(m::AbstractFTheoryModel)\ndegrees_of_kbar_restrictions_to_components_of_dual_graph(m::AbstractFTheoryModel)\ngenera_of_components_of_dual_graph(m::AbstractFTheoryModel)","category":"page"},{"location":"Experimental/FTheoryTools/literature/#dual_graph-Tuple{AbstractFTheoryModel}","page":"Literature constructions","title":"dual_graph","text":"dual_graph(m::AbstractFTheoryModel)\n\nThis method returns the dual graph of the QSM model in question. Note that no labels are (currently) attached to the vertices/nodes or edges. To understand/read this graph correctly, please use the methods listed below.\n\njulia> qsm_model = literature_model(arxiv_id = \"1903.00009\", model_parameters = Dict(\"k\" => 4))\nHypersurface model over a concrete base\n\njulia> dual_graph(qsm_model)\nUndirected graph with 21 nodes and the following edges:\n(5, 1)(6, 5)(7, 6)(8, 7)(9, 4)(9, 8)(10, 1)(11, 4)(12, 3)(12, 10)(13, 3)(13, 11)(14, 1)(15, 4)(16, 3)(17, 3)(18, 2)(18, 14)(19, 2)(19, 15)(20, 2)(20, 16)(21, 2)(21, 17)\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/literature/#components_of_dual_graph-Tuple{AbstractFTheoryModel}","page":"Literature constructions","title":"components_of_dual_graph","text":"components_of_dual_graph(m::AbstractFTheoryModel)\n\nThis method returns a vector with labels for each node/vertex of the dual graph of the QSM model in question. Those labels allow to understand the geometric origin of the node/vertex.\n\nSpecifically, recall that those nodes are associated to the Ci-curves, which are in turn given by Ci = V(xi, s). xi is a homogenous coordinate of the 3-dimensional toric base space B3 of the QSM in question, and s is a generic section of the anticanonical bundle of B3.\n\nOnly non-trivial Ci = V(xi, s) correspond to vertices/nodes of the dual graph.\n\nIf Ci = V(xi, s) is irreducible and corresponds to the k-th component, then the label \"Ci\" appears at position k of the vector returned by this method. However, if Ci = V(xi, s) is reducible, then we introduce the labels Ci-0, Ci-1, Ci-2 etc. for those irreducible components of Ci. If Ci-0 corresponds to the k-th components of the dual graph, then the label \"Ci-0\" appears at position k of the vector returned by this method.\n\njulia> qsm_model = literature_model(arxiv_id = \"1903.00009\", model_parameters = Dict(\"k\" => 4))\nHypersurface model over a concrete base\n\njulia> components_of_dual_graph(qsm_model)\n21-element Vector{String}:\n \"C0\"\n \"C1\"\n \"C2\"\n \"C3\"\n \"C4\"\n \"C5\"\n \"C6\"\n \"C7\"\n \"C8\"\n \"C9\"\n ⋮\n \"C16\"\n \"C17\"\n \"C21\"\n \"C24-0\"\n \"C24-1\"\n \"C25\"\n \"C27\"\n \"C28-0\"\n \"C28-1\"\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/literature/#degrees_of_kbar_restrictions_to_components_of_dual_graph-Tuple{AbstractFTheoryModel}","page":"Literature constructions","title":"degrees_of_kbar_restrictions_to_components_of_dual_graph","text":"degrees_of_kbar_restrictions_to_components_of_dual_graph(m::AbstractFTheoryModel)\n\nThe anticanonical bundle of the toric 3-dimensional base space of the F-theory QSM in question can be restricted to the (geometric counterparts of the) nodes/vertices of the dual graph. The result is a line bundle for each node/vertex. This method returns a vector with the degrees of these line bundles.\n\njulia> qsm_model = literature_model(arxiv_id = \"1903.00009\", model_parameters = Dict(\"k\" => 4))\nHypersurface model over a concrete base\n\njulia> degrees_of_kbar_restrictions_to_components_of_dual_graph(qsm_model)[\"C28-1\"]\n0\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/literature/#genera_of_components_of_dual_graph-Tuple{AbstractFTheoryModel}","page":"Literature constructions","title":"genera_of_components_of_dual_graph","text":"genera_of_components_of_dual_graph(m::AbstractFTheoryModel)\n\nThis methods returns a vector with the genera of the (geometric counterparts of the) nodes/vertices of the dual graph.\n\njulia> qsm_model = literature_model(arxiv_id = \"1903.00009\", model_parameters = Dict(\"k\" => 4))\nHypersurface model over a concrete base\n\njulia> genera_of_components_of_dual_graph(qsm_model)[\"C28-1\"]\n0\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/literature/","page":"Literature constructions","title":"Literature constructions","text":"The dual graph is essential in counting root bundles (cf. [BCL21]). It turns out, that one can simplify this graph so that the computations at hand can be conducted on a simpler graph instead. The following functionality exists to access this simplified dual graph.","category":"page"},{"location":"Experimental/FTheoryTools/literature/","page":"Literature constructions","title":"Literature constructions","text":"simplified_dual_graph(m::AbstractFTheoryModel)\ncomponents_of_simplified_dual_graph(m::AbstractFTheoryModel)\ndegrees_of_kbar_restrictions_to_components_of_simplified_dual_graph(m::AbstractFTheoryModel)\ngenera_of_components_of_simplified_dual_graph(m::AbstractFTheoryModel)","category":"page"},{"location":"Experimental/FTheoryTools/literature/#simplified_dual_graph-Tuple{AbstractFTheoryModel}","page":"Literature constructions","title":"simplified_dual_graph","text":"simplified_dual_graph(m::AbstractFTheoryModel)\n\nThis method returns the simplified dual graph of the QSM model in question. Note that no labels are (currently) attached to the vertices/nodes or edges. To understand/read this graph correctly, please use the methods listed below.\n\njulia> qsm_model = literature_model(arxiv_id = \"1903.00009\", model_parameters = Dict(\"k\" => 4))\nHypersurface model over a concrete base\n\njulia> simplified_dual_graph(qsm_model)\nUndirected graph with 4 nodes and the following edges:\n(2, 1)(3, 1)(3, 2)(4, 1)(4, 2)(4, 3)\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/literature/#components_of_simplified_dual_graph-Tuple{AbstractFTheoryModel}","page":"Literature constructions","title":"components_of_simplified_dual_graph","text":"components_of_simplified_dual_graph(m::AbstractFTheoryModel)\n\nThis method returns a vector with labels for each node/vertex of the simplified dual graph. Otherwise, works identical to components_of_dual_graph(m::AbstractFTheoryModel).\n\njulia> qsm_model = literature_model(arxiv_id = \"1903.00009\", model_parameters = Dict(\"k\" => 4))\nHypersurface model over a concrete base\n\njulia> components_of_simplified_dual_graph(qsm_model)\n4-element Vector{String}:\n \"C0\"\n \"C1\"\n \"C2\"\n \"C3\"\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/literature/#degrees_of_kbar_restrictions_to_components_of_simplified_dual_graph-Tuple{AbstractFTheoryModel}","page":"Literature constructions","title":"degrees_of_kbar_restrictions_to_components_of_simplified_dual_graph","text":"degrees_of_kbar_restrictions_to_components_of_simplified_dual_graph(m::AbstractFTheoryModel)\n\nSame as degrees_of_kbar_restrictions_to_components_of_dual_graph(m::AbstractFTheoryModel), but for the simplified dual graph.\n\njulia> qsm_model = literature_model(arxiv_id = \"1903.00009\", model_parameters = Dict(\"k\" => 4))\nHypersurface model over a concrete base\n\njulia> degrees_of_kbar_restrictions_to_components_of_simplified_dual_graph(qsm_model)[\"C2\"]\n2\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Experimental/FTheoryTools/literature/#genera_of_components_of_simplified_dual_graph-Tuple{AbstractFTheoryModel}","page":"Literature constructions","title":"genera_of_components_of_simplified_dual_graph","text":"genera_of_components_of_simplified_dual_graph(m::AbstractFTheoryModel)\n\nThis methods returns a vector with the genera of the (geometric counterparts of the) nodes/vertices of the dual graph.\n\njulia> qsm_model = literature_model(arxiv_id = \"1903.00009\", model_parameters = Dict(\"k\" => 4))\nHypersurface model over a concrete base\n\njulia> genera_of_components_of_simplified_dual_graph(qsm_model)[\"C2\"]\n0\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"Groups/group_characters/","page":"Group characters","title":"Group characters","text":"CurrentModule = Oscar\nDocTestSetup = Oscar.doctestsetup()","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 the Atlas of Finite Groups [CCNPW85] and from the Atlas of Brauer Characters [JLPW95] are available in OSCAR. Such character tables can be fetched with character_table(id::String, p::Int = 0) from the database, via their names. Moreover, the library of character tables can be used similar to group libraries (see Group libraries) in the sense that all_character_table_names returns descriptions of all those available character tables that have certain properties.","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":"The character table to which a character chi belongs can be fetched as parent(chi).","category":"page"},{"location":"Groups/group_characters/","page":"Group characters","title":"Group characters","text":"GAPGroupCharacterTable\ncharacter_table(G::Union{GAPGroup, FinGenAbGroup}, p::T = 0) where T <: IntegerUnion\ncharacter_table(id::String, p::Int = 0)\ncharacter_table(series::Symbol, parameter::Union{Int, Vector{Int}})\nBase.show(io::IO, ::MIME\"text/plain\", tbl::GAPGroupCharacterTable)\ncharacteristic(tbl::GAPGroupCharacterTable)\nBase.mod(tbl::GAPGroupCharacterTable, p::Int)\nquo(tbl::GAPGroupCharacterTable, nclasses::Vector{Int})\nall_character_table_names\nis_character_table_name","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-Union{Tuple{Union{FinGenAbGroup, Oscar.GAPGroup}}, Tuple{T}, Tuple{Union{FinGenAbGroup, Oscar.GAPGroup}, T}} where T<:Union{Integer, ZZRingElem}","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;\nCharacter table of Sym(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;\n2-modular Brauer table of Sym(3)\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\n","category":"method"},{"location":"Groups/group_characters/#character_table","page":"Group characters","title":"character_table","text":"character_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\nSeveral names can be admissible for the same character table from the library. For example, the alternating group on five points is isomorphic to the projective special linear groups in dimension 2 over the fields with four or five elements, and each of the strings \"A5\", \"L2(4)\", \"L2(5)\" is an admissible name for its library character table. The names are not case sensitive, thus also \"a5\" is admissible.\n\nUse all_character_table_names for creating a vector that contains one admissible name for each available character table, perhaps filtered by some conditions.\n\n\n\n\n\n","category":"function"},{"location":"Groups/group_characters/#character_table-Tuple{Symbol, Union{Int64, Vector{Int64}}}","page":"Group characters","title":"character_table","text":"character_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\") vector [p, q] with prime p and q dividing p-1\n:ExtraspecialPlusOdd odd power of odd prime\n\n\n\n\n\n","category":"method"},{"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;\nC3\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/#quo-Tuple{Oscar.GAPGroupCharacterTable, Vector{Int64}}","page":"Group characters","title":"quo","text":"quo(tbl::GAPGroupCharacterTable, nclasses::Vector{Int})\n\nReturn the pair (fact, proj) where fact is the character table of the factor of tbl modulo the normal subgroup that is the normal closure of the conjugacy classes whose positions are listed in nclasses, and proj is the class fusion from tbl to fact.\n\nExamples\n\njulia> t = character_table(\"2.A5\");\n\njulia> n = class_positions_of_center(t); println(n)\n[1, 2]\n\njulia> fact, proj = quo(t, n);\n\njulia> order(fact)\n60\n\njulia> println(proj)\n[1, 1, 2, 3, 3, 4, 4, 5, 5]\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 a vector of strings that contains an admissible name of each character table in the character table library that satisfies the conditions in the vector 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_of_conjugacy_classes => 1))\n1\n\n\n\n\n\n","category":"function"},{"location":"Groups/group_characters/#is_character_table_name","page":"Group characters","title":"is_character_table_name","text":"is_character_table_name(name::String)\n\nReturn true if character_table(name) returns a character table, and false otherwise\n\nExamples\n\njulia> is_character_table_name(\"J1\")\ntrue\n\njulia> is_character_table_name(\"J5\")\nfalse\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\nconductor(chi::GAPGroupClassFunction)\nconj(chi::GAPGroupClassFunction)\nNemo.degree(chi::GAPGroupClassFunction)\ngalois_orbit_sum\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/#conductor-Tuple{Oscar.GAPGroupClassFunction}","page":"Group characters","title":"conductor","text":"conductor(::Type{T} = ZZRingElem, chi::GAPGroupClassFunction)\n where T <: IntegerUnion\n\nReturn the minimal integer n, as an instance of T, such that all values of chi lie in the n-th cyclotomic field.\n\nExamples\n\njulia> tbl = character_table(\"A5\");\n\njulia> println([conductor(chi) for chi in tbl])\nZZRingElem[1, 5, 5, 1, 1]\n\n\n\n\n\n","category":"method"},{"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(==(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, QQFieldElem, QQAbFieldElem}\n\nReturn chi[1], as an instance of T.\n\n\n\n\n\n","category":"method"},{"location":"Groups/group_characters/#galois_orbit_sum","page":"Group characters","title":"galois_orbit_sum","text":"galois_orbit_sum(chi::GAPGroupClassFunction)\n\nReturn a class function psi. If chi is an ordinary character then psi is the sum of all different Galois conjugates of chi; the values of psi are rationals. If chi is a Brauer character then psi is the sum of all different images of chi under powers of the Frobenius automorphism; thus psi is afforded by a representation over the prime field, but the values of psi need not be rationals.\n\nExamples\n\njulia> t = character_table(\"A5\");\n\njulia> println([degree(character_field(x)[1]) for x in t])\n[1, 2, 2, 1, 1]\n\njulia> println([degree(character_field(galois_orbit_sum(x))[1]) for x in t])\n[1, 1, 1, 1, 1]\n\n\n\n\n\n","category":"function"},{"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":"block_distribution\ncharacter_parameters\nclass_names(tbl::GAPGroupCharacterTable)\nclass_parameters\nconjugacy_classes(tbl::GAPGroupCharacterTable)\ndecomposition_matrix\nidentifier(tbl::GAPGroupCharacterTable)\ninduced_cyclic(tbl::GAPGroupCharacterTable)\nis_duplicate_table\nmaxes\nnames_of_fusion_sources\nclass_lengths(tbl::GAPGroupCharacterTable)\norders_centralizers\norders_class_representatives(tbl::GAPGroupCharacterTable)\nordinary_table(tbl::GAPGroupCharacterTable)\ntrivial_character(tbl::GAPGroupCharacterTable)\nregular_character(tbl::GAPGroupCharacterTable)\nlinear_characters(tbl::GAPGroupCharacterTable)","category":"page"},{"location":"Groups/group_characters/#block_distribution","page":"Group characters","title":"block_distribution","text":"block_distribution(tbl::GAPGroupCharacterTable, p::IntegerUnion)\n\nReturn a dictionary with the keys :defect (the vector containing at position i the defect of the i-th p-block of tbl) and :block (the vector containing at position i the number j such that tbl[i] belongs to the j-th p-block).\n\nAn exception is thrown if tbl is not an ordinary character table.\n\nExamples\n\njulia> block_distribution(character_table(\"A5\"), 2)\nDict{Symbol, Vector{Int64}} with 2 entries:\n :block => [1, 1, 1, 2, 1]\n :defect => [2, 0]\n\n\n\n\n\n","category":"function"},{"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.\n\nNote that the vectors conjugacy_classes(group(tbl)) and conjugacy_classes(tbl) are independent. They will usually have the same ordering, but it may happen that they are ordered differently.\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-Tuple{Oscar.GAPGroupCharacterTable}","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":"method"},{"location":"Groups/group_characters/#induced_cyclic-Tuple{Oscar.GAPGroupCharacterTable}","page":"Group characters","title":"induced_cyclic","text":"induced_cyclic(tbl::GAPGroupCharacterTable, classes::AbstractVector{Int} = 1:nrows(tbl))\n\nReturn the vector of permutation characters of tbl that are induced from cyclic subgroups. If classes is given then only the cyclic subgroups generated by elements in the classes at positions in this vector are returned.\n\nExamples\n\njulia> t = character_table(\"A5\");\n\njulia> ind = induced_cyclic(t);\n\njulia> all(x -> scalar_product(x, t[1]) == 1, ind)\ntrue\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 a vector 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 vector 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(in(names_of_fusion_sources(tbl)), maxes(tbl))\ntrue\n\n\n\n\n\n","category":"function"},{"location":"Groups/group_characters/#class_lengths-Tuple{Oscar.GAPGroupCharacterTable}","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":"method"},{"location":"Groups/group_characters/#orders_centralizers","page":"Group characters","title":"orders_centralizers","text":"orders_centralizers(tbl::GAPGroupCharacterTable)\n\nReturn the vector 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-Tuple{Oscar.GAPGroupCharacterTable}","page":"Group characters","title":"orders_class_representatives","text":"orders_class_representatives(tbl::GAPGroupCharacterTable)\n\nReturn the vector 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":"method"},{"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 QQAbFieldElem(1) in each position.\n\nExamples\n\njulia> t = character_table(symmetric_group(4));\n\njulia> all(==(1), trivial_character(t))\ntrue\n\n\n\n\n\n","category":"method"},{"location":"Groups/group_characters/#regular_character-Tuple{Oscar.GAPGroupCharacterTable}","page":"Group characters","title":"regular_character","text":"regular_character(tbl::GAPGroupCharacterTable)\n\nReturn the regular character of tbl.\n\nExamples\n\njulia> tbl = character_table(symmetric_group(3));\n\njulia> values(regular_character(tbl))\n3-element Vector{QQAbFieldElem{AbsSimpleNumFieldElem}}:\n 6\n 0\n 0\n\n\n\n\n\n","category":"method"},{"location":"Groups/group_characters/#linear_characters-Tuple{Oscar.GAPGroupCharacterTable}","page":"Group characters","title":"linear_characters","text":"linear_characters(tbl::GAPGroupCharacterTable)\n\nReturn the array of linear characters of tbl, that is, the characters of degree 1.\n\nExamples\n\njulia> tbl = character_table(symmetric_group(3));\n\njulia> length(linear_characters(tbl))\n2\n\n\n\n\n\n","category":"method"},{"location":"Groups/group_characters/","page":"Group characters","title":"Group characters","text":"The following properties of a group can be read off from its character table. Therefore it is supported to call these functions with a character table.","category":"page"},{"location":"Groups/group_characters/","page":"Group characters","title":"Group characters","text":"is_abelian(tbl::GAPGroupCharacterTable)\nis_almost_simple(tbl::GAPGroupCharacterTable)\nis_cyclic(tbl::GAPGroupCharacterTable)\nis_elementary_abelian(tbl::GAPGroupCharacterTable)\nis_nilpotent(tbl::GAPGroupCharacterTable)\nis_perfect(tbl::GAPGroupCharacterTable)\nis_quasisimple(tbl::GAPGroupCharacterTable)\nis_simple(tbl::GAPGroupCharacterTable)\nis_solvable(tbl::GAPGroupCharacterTable)\nis_sporadic_simple(tbl::GAPGroupCharacterTable)\nis_supersolvable(tbl::GAPGroupCharacterTable)","category":"page"},{"location":"Groups/group_characters/#is_abelian-Tuple{Oscar.GAPGroupCharacterTable}","page":"Group characters","title":"is_abelian","text":"is_abelian(tbl::GAPGroupCharacterTable)\n\nReturn whether tbl is the ordinary character table of an abelian group, see is_abelian(G::GAPGroup).\n\nExamples\n\njulia> is_abelian(character_table(\"A5\"))\nfalse\n\njulia> is_abelian(character_table(\"C2\"))\ntrue\n\n\n\n\n\n","category":"method"},{"location":"Groups/group_characters/#is_almost_simple-Tuple{Oscar.GAPGroupCharacterTable}","page":"Group characters","title":"is_almost_simple","text":"is_almost_simple(tbl::GAPGroupCharacterTable)\n\nReturn whether tbl is the ordinary character table of an almost simple group, see is_almost_simple(G::GAPGroup).\n\nExamples\n\njulia> is_almost_simple(character_table(\"S5\"))\ntrue\n\njulia> is_almost_simple(character_table(\"S4\"))\nfalse\n\n\n\n\n\n","category":"method"},{"location":"Groups/group_characters/#is_cyclic-Tuple{Oscar.GAPGroupCharacterTable}","page":"Group characters","title":"is_cyclic","text":"is_cyclic(tbl::GAPGroupCharacterTable)\n\nReturn whether tbl is the ordinary character table of a cyclic group, see is_cyclic(G::GAPGroup).\n\nExamples\n\njulia> is_cyclic(character_table(\"C2\"))\ntrue\n\njulia> is_cyclic(character_table(\"S4\"))\nfalse\n\n\n\n\n\n","category":"method"},{"location":"Groups/group_characters/#is_elementary_abelian-Tuple{Oscar.GAPGroupCharacterTable}","page":"Group characters","title":"is_elementary_abelian","text":"is_elementary_abelian(tbl::GAPGroupCharacterTable)\n\nReturn whether tbl is the ordinary character table of an elementary abelian group, see is_elementary_abelian(G::GAPGroup).\n\nExamples\n\njulia> is_elementary_abelian(character_table(\"C2\"))\ntrue\n\njulia> is_elementary_abelian(character_table(\"S4\"))\nfalse\n\n\n\n\n\n","category":"method"},{"location":"Groups/group_characters/#is_nilpotent-Tuple{Oscar.GAPGroupCharacterTable}","page":"Group characters","title":"is_nilpotent","text":"is_nilpotent(tbl::GAPGroupCharacterTable)\n\nReturn whether tbl is the ordinary character table of a nilpotent group, see is_nilpotent(G::GAPGroup).\n\nExamples\n\njulia> is_nilpotent(character_table(\"C2\"))\ntrue\n\njulia> is_nilpotent(character_table(\"S4\"))\nfalse\n\n\n\n\n\n","category":"method"},{"location":"Groups/group_characters/#is_perfect-Tuple{Oscar.GAPGroupCharacterTable}","page":"Group characters","title":"is_perfect","text":"is_perfect(tbl::GAPGroupCharacterTable)\n\nReturn whether tbl is the ordinary character table of a perfect group, see is_perfect(G::GAPGroup).\n\nExamples\n\njulia> is_perfect(character_table(\"A5\"))\ntrue\n\njulia> is_perfect(character_table(\"S4\"))\nfalse\n\n\n\n\n\n","category":"method"},{"location":"Groups/group_characters/#is_quasisimple-Tuple{Oscar.GAPGroupCharacterTable}","page":"Group characters","title":"is_quasisimple","text":"is_quasisimple(tbl::GAPGroupCharacterTable)\n\nReturn whether tbl is the ordinary character table of a quasisimple group, see is_quasisimple(G::GAPGroup).\n\nExamples\n\njulia> is_quasisimple(character_table(\"A5\"))\ntrue\n\njulia> is_quasisimple(character_table(\"S4\"))\nfalse\n\n\n\n\n\n","category":"method"},{"location":"Groups/group_characters/#is_simple-Tuple{Oscar.GAPGroupCharacterTable}","page":"Group characters","title":"is_simple","text":"is_simple(tbl::GAPGroupCharacterTable)\n\nReturn whether tbl is the ordinary character table of a simple group, see is_simple(G::GAPGroup).\n\nExamples\n\njulia> is_simple(character_table(\"A5\"))\ntrue\n\njulia> is_simple(character_table(\"S4\"))\nfalse\n\n\n\n\n\n","category":"method"},{"location":"Groups/group_characters/#is_solvable-Tuple{Oscar.GAPGroupCharacterTable}","page":"Group characters","title":"is_solvable","text":"is_solvable(tbl::GAPGroupCharacterTable)\n\nReturn whether tbl is the ordinary character table of a solvable group, see is_solvable(G::GAPGroup).\n\nExamples\n\njulia> is_solvable(character_table(\"A5\"))\nfalse\n\njulia> is_solvable(character_table(\"S4\"))\ntrue\n\n\n\n\n\n","category":"method"},{"location":"Groups/group_characters/#is_sporadic_simple-Tuple{Oscar.GAPGroupCharacterTable}","page":"Group characters","title":"is_sporadic_simple","text":"is_sporadic_simple(tbl::GAPGroupCharacterTable)\n\nReturn whether tbl is the ordinary character table of a sporadic simple group, see is_sporadic_simple(G::GAPGroup).\n\nExamples\n\njulia> is_sporadic_simple(character_table(\"A5\"))\nfalse\n\njulia> is_sporadic_simple(character_table(\"M11\"))\ntrue\n\n\n\n\n\n","category":"method"},{"location":"Groups/group_characters/#is_supersolvable-Tuple{Oscar.GAPGroupCharacterTable}","page":"Group characters","title":"is_supersolvable","text":"is_supersolvable(tbl::GAPGroupCharacterTable)\n\nReturn whether tbl is the ordinary character table of a supersolvable group, see is_supersolvable(G::GAPGroup).\n\nExamples\n\njulia> is_supersolvable(character_table(\"A5\"))\nfalse\n\njulia> is_supersolvable(character_table(\"S3\"))\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":"linear_characters(G::GAPGroup)\nnatural_character(G::PermGroup)\nnatural_character(G::Union{MatrixGroup{QQFieldElem}, MatrixGroup{AbsSimpleNumFieldElem}})\nnatural_character(G::MatrixGroup{T, MT}) where T <: FinFieldElem where MT\nnatural_character(rho::GAPGroupHomomorphism)\ntrivial_character(G::GAPGroup)\nregular_character(G::GAPGroup)","category":"page"},{"location":"Groups/group_characters/#linear_characters-Tuple{Oscar.GAPGroup}","page":"Group characters","title":"linear_characters","text":"linear_characters(G::Union{GAPGroup, FinGenAbGroup})\n\nReturn the array of linear characters of G, that is, the characters of degree 1.\n\nExamples\n\njulia> G = symmetric_group(3);\n\njulia> length(linear_characters(G))\n2\n\n\n\n\n\n","category":"method"},{"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{AbsSimpleNumFieldElem, T} where T<:MatElem{AbsSimpleNumFieldElem}, MatrixGroup{QQFieldElem, T} where T<:MatElem{QQFieldElem}}}","page":"Group characters","title":"natural_character","text":"natural_character(G::Union{MatrixGroup{QQFieldElem}, MatrixGroup{AbsSimpleNumFieldElem}})\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)))\nQQAbFieldElem{AbsSimpleNumFieldElem}[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)))\nQQAbFieldElem{AbsSimpleNumFieldElem}[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)))\nQQAbFieldElem{AbsSimpleNumFieldElem}[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)))\nQQAbFieldElem{AbsSimpleNumFieldElem}[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 QQAbFieldElem(1) in each position.\n\nExamples\n\njulia> g = symmetric_group(4);\n\njulia> all(==(1), trivial_character(g))\ntrue\n\n\n\n\n\n","category":"method"},{"location":"Groups/group_characters/#regular_character-Tuple{Oscar.GAPGroup}","page":"Group characters","title":"regular_character","text":"regular_character(G::GAPGroup)\n\nReturn the regular character of G.\n\nExamples\n\njulia> G = symmetric_group(3);\n\njulia> values(regular_character(G))\n3-element Vector{QQAbFieldElem{AbsSimpleNumFieldElem}}:\n 6\n 0\n 0\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(chi::GAPGroupClassFunction, psi::GAPGroupClassFunction)\ntensor_product(chi::GAPGroupClassFunction, psi::GAPGroupClassFunction)\ncoordinates(chi::GAPGroupClassFunction)\nmultiplicities_eigenvalues\ninduce(chi::GAPGroupClassFunction, tbl::GAPGroupCharacterTable)\nrestrict(chi::GAPGroupClassFunction, subtbl::GAPGroupCharacterTable)","category":"page"},{"location":"Groups/group_characters/#scalar_product-Tuple{Oscar.GAPGroupClassFunction, Oscar.GAPGroupClassFunction}","page":"Group characters","title":"scalar_product","text":"scalar_product(::Type{T} = QQFieldElem, chi::GAPGroupClassFunction, psi::GAPGroupClassFunction)\n where T <: Union{IntegerUnion, ZZRingElem, QQFieldElem, QQAbFieldElem}\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":"method"},{"location":"Groups/group_characters/#tensor_product-Tuple{Oscar.GAPGroupClassFunction, Oscar.GAPGroupClassFunction}","page":"Group characters","title":"tensor_product","text":"tensor_product(chi::GAPGroupClassFunction, psi::GAPGroupClassFunction)\n\nReturn the pointwise product of chi and psi. The resulting character is afforded by the tensor product of representations corresponding to chi and psi, hence the name.\n\nAlias for chi * psi.\n\n\n\n\n\n","category":"method"},{"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, QQAbFieldElem}\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(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 = parent(chi); 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))\nQQAbFieldElem{AbsSimpleNumFieldElem}[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, G::Union{GAPGroup, FinGenAbGroup})\ninduce(chi::GAPGroupClassFunction, tbl::GAPGroupCharacterTable[, fusion::Vector{Int}])\n\nReturn the class function of G or tbl that is induced from chi, which is a class function of a subgroup of G or 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\nThe syntax chi^tbl and chi^G is also supported.\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, H::Union{GAPGroup, FinGenAbGroup})\nrestrict(chi::GAPGroupClassFunction, subtbl::GAPGroupCharacterTable[, fusion::Vector{Int}])\n\nReturn the class function of H or subtbl that is the restriction of chi, which is a class function of a supergroup of H or 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\nknown_class_fusions\norder(tbl::GAPGroupCharacterTable)\npossible_class_fusions\napproximate_class_fusion","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\nExamples\n\njulia> t1 = character_table(\"A5\"); t2 = character_table(\"A6\");\n\njulia> known_class_fusion(t1, t2)\n(true, [1, 2, 3, 6, 7])\n\njulia> known_class_fusion(t2, t1)\n(false, Int64[])\n\n\n\n\n\n","category":"function"},{"location":"Groups/group_characters/#known_class_fusions","page":"Group characters","title":"known_class_fusions","text":"known_class_fusions(tbl::GAPGroupCharacterTable)\n\nReturn the vector of pairs (name, fus) where name is the identifier of a character table and fus is the stored class fusion from tbl to this table, see known_class_fusion.\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,\n tbl::GAPGroupCharacterTable;\n decompose::Bool = true,\n fusionmap::Vector = [])\n\nReturn the vector of possible class fusions from subtbl to tbl. Each entry is an vector 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\nIf decompose is set to true then the strategy is changed: The decomposability of restricted characters of tbl as integral linear combinations of characters of subtbl (with perhaps negative coefficients) is not checked; this does not change the result, but in certain situations it is faster to omit this step.\n\nIf fusionmap is set to a vector of integers and integer vectors then only those maps are returned that are compatible with the prescribed value.\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/#approximate_class_fusion","page":"Group characters","title":"approximate_class_fusion","text":"approximate_class_fusion(subtbl::GAPGroupCharacterTable,\n tbl::GAPGroupCharacterTable)\n\nCompute for each class of subtbl all those classes in tbl to which it can fuse under an embedding of the group of subtbl into the group of tbl, according to element orders and centralizer orders in the two tables.\n\nIf no embedding is possible then return an empty vector. Otherwise return a vector of length equal to the number of classes of subtbl, such that the entry at position i either an integer (if there is a unique possible image class) or the vector of the positions of possible image classes.\n\nExamples\n\njulia> subtbl = character_table(\"A5\"); tbl = character_table(\"A6\");\n\njulia> println(approximate_class_fusion(subtbl, tbl))\nUnion{Int64, Vector{Int64}}[1, 2, [3, 4], [6, 7], [6, 7]]\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(chi::GAPGroupCharacterTable)\nclass_positions_of_center(chi::GAPGroupClassFunction)\nclass_positions_of_derived_subgroup\nkernel(chi::GAPGroupClassFunction)\nclass_positions_of_kernel\nclass_positions_of_normal_subgroups\npcore(tbl::GAPGroupCharacterTable, p::IntegerUnion)\nclass_positions_of_pcore\nclass_positions_of_solvable_residuum","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-Tuple{Oscar.GAPGroupCharacterTable}","page":"Group characters","title":"class_positions_of_center","text":"class_positions_of_center(tbl::GAPGroupCharacterTable)\n\nReturn the vector of integers i such that the i-th conjugacy class of tbl is contained in the center of the group G of tbl, i.e., the i-th class has length 1.\n\nExamples\n\njulia> tbl = character_table(dihedral_group(8));\n\njulia> println(class_positions_of_center(tbl))\n[1, 4]\n\n\n\n\n\n","category":"method"},{"location":"Groups/group_characters/#class_positions_of_center-Tuple{Oscar.GAPGroupClassFunction}","page":"Group characters","title":"class_positions_of_center","text":"class_positions_of_center(chi::GAPGroupClassFunction)\n\nReturn the vector 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":"method"},{"location":"Groups/group_characters/#class_positions_of_derived_subgroup","page":"Group characters","title":"class_positions_of_derived_subgroup","text":"class_positions_of_derived_subgroup(tbl::GAPGroupCharacterTable)\n\nReturn the vector of integers i such that the i-th conjugacy class of tbl is contained in the derived subgroup of the group G of tbl.\n\nExamples\n\njulia> tbl = character_table(dihedral_group(8));\n\njulia> println(class_positions_of_derived_subgroup(tbl))\n[1, 4]\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 vector 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/#class_positions_of_normal_subgroups","page":"Group characters","title":"class_positions_of_normal_subgroups","text":"class_positions_of_normal_subgroups(tbl::GAPGroupCharacterTable)\n\nReturn a vector whose entries describe all normal subgroups of the group of tbl. Each entry is a vector of those class positions such that the union of these classes forms a normal subgroup.\n\nExamples\n\njulia> t = character_table(\"2.A5\");\n\njulia> class_positions_of_normal_subgroups(t)\n3-element Vector{Vector{Int64}}:\n [1]\n [1, 2]\n [1, 2, 3, 4, 5, 6, 7, 8, 9]\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 vector 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":"Groups/group_characters/#class_positions_of_solvable_residuum","page":"Group characters","title":"class_positions_of_solvable_residuum","text":"class_positions_of_solvable_residuum(tbl::GAPGroupCharacterTable)\n\nReturn the vector of integers i such that the i-th conjugacy class of tbl is contained in the solvable residuum of the group G of tbl, i.e., the smallest normal subgroup N of G such that the factor group GN is solvable. This normal subgroup is equal to the last term of the derived series of G, see derived_series.\n\nExamples\n\njulia> tbl = character_table(symmetric_group(4));\n\njulia> println(class_positions_of_solvable_residuum(tbl))\n[1]\n\n\n\n\n\n","category":"function"},{"location":"InvariantTheory/tori/","page":"Invariants of Tori","title":"Invariants of Tori","text":"CurrentModule = Oscar","category":"page"},{"location":"InvariantTheory/tori/#Invariants-of-Tori","page":"Invariants of Tori","title":"Invariants of Tori","text":"","category":"section"},{"location":"InvariantTheory/tori/","page":"Invariants of Tori","title":"Invariants of Tori","text":"In this section, with notation as in the introduction to this chapter, T =(K^ast)^m will be a torus of rank m over a field K. To compute invariants of diagonal torus actions, OSCAR makes use of Algorithm 4.3.1 in [DK15] which, in particular, relies on algorithmic means from polyhedral geometry.","category":"page"},{"location":"InvariantTheory/tori/#Creating-Invariant-Rings","page":"Invariants of Tori","title":"Creating Invariant Rings","text":"","category":"section"},{"location":"InvariantTheory/tori/#How-Tori-and-Their-Representations-are-Given","page":"Invariants of Tori","title":"How Tori and Their Representations are Given","text":"","category":"section"},{"location":"InvariantTheory/tori/","page":"Invariants of Tori","title":"Invariants of Tori","text":" torus_group(F::Field, n::Int)","category":"page"},{"location":"InvariantTheory/tori/#torus_group-Tuple{Field, Int64}","page":"Invariants of Tori","title":"torus_group","text":"torus_group(K::Field, m::Int)\n\nReturn the torus (K^ast)^m.\n\nnote: Note\nIn the context of computing invariant rings, there is no need to deal with the group structure of a torus: The torus (K^ast)^m is specified by just giving K and m.\n\nExamples\n\njulia> T = torus_group(QQ,2)\nTorus of rank 2\n over QQ\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"InvariantTheory/tori/","page":"Invariants of Tori","title":"Invariants of Tori","text":"rank(T::TorusGroup)","category":"page"},{"location":"InvariantTheory/tori/#rank-Tuple{Oscar.TorusGroup}","page":"Invariants of Tori","title":"rank","text":"rank(T::TorusGroup)\n\nReturn the rank of T.\n\nExamples\n\njulia> T = torus_group(QQ,2);\n\njulia> rank(T)\n2\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"InvariantTheory/tori/","page":"Invariants of Tori","title":"Invariants of Tori","text":"field(T::TorusGroup)","category":"page"},{"location":"InvariantTheory/tori/#field-Tuple{Oscar.TorusGroup}","page":"Invariants of Tori","title":"field","text":"field(T::TorusGroup)\n\nReturn the field over which T is defined.\n\nExamples\n\njulia> T = torus_group(QQ,2);\n\njulia> field(T)\nRational field\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"InvariantTheory/tori/","page":"Invariants of Tori","title":"Invariants of Tori","text":"representation_from_weights(T::TorusGroup, W::Union{ZZMatrix, Matrix{<:Integer}, Vector{<:Int}})","category":"page"},{"location":"InvariantTheory/tori/#representation_from_weights-Tuple{Oscar.TorusGroup, Union{ZZMatrix, Matrix{<:Integer}, Vector{<:Int64}}}","page":"Invariants of Tori","title":"representation_from_weights","text":"representation_from_weights(T::TorusGroup, W::Union{ZZMatrix, Matrix{<:Integer}, Vector{<:Int}})\n\nReturn the diagonal action of T with weights given by W.\n\nExamples\n\njulia> T = torus_group(QQ,2);\n\njulia> r = representation_from_weights(T, [-1 1; -1 1; 2 -2; 0 -1])\nRepresentation of torus of rank 2\n over QQ and weights \n Vector{ZZRingElem}[[-1, 1], [-1, 1], [2, -2], [0, -1]]\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"InvariantTheory/tori/","page":"Invariants of Tori","title":"Invariants of Tori","text":"group(r::RepresentationTorusGroup)","category":"page"},{"location":"InvariantTheory/tori/#group-Tuple{Oscar.RepresentationTorusGroup}","page":"Invariants of Tori","title":"group","text":"group(r::RepresentationTorusGroup)\n\nReturn the torus group represented by r.\n\nExamples\n\njulia> T = torus_group(QQ,2);\n\njulia> r = representation_from_weights(T, [-1 1; -1 1; 2 -2; 0 -1]);\n\njulia> group(r)\nTorus of rank 2\n over QQ\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"InvariantTheory/tori/#Constructor-for-Invariant-Rings","page":"Invariants of Tori","title":"Constructor for Invariant Rings","text":"","category":"section"},{"location":"InvariantTheory/tori/","page":"Invariants of Tori","title":"Invariants of Tori","text":"invariant_ring(r::RepresentationTorusGroup)","category":"page"},{"location":"InvariantTheory/tori/#invariant_ring-Tuple{Oscar.RepresentationTorusGroup}","page":"Invariants of Tori","title":"invariant_ring","text":"invariant_ring(r::RepresentationTorusGroup)\n\nReturn the invariant ring of the torus group represented by r.\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 fundamental_invariants function).\n\nExamples\n\njulia> T = torus_group(QQ,2);\n\njulia> r = representation_from_weights(T, [-1 1; -1 1; 2 -2; 0 -1]);\n\njulia> RT = invariant_ring(r)\nInvariant Ring of\ngraded multivariate polynomial ring in 4 variables over QQ under group action of torus of rank2\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"InvariantTheory/tori/#Fundamental-Systems-of-Invariants","page":"Invariants of Tori","title":"Fundamental Systems of Invariants","text":"","category":"section"},{"location":"InvariantTheory/tori/","page":"Invariants of Tori","title":"Invariants of Tori","text":"fundamental_invariants(RT::TorGroupInvarRing)","category":"page"},{"location":"InvariantTheory/tori/#fundamental_invariants-Tuple{Oscar.TorGroupInvarRing}","page":"Invariants of Tori","title":"fundamental_invariants","text":"fundamental_invariants(RT::TorGroupInvarRing)\n\nReturn a system of fundamental invariants for RT.\n\nExamples\n\njulia> T = torus_group(QQ,2);\n\njulia> r = representation_from_weights(T, [-1 1; -1 1; 2 -2; 0 -1]);\n\njulia> RT = invariant_ring(r);\n\njulia> fundamental_invariants(RT)\n3-element Vector{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}:\n X[1]^2*X[3]\n X[1]*X[2]*X[3]\n X[2]^2*X[3]\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"InvariantTheory/tori/#Invariant-Rings-as-Affine-Algebras","page":"Invariants of Tori","title":"Invariant Rings as Affine Algebras","text":"","category":"section"},{"location":"InvariantTheory/tori/","page":"Invariants of Tori","title":"Invariants of Tori","text":"affine_algebra(RT::TorGroupInvarRing)","category":"page"},{"location":"InvariantTheory/tori/#affine_algebra-Tuple{Oscar.TorGroupInvarRing}","page":"Invariants of Tori","title":"affine_algebra","text":"affine_algebra(RT::TorGroupInvarRing)\n\nReturn the invariant ring RT as an affine algebra (this amounts to compute the algebra syzygies among the fundamental invariants of RT).\n\nIn addition, if A is this algebra, and R is the polynomial ring of which RT is a subalgebra, return the inclusion homomorphism A hookrightarrow R whose image is RT.\n\nExamples\n\njulia> T = torus_group(QQ,2);\n\njulia> r = representation_from_weights(T, [-1 1; -1 1; 2 -2; 0 -1]);\n\njulia> RT = invariant_ring(r);\n\njulia> fundamental_invariants(RT)\n3-element Vector{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}:\n X[1]^2*X[3]\n X[1]*X[2]*X[3]\n X[2]^2*X[3]\n\njulia> affine_algebra(RT)\n(Quotient of multivariate polynomial ring by ideal (-t[1]*t[3] + t[2]^2), Hom: quotient of multivariate polynomial ring -> graded multivariate polynomial ring)\n\nwarning: Experimental\nThis function is part of the experimental code in Oscar. Please read here for more details.\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/homological_algebra/","page":"Homological Algebra","title":"Homological Algebra","text":"CurrentModule = Oscar\nDocTestSetup = Oscar.doctestsetup()","category":"page"},{"location":"CommutativeAlgebra/homological_algebra/#Homological-Algebra","page":"Homological Algebra","title":"Homological Algebra","text":"","category":"section"},{"location":"CommutativeAlgebra/homological_algebra/","page":"Homological Algebra","title":"Homological Algebra","text":"Some OSCAR functions which are fundamental to homological algebra such as the kernel function for module homomorphisms and basic functions for handling chain and cochain complexes are discussed in the module section. Building on these functions, we here introduce further OSCAR functionality supporting computations in homological algebra.","category":"page"},{"location":"CommutativeAlgebra/homological_algebra/#Pruning-Modules","page":"Homological Algebra","title":"Pruning Modules","text":"","category":"section"},{"location":"CommutativeAlgebra/homological_algebra/","page":"Homological Algebra","title":"Homological Algebra","text":"prune_with_map(M::ModuleFP)","category":"page"},{"location":"CommutativeAlgebra/homological_algebra/#prune_with_map-Tuple{ModuleFP}","page":"Homological Algebra","title":"prune_with_map","text":"prune_with_map(M::ModuleFP)\n\nIf M is positively graded, return a module N and an isomorphism from N to M such that N is generated by a minimal number of elements.\n\nIf M is not (positively) graded, the function still aims at reducing the number of generators.\n\nExamples\n\njulia> R, (w, x, y, z) = graded_polynomial_ring(QQ, [:w, :x, :y, :z]);\n\njulia> Z = R(0)\n0\n\njulia> O = R(1)\n1\n\njulia> B = [Z Z Z O; w*y w*z-x*y x*z-y^2 Z];\n\njulia> A = transpose(matrix(B))\n[0 w*y]\n[0 w*z - x*y]\n[0 x*z - y^2]\n[1 0]\n\njulia> M = graded_cokernel(A)\nGraded subquotient of submodule of R^2 generated by\n1 -> e[1]\n2 -> e[2]\nby submodule of R^2 generated by\n1 -> w*y*e[2]\n2 -> (w*z - x*y)*e[2]\n3 -> (x*z - y^2)*e[2]\n4 -> e[1]\n\njulia> N, phi = prune_with_map(M);\n\njulia> N\nGraded subquotient of submodule of R^1 generated by\n1 -> e[1]\nby submodule of R^1 generated by\n1 -> (-x*z + y^2)*e[1]\n2 -> (-w*z + x*y)*e[1]\n3 -> w*y*e[1]\n\njulia> phi(first(gens(N)))\ne[2]\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/homological_algebra/#Presentations","page":"Homological Algebra","title":"Presentations","text":"","category":"section"},{"location":"CommutativeAlgebra/homological_algebra/","page":"Homological Algebra","title":"Homological Algebra","text":"presentation(M::ModuleFP)","category":"page"},{"location":"CommutativeAlgebra/homological_algebra/#presentation-Tuple{ModuleFP}","page":"Homological Algebra","title":"presentation","text":"presentation(M::ModuleFP; minimal = false)\n\nReturn a (free) presentation of M. \n\nnote: Note\nIf minimal is true, and M is positively graded, a minimal presentation is returned. If minimal is true, and M is not (positively) graded, the function still aims at returning an ''improved'' presentation.\n\nExamples\n\njulia> R, (w, x, y, z) = graded_polynomial_ring(QQ, [:w, :x, :y, :z]);\n\njulia> Z = R(0)\n0\n\njulia> O = R(1)\n1\n\njulia> B = [Z Z Z O; w*y w*z-x*y x*z-y^2 Z];\n\njulia> A = transpose(matrix(B))\n[0 w*y]\n[0 w*z - x*y]\n[0 x*z - y^2]\n[1 0]\n\njulia> M = graded_cokernel(A)\nGraded subquotient of submodule of R^2 generated by\n1 -> e[1]\n2 -> e[2]\nby submodule of R^2 generated by\n1 -> w*y*e[2]\n2 -> (w*z - x*y)*e[2]\n3 -> (x*z - y^2)*e[2]\n4 -> e[1]\n\njulia> PM1 = presentation(M)\n0 <---- M <---- R^2 <---- R^4\n\njulia> PM2 = presentation(M, minimal = true)\n0 <---- M <---- R^1 <---- R^3\n\n\njulia> Rg, (x, y, z) = graded_polynomial_ring(QQ, [:x, :y, :z]);\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/homological_algebra/#Representation-as-Cokernel","page":"Homological Algebra","title":"Representation as Cokernel","text":"","category":"section"},{"location":"CommutativeAlgebra/homological_algebra/","page":"Homological Algebra","title":"Homological Algebra","text":"present_as_cokernel(M::SubquoModule, task::Symbol = :none)","category":"page"},{"location":"CommutativeAlgebra/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> Rg, (x, y, z) = graded_polynomial_ring(QQ, [: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);\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/homological_algebra/#Free-Resolutions","page":"Homological Algebra","title":"Free Resolutions","text":"","category":"section"},{"location":"CommutativeAlgebra/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/homological_algebra/#free_resolution-Tuple{SubquoModule{<:MPolyRingElem}}","page":"Homological Algebra","title":"free_resolution","text":"free_resolution(M::SubquoModule{T}; \n length::Int=0,\n algorithm::Symbol = T <:MPolyRingElem ? :fres : :sres) where {T <: Union{MPolyRingElem, MPolyQuoRingElem}}\n\nReturn a free resolution of M.\n\nIf length != 0, the free resolution is only computed up to the length-th free module. Current options for algorithm are :fres, :nres, and :mres for modules over polynomial rings and :sres for modules over quotients of polynomial rings.\n\nnote: Note\nThe function first computes a presentation of M. It then successively computes higher syzygy modules.\n\nnote: Note\nIf algorithm == mres, and M is positively graded, a minimal free resolution is returned.\nIf algorithm == nres, and M is positively graded, the function proceeds as above except that it starts by computing a presentation which is not neccessarily minimal.In both cases, if M is not (positively) graded, the function still aims at returning an ''improved'' resolution.\n\nnote: Note\nIf algorithm == fres, the function relies on an enhanced version of Schreyer's algorithm [EMSS16]. Typically, this is more efficient than the approaches above, but the resulting resolution is far from being minimal.\n\nnote: Note\nIf M is a module over a quotient of a polynomial ring then the length keyword must be set to a nonzero value.\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 R\n\njulia> fr\nFree resolution of M\nR^2 <---- R^6 <---- R^6 <---- R^2 <---- 0\n0 1 2 3 4\n\njulia> is_complete(fr)\ntrue\n\njulia> R, (w, x, y, z) = graded_polynomial_ring(QQ, [:w, :x, :y, :z]);\n\njulia> Z = R(0)\n0\n\njulia> O = R(1)\n1\n\njulia> B = [Z Z Z O; w*y w*z-x*y x*z-y^2 Z];\n\njulia> A = transpose(matrix(B));\n\njulia> M = graded_cokernel(A)\nGraded subquotient of submodule of R^2 generated by\n1 -> e[1]\n2 -> e[2]\nby submodule of R^2 generated by\n1 -> w*y*e[2]\n2 -> (w*z - x*y)*e[2]\n3 -> (x*z - y^2)*e[2]\n4 -> e[1]\n\njulia> FM1 = free_resolution(M)\nFree resolution of M\nR^2 <---- R^7 <---- R^8 <---- R^3 <---- 0\n0 1 2 3 4\n\njulia> betti_table(FM1)\n 0 1 2 3\n-----------------\n-1 : - 1 - -\n0 : 2 - - -\n1 : - 3 3 1\n2 : - 3 5 2\n-----------------\ntotal: 2 7 8 3\n\n\njulia> matrix(map(FM1, 1))\n[1 0]\n[0 -x*z + y^2]\n[0 -w*z + x*y]\n[0 w*y]\n[0 x^2*z]\n[0 w*x*z]\n[0 w^2*z]\n\njulia> FM2 = free_resolution(M, algorithm = :nres)\nFree resolution of M\nR^2 <---- R^4 <---- R^4 <---- R^2 <---- 0\n0 1 2 3 4\n\njulia> betti_table(FM2)\n 0 1 2 3\n-----------------\n-1 : - 1 - -\n0 : 2 - - -\n1 : - 3 - -\n2 : - - 4 2\n-----------------\ntotal: 2 4 4 2\n\n\njulia> matrix(map(FM2, 1))\n[1 0]\n[0 -x*z + y^2]\n[0 -w*z + x*y]\n[0 w*y]\n\njulia> FM3 = free_resolution(M, algorithm = :mres)\nFree resolution of M\nR^1 <---- R^3 <---- R^4 <---- R^2 <---- 0\n0 1 2 3 4\n\njulia> betti_table(FM3)\n 0 1 2 3\n-----------------\n0 : 1 - - -\n1 : - 3 - -\n2 : - - 4 2\n-----------------\ntotal: 1 3 4 2\n\n\njulia> matrix(map(FM3, 1))\n[-x*z + y^2]\n[-w*z + x*y]\n[ w*y]\n\n\nNote: Over rings other than polynomial rings or quotients of polynomial rings, the method will default to a lazy, iterative kernel computation.\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/homological_algebra/#Betti-Tables","page":"Homological Algebra","title":"Betti Tables","text":"","category":"section"},{"location":"CommutativeAlgebra/homological_algebra/","page":"Homological Algebra","title":"Homological Algebra","text":"Given a mathbb Z-graded multivariate polynomial ring S, and given a graded free resolution with finitely generated graded free S-modules ","category":"page"},{"location":"CommutativeAlgebra/homological_algebra/","page":"Homological Algebra","title":"Homological Algebra","text":"F_i=bigoplus_j S(-j) ^beta_ij","category":"page"},{"location":"CommutativeAlgebra/homological_algebra/","page":"Homological Algebra","title":"Homological Algebra","text":"the numbers beta_ij are commonly known as the graded Betti numbers of the resolution. A convenient way of visualizing these numbers is to write a Betti table as in the example below:","category":"page"},{"location":"CommutativeAlgebra/homological_algebra/","page":"Homological Algebra","title":"Homological Algebra","text":" 0 1 2 3 \n------------------\n0 : 1 - - - \n1 : - 2 1 - \n2 : - 2 3 1 \n------------------\ntotal: 1 4 4 1","category":"page"},{"location":"CommutativeAlgebra/homological_algebra/","page":"Homological Algebra","title":"Homological Algebra","text":"A number i in the top row of the table refers to the i-th free module F_i of the resolution. More precisely, the column with first entry i lists the number of free generators of F_i in different degrees and, in the bottom row, the total number of free generators (that is, the rank of F_i). If k is the first entry of a row containing a number beta in the column corresponding to F_i, then F_i has beta generators in degree k+i. That is, for a free module F_i written as a direct sum as above, beta is the number beta_ij with j=k+i. The explicit example table above indicates, for instance, that F_2 has one generator in degree 3 and three generators in degree 4. In total, the diagram corresponds to a graded free resolution of type ","category":"page"},{"location":"CommutativeAlgebra/homological_algebra/","page":"Homological Algebra","title":"Homological Algebra","text":"S leftarrow S(-2)^2oplus S(-3)^2 leftarrow S(-3)oplus S(-4)^3 leftarrow S(-5) leftarrow 0","category":"page"},{"location":"CommutativeAlgebra/homological_algebra/","page":"Homological Algebra","title":"Homological Algebra","text":"betti_table(F::FreeResolution)","category":"page"},{"location":"CommutativeAlgebra/homological_algebra/#betti_table-Tuple{FreeResolution}","page":"Homological Algebra","title":"betti_table","text":"betti_table(F::FreeResolution)\n\nGiven a mathbb Z-graded free resolution F, return the graded Betti numbers of F in form of a Betti table.\n\nAlternatively, use betti.\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*z, x*w^2, y*w^2])\nideal(x*z, y*z, w^2*x, w^2*y)\n\njulia> A, _= quo(R, I)\n(Quotient of multivariate polynomial ring by ideal with 4 generators, Map from\nR to A defined by a julia-function with inverse)\n\njulia> FA = free_resolution(A)\nFree resolution of A\nR^1 <---- R^4 <---- R^4 <---- R^1 <---- 0\n0 1 2 3 4\n\njulia> betti_table(FA)\n 0 1 2 3\n------------------\n0 : 1 - - -\n1 : - 2 1 -\n2 : - 2 3 1\n------------------\ntotal: 1 4 4 1\n\njulia> R, (x, y) = graded_polynomial_ring(QQ, [:x, :y]);\n\njulia> I = ideal(R, [x, y, x+y]);\n\njulia> M = quotient_ring_as_module(I);\n\njulia> FM = free_resolution(M, algorithm = :nres);\n\njulia> betti_table(FM)\n 0 1 2\n---------------\n-1 : - - 1\n0 : 1 3 1\n---------------\ntotal: 1 3 2\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/homological_algebra/","page":"Homological Algebra","title":"Homological Algebra","text":"minimal_betti_table(F::FreeResolution{T}) where {T<:ModuleFP}","category":"page"},{"location":"CommutativeAlgebra/homological_algebra/#minimal_betti_table-Union{Tuple{FreeResolution{T}}, Tuple{T}} where T<:ModuleFP","page":"Homological Algebra","title":"minimal_betti_table","text":"minimal_betti_table(F::FreeResolution{T}; check::Bool=true) where {T<:ModuleFP}\n\nGiven a graded free resolution F over a standard mathbb Z-graded multivariate polynomial ring with coefficients in a field, return the Betti table of the minimal free resolution arising from F.\n\nnote: Note\nThe algorithm proceeds without actually minimizing the resolution.\n\nExamples\n\njulia> R, (w, x, y, z) = graded_polynomial_ring(QQ, [:w, :x, :y, :z]);\n\njulia> I = ideal(R, [w^2-x*z, w*x-y*z, x^2-w*y, x*y-z^2, y^2-w*z]);\n\njulia> A, _ = quo(R, I)\n(Quotient of multivariate polynomial ring by ideal with 5 generators, Map from\nR to A defined by a julia-function with inverse)\n\njulia> FA = free_resolution(A)\nFree resolution of A\nR^1 <---- R^5 <---- R^6 <---- R^2 <---- 0\n0 1 2 3 4\n\njulia> betti_table(FA)\n 0 1 2 3 \n------------------\n0 : 1 - - - \n1 : - 5 5 1 \n2 : - - 1 1 \n------------------\ntotal: 1 5 6 2 \n\njulia> minimal_betti_table(FA)\n 0 1 2 3 \n------------------\n0 : 1 - - - \n1 : - 5 5 - \n2 : - - - 1 \n------------------\ntotal: 1 5 5 1 \n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/homological_algebra/","page":"Homological Algebra","title":"Homological Algebra","text":"minimal_betti_table(M::ModuleFP{T}) where {T<:MPolyDecRingElem}","category":"page"},{"location":"CommutativeAlgebra/homological_algebra/#minimal_betti_table-Union{Tuple{ModuleFP{T}}, Tuple{T}} where T<:MPolyDecRingElem","page":"Homological Algebra","title":"minimal_betti_table","text":"minimal_betti_table(M::ModuleFP{T}) where {T<:MPolyDecRingElem}\nminimal_betti_table(A::MPolyQuoRing{T}) where {T<:MPolyDecRingElem}\nminimal_betti_table(I::MPolyIdeal{T}) where {T<:MPolyDecRingElem}\n\nGiven a finitely presented graded module M over a standard mathbb Z-graded multivariate polynomial ring with coefficients in a field, return the Betti Table of the minimal free resolution of M. Similarly for A and I.\n\nExamples\n\njulia> R, (w, x, y, z) = graded_polynomial_ring(QQ, [:w, :x, :y, :z]);\n\njulia> I = ideal(R, [w^2-x*z, w*x-y*z, x^2-w*y, x*y-z^2, y^2-w*z]);\n\njulia> A, _ = quo(R, I)\n(Quotient of multivariate polynomial ring by ideal with 5 generators, Map from\nR to A defined by a julia-function with inverse)\n\njulia> minimal_betti_table(A)\n 0 1 2 3\n------------------\n0 : 1 - - -\n1 : - 5 5 -\n2 : - - - 1\n------------------\ntotal: 1 5 5 1\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/homological_algebra/#Castelnuovo-Mumford-Regularity","page":"Homological Algebra","title":"Castelnuovo-Mumford Regularity","text":"","category":"section"},{"location":"CommutativeAlgebra/homological_algebra/","page":"Homological Algebra","title":"Homological Algebra","text":"cm_regularity(M::ModuleFP)","category":"page"},{"location":"CommutativeAlgebra/homological_algebra/#cm_regularity-Tuple{ModuleFP}","page":"Homological Algebra","title":"cm_regularity","text":"cm_regularity(M::ModuleFP; check::Bool=true)\n\nGiven a finitely presented graded module M over a standard mathbb Z-graded multivariate polynomial ring with coefficients in a field, return the Castelnuovo-Mumford regularity of M.\n\ncm_regularity(I::MPolyIdeal)\n\nGiven a (homogeneous) ideal I in a standard mathbb Z-graded multivariate polynomial ring with coefficients in a field, return the Castelnuovo-Mumford regularity of I.\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 0 1 2 3 \n--------------\n0 : 1 - - - \n1 : - 3 - - \n2 : - - 3 - \n3 : - - - 1 \n--------------\ntotal: 1 3 3 1 \n\njulia> R, (w, x, y, z) = graded_polynomial_ring(QQ, [:w, :x, :y, :z]);\n\njulia> I = ideal(R, [-x*z+y^2, x*y-w*z, x^2-w*y]);\n\njulia> cm_regularity(I)\n2\n\njulia> A, _ = quo(R, I);\n\njulia> minimal_betti_table(A)\n 0 1 2 \n------------\n0 : 1 - - \n1 : - 3 2 \n------------\ntotal: 1 3 2 \n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/homological_algebra/#Homology","page":"Homological Algebra","title":"Homology","text":"","category":"section"},{"location":"CommutativeAlgebra/homological_algebra/","page":"Homological Algebra","title":"Homological Algebra","text":"homology(C::ComplexOfMorphisms{<:ModuleFP})","category":"page"},{"location":"CommutativeAlgebra/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/homological_algebra/","page":"Homological Algebra","title":"Homological Algebra","text":"homology(C::ComplexOfMorphisms{<:ModuleFP}, i::Int)","category":"page"},{"location":"CommutativeAlgebra/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/homological_algebra/#Hom-and-Ext","page":"Homological Algebra","title":"Hom and Ext","text":"","category":"section"},{"location":"CommutativeAlgebra/homological_algebra/","page":"Homological Algebra","title":"Homological Algebra","text":"hom(M::ModuleFP, N::ModuleFP; algorithm::Symbol=:maps)","category":"page"},{"location":"CommutativeAlgebra/homological_algebra/#hom-Tuple{ModuleFP, ModuleFP}","page":"Homological Algebra","title":"hom","text":"hom(M::ModuleFP, N::ModuleFP; algorithm::Symbol=:maps)\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\nThe keyword algorithm can be set to :maps for the default algorithm or to :matrices for an alternative based on matrices.\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_object(F, V)\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":"method"},{"location":"CommutativeAlgebra/homological_algebra/","page":"Homological Algebra","title":"Homological Algebra","text":"element_to_homomorphism(f::ModuleFPElem)","category":"page"},{"location":"CommutativeAlgebra/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_object(F, V)\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/homological_algebra/","page":"Homological Algebra","title":"Homological Algebra","text":"homomorphism_to_element(H::ModuleFP, phi::ModuleFPHom)","category":"page"},{"location":"CommutativeAlgebra/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_object(F, V)\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> is_welldefined(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/homological_algebra/","page":"Homological Algebra","title":"Homological Algebra","text":"ext(M::ModuleFP, N::ModuleFP, i::Int)","category":"page"},{"location":"CommutativeAlgebra/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_object(F, V)\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 -> y*(e[1] -> e[1])\n2 -> x*(e[1] -> e[1])\n\njulia> ext(M, M, 1)\nSubquotient of Submodule with 2 generators\n1 -> (e[1] -> e[1])\n2 -> (e[2] -> e[1])\nby Submodule with 4 generators\n1 -> y*(e[1] -> e[1])\n2 -> x*(e[1] -> e[1])\n3 -> y*(e[2] -> e[1])\n4 -> x*(e[2] -> e[1])\n\njulia> ext(M, M, 2)\nSubquotient of Submodule with 1 generator\n1 -> (e[1] -> e[1])\nby Submodule with 2 generators\n1 -> y*(e[1] -> e[1])\n2 -> 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/homological_algebra/#Tensorproduct-and-Tor","page":"Homological Algebra","title":"Tensorproduct and Tor","text":"","category":"section"},{"location":"CommutativeAlgebra/homological_algebra/","page":"Homological Algebra","title":"Homological Algebra","text":"tensor_product(G::ModuleFP...; task::Symbol = :none)","category":"page"},{"location":"CommutativeAlgebra/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/homological_algebra/","page":"Homological Algebra","title":"Homological Algebra","text":"tor(M::ModuleFP, N::ModuleFP, i::Int)","category":"page"},{"location":"CommutativeAlgebra/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 2 generators\n1 -> x*e[1] \\otimes e[1]\n2 -> x*y*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/homological_algebra/#Fitting-Ideals","page":"Homological Algebra","title":"Fitting Ideals","text":"","category":"section"},{"location":"CommutativeAlgebra/homological_algebra/","page":"Homological Algebra","title":"Homological Algebra","text":"fitting_ideal(M::ModuleFP{T}, i::Int) where T <: MPolyRingElem","category":"page"},{"location":"CommutativeAlgebra/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_object(F,U)\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 generated by\n 0\n\njulia> fitting_ideal(M, 0)\nIdeal generated by\n x^3 - y^2\n\njulia> fitting_ideal(M, 1)\nIdeal generated by\n y\n x\n\njulia> fitting_ideal(M, 2)\nIdeal generated by\n 1\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/homological_algebra/#Flatness","page":"Homological Algebra","title":"Flatness","text":"","category":"section"},{"location":"CommutativeAlgebra/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/homological_algebra/","page":"Homological Algebra","title":"Homological Algebra","text":"is_flat(M::ModuleFP{T}) where T <: MPolyRingElem","category":"page"},{"location":"CommutativeAlgebra/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_object(F,U)\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/homological_algebra/","page":"Homological Algebra","title":"Homological Algebra","text":"non_flat_locus(M::ModuleFP{T}) where T <: MPolyRingElem","category":"page"},{"location":"CommutativeAlgebra/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_object(F,U)\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 generated by\n x^3 - y^2\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/homological_algebra/#Regular-Sequence-Test","page":"Homological Algebra","title":"Regular Sequence Test","text":"","category":"section"},{"location":"CommutativeAlgebra/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/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/homological_algebra/#Koszul-Complex","page":"Homological Algebra","title":"Koszul Complex","text":"","category":"section"},{"location":"CommutativeAlgebra/homological_algebra/","page":"Homological Algebra","title":"Homological Algebra","text":"koszul_matrix(V::Vector{T}, i::Int) where T <: MPolyRingElem","category":"page"},{"location":"CommutativeAlgebra/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[x y z]\n\njulia> koszul_matrix(V, 2)\n[-y -z 0]\n[ x 0 -z]\n[ 0 x y]\n\njulia> koszul_matrix(V, 1)\n[ z]\n[-y]\n[ x]\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/homological_algebra/","page":"Homological Algebra","title":"Homological Algebra","text":"koszul_complex(V::Vector{T}) where T <: MPolyRingElem","category":"page"},{"location":"CommutativeAlgebra/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 -z 0]\n[ x 0 -z]\n[ 0 x y]\n\njulia> Kd = hom(K, free_module(R, 1));\n\njulia> matrix(map(Kd, 1))\n[-y x 0]\n[-z 0 x]\n[ 0 -z y]\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/homological_algebra/#Koszul-Homology","page":"Homological Algebra","title":"Koszul Homology","text":"","category":"section"},{"location":"CommutativeAlgebra/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/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 [GP08] or [DL06] 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)\nSubquotient of Submodule with 1 generator\n1 -> e[1]^e[2]^e[3]\nby Submodule with 3 generators\n1 -> y*z*e[1]^e[2]^e[3]\n2 -> -x*z*e[1]^e[2]^e[3]\n3 -> x*y*e[1]^e[2]^e[3]\n\njulia> koszul_homology(V, F, 1)\nSubquotient of Submodule with 2 generators\n1 -> y*e[1]^e[3] \\otimes e[1] + z*e[2]^e[3] \\otimes e[1]\n2 -> x*e[1]^e[2] \\otimes e[1] - z*e[2]^e[3] \\otimes e[1]\nby Submodule with 3 generators\n1 -> -x*z*e[1]^e[2] \\otimes e[1] - y*z*e[1]^e[3] \\otimes e[1]\n2 -> x*y*e[1]^e[2] \\otimes e[1] - y*z*e[2]^e[3] \\otimes e[1]\n3 -> x*y*e[1]^e[3] \\otimes e[1] + x*z*e[2]^e[3] \\otimes e[1]\n\njulia> koszul_homology(V, F, 2)\nSubquotient of Submodule with 1 generator\n1 -> x*y*e[1] \\otimes e[1] + x*z*e[2] \\otimes e[1] + y*z*e[3] \\otimes e[1]\nby Submodule with 1 generator\n1 -> x*y*e[1] \\otimes e[1] + x*z*e[2] \\otimes e[1] + y*z*e[3] \\otimes e[1]\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)\nSubquotient of Submodule with 1 generator\n1 -> e[1]^e[2]^e[3]\nby Submodule with 3 generators\n1 -> (w*y - x^2)*e[1]^e[2]^e[3]\n2 -> (-w*z + x*y)*e[1]^e[2]^e[3]\n3 -> (x*z - y^2)*e[1]^e[2]^e[3]\n\njulia> koszul_homology(gens(TC), F, 1)\nSubquotient of Submodule with 2 generators\n1 -> z*e[1]^e[2] \\otimes e[1] + y*e[1]^e[3] \\otimes e[1] + x*e[2]^e[3] \\otimes e[1]\n2 -> y*e[1]^e[2] \\otimes e[1] + x*e[1]^e[3] \\otimes e[1] + w*e[2]^e[3] \\otimes e[1]\nby Submodule with 3 generators\n1 -> (-w*z + x*y)*e[1]^e[2] \\otimes e[1] + (-w*y + x^2)*e[1]^e[3] \\otimes e[1]\n2 -> (x*z - y^2)*e[1]^e[2] \\otimes e[1] + (-w*y + x^2)*e[2]^e[3] \\otimes e[1]\n3 -> (x*z - y^2)*e[1]^e[3] \\otimes e[1] + (w*z - x*y)*e[2]^e[3] \\otimes e[1]\n\njulia> koszul_homology(gens(TC), F, 2)\nSubquotient of Submodule with 1 generator\n1 -> (-x*z + y^2)*e[1] \\otimes e[1] + (-w*z + x*y)*e[2] \\otimes e[1] + (-w*y + x^2)*e[3] \\otimes e[1]\nby Submodule with 1 generator\n1 -> (x*z - y^2)*e[1] \\otimes e[1] + (w*z - x*y)*e[2] \\otimes e[1] + (w*y - x^2)*e[3] \\otimes e[1]\n\n\n\n\n\n","category":"method"},{"location":"CommutativeAlgebra/homological_algebra/#Depth","page":"Homological Algebra","title":"Depth","text":"","category":"section"},{"location":"CommutativeAlgebra/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/homological_algebra/","page":"Homological Algebra","title":"Homological Algebra","text":"depth(I::MPolyIdeal{T}, M::ModuleFP{T}) where T <: MPolyRingElem","category":"page"},{"location":"CommutativeAlgebra/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 generated by\n w\n x\n y\n 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 generated by\n y[1]\n y[2]\n y[3]\n y[4]\n y[5]\n\njulia> depth(I, M)\n1\n\n\n\n\n\n","category":"method"},{"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":"number_of_generators(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":"morphism(X::AbsAffineScheme, Y::AbsAffineScheme, f::Vector{<:RingElem}; check::Bool=true)","category":"page"},{"location":"AlgebraicGeometry/Schemes/MorphismsOfAffineSchemes/#morphism-Tuple{AbsAffineScheme, AbsAffineScheme, Vector{<:RingElem}}","page":"Morphisms of affine schemes","title":"morphism","text":"morphism(X::AbsAffineScheme, Y::AbsAffineScheme, 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> morphism(X, Y, gens(OO(X)))\nAffine scheme morphism\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::AbsAffineScheme{<:Any, <:MPolyRing})\ninclusion_morphism(X::AbsAffineScheme, Y::AbsAffineScheme; check::Bool=true)\ncompose(f::AbsAffineSchemeMor, g::AbsAffineSchemeMor)\nrestrict(f::AffineSchemeMor, U::AbsAffineScheme, V::AbsAffineScheme)","category":"page"},{"location":"AlgebraicGeometry/Schemes/MorphismsOfAffineSchemes/#identity_map-Tuple{AbsAffineScheme{<:Any, <:MPolyRing}}","page":"Morphisms of affine schemes","title":"identity_map","text":"identity_map(X::AbsAffineScheme{<: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)\nAffine scheme morphism\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{AbsAffineScheme, AbsAffineScheme}","page":"Morphisms of affine schemes","title":"inclusion_morphism","text":"inclusion_morphism(X::AbsAffineScheme, Y::AbsAffineScheme; 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 x1, x2, x3\n over rational field\n by ideal (x1)\n\njulia> f = inclusion_morphism(Y, X)\nAffine scheme morphism\n from [x1, x2, x3] scheme(x1)\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> I = kernel(pullback(f)) # this is a way to obtain the ideal ``I ⊆ O(X)`` cutting out ``Y`` from ``X``.\nIdeal generated by\n x1\n\njulia> base_ring(I) == OO(X)\ntrue\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/MorphismsOfAffineSchemes/#compose-Tuple{AbsAffineSchemeMor, AbsAffineSchemeMor}","page":"Morphisms of affine schemes","title":"compose","text":"compose(f::AbsAffineSchemeMor, g::AbsAffineSchemeMor)\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 x1, x2, x3\n over rational field\n by ideal (x1)\n\njulia> m1 = inclusion_morphism(Y, X)\nAffine scheme morphism\n from [x1, x2, x3] scheme(x1)\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> m2 = identity_map(X)\nAffine scheme morphism\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)\nAffine scheme morphism\n from [x1, x2, x3] scheme(x1)\n to [x1, x2, x3] scheme(x1)\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{Oscar.AffineSchemeMor, AbsAffineScheme, AbsAffineScheme}","page":"Morphisms of affine schemes","title":"restrict","text":"restrict(f::AbsAffineSchemeMor, D::AbsAffineScheme, Z::AbsAffineScheme; check::Bool=true)\n\nThis method restricts the domain of the morphism f to D and its codomain to Z.\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 x1, x2, x3\n over rational field\n by ideal (x1)\n\njulia> restrict(identity_map(X), Y, Y) == identity_map(Y)\ntrue\n\n\n\n\n\nrestrict(f::SchemeMor, U::Scheme, V::Scheme; check::Bool=true)\n\nReturn the restriction g U V of f to U and V.\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::AbsAffineSchemeMor)\ncodomain(f::AbsAffineSchemeMor)\npullback(f::AbsAffineSchemeMor)\ngraph(f::AbsAffineSchemeMor)","category":"page"},{"location":"AlgebraicGeometry/Schemes/MorphismsOfAffineSchemes/#domain-Tuple{AbsAffineSchemeMor}","page":"Morphisms of affine schemes","title":"domain","text":"domain(f::AbsAffineSchemeMor)\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 x1, x2, x3\n over rational field\n by ideal (x1)\n\njulia> f = inclusion_morphism(X, Y)\nAffine scheme morphism\n from [x1, x2, x3] scheme(x1)\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> domain(f)\nSpectrum\n of quotient\n of multivariate polynomial ring in 3 variables x1, x2, x3\n over rational field\n by ideal (x1)\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/MorphismsOfAffineSchemes/#codomain-Tuple{AbsAffineSchemeMor}","page":"Morphisms of affine schemes","title":"codomain","text":"codomain(f::AbsAffineSchemeMor)\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 x1, x2, x3\n over rational field\n by ideal (x1)\n\njulia> f = inclusion_morphism(X, Y)\nAffine scheme morphism\n from [x1, x2, x3] scheme(x1)\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> 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{AbsAffineSchemeMor}","page":"Morphisms of affine schemes","title":"pullback","text":"pullback(f::AbsAffineSchemeMor)\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 x1, x2, x3\n over rational field\n by ideal (x1)\n\njulia> pullback(inclusion_morphism(X, Y))\nRing homomorphism\n from multivariate polynomial ring in 3 variables over QQ\n to quotient of multivariate polynomial ring by ideal (x1)\ndefined by\n x1 -> x1\n x2 -> x2\n x3 -> x3\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/MorphismsOfAffineSchemes/#graph-Tuple{AbsAffineSchemeMor}","page":"Morphisms of affine schemes","title":"graph","text":"graph(f::AbsAffineSchemeMor)\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 x1, x2, x3\n over rational field\n by ideal (x1)\n\njulia> f = inclusion_morphism(X, Y)\nAffine scheme morphism\n from [x1, x2, x3] scheme(x1)\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> graph(f)\n(scheme(x1, -x1, x2 - x2, x3 - x3), Hom: scheme(x1, -x1, x2 - x2, x3 - x3) -> scheme(x1), Hom: scheme(x1, -x1, x2 - x2, x3 - x3) -> affine 3-space over QQ with coordinates [x1, x2, x3])\n\n\n\n\n\ngraph(TropC::TropicalCurve{minOrMax,false})\n\nReturn the graph of an abstract tropical curve TropC. Same as polyhedral_complex(tc).\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 AffineSchemeMor, 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::AbsAffineSchemeMor)\nis_inverse_of(f::AbsAffineSchemeMor, g::AbsAffineSchemeMor)\nis_identity_map(f::AbsAffineSchemeMor)","category":"page"},{"location":"AlgebraicGeometry/Schemes/MorphismsOfAffineSchemes/#is_isomorphism-Tuple{AbsAffineSchemeMor}","page":"Morphisms of affine schemes","title":"is_isomorphism","text":"is_isomorphism(f::AbsAffineSchemeMor)\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{AbsAffineSchemeMor, AbsAffineSchemeMor}","page":"Morphisms of affine schemes","title":"is_inverse_of","text":"is_inverse_of(f::AbsAffineSchemeMor, g::AbsAffineSchemeMor)\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{AbsAffineSchemeMor}","page":"Morphisms of affine schemes","title":"is_identity_map","text":"is_identity_map(f::AbsAffineSchemeMor)\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 x1, x2, x3\n over rational field\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::AbsAffineSchemeMor, g::AbsAffineSchemeMor)\nproduct(X::AbsAffineScheme, Y::AbsAffineScheme)\nsimplify(X::AbsAffineScheme{<:AbstractAlgebra.Field})","category":"page"},{"location":"AlgebraicGeometry/Schemes/MorphismsOfAffineSchemes/#fiber_product-Tuple{AbsAffineSchemeMor, AbsAffineSchemeMor}","page":"Morphisms of affine schemes","title":"fiber_product","text":"fiber_product(f::AbsAffineSchemeMor, g::AbsAffineSchemeMor)\n\nFor morphisms f X Z and g Y Z return the fiber product XY over Z together with its two canonical projections.\n\nWhenever you have another set of maps a: W → X and b : W → Y forming a commutative square with f and g, you can use induced_map_to_fiber_product to create the resulting map W → X×Y.\n\n\n\n\n\n","category":"method"},{"location":"AlgebraicGeometry/Schemes/MorphismsOfAffineSchemes/#product-Tuple{AbsAffineScheme, AbsAffineScheme}","page":"Morphisms of affine schemes","title":"product","text":"product(X::AbsAffineScheme, Y::AbsAffineScheme)\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{AbsAffineScheme{<:Field}}","page":"Morphisms of affine schemes","title":"simplify","text":"simplify(X::AbsAffineScheme{<: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 SimplifiedAffineScheme 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 = Oscar.doctestsetup()","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_finite_order(x::GAPGroupElem)\ngens(::GAPGroup)\nhas_gens(::GAPGroup)\nnumber_of_generators(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, SubFPGroup, PcGroup, SubPcGroup, 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_finite_order-Tuple{GAPGroupElem}","page":"Basics","title":"is_finite_order","text":"is_finite_order(g::GAPGroupElem) -> Bool\n\nReturn true if g has finite order, and false otherwise.\n\nExamples\n\njulia> is_finite_order(gen(symmetric_group(5), 1))\ntrue\n\njulia> is_finite_order(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)\nFree group of rank 2\n\njulia> has_gens(F)\ntrue\n\njulia> H = derived_subgroup(F)[1]\nFree group\n\njulia> has_gens(H)\nfalse\n\n\n\n\n\n","category":"method"},{"location":"Groups/basics/#number_of_generators-Tuple{Oscar.GAPGroup}","page":"Basics","title":"number_of_generators","text":"number_of_generators(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 one(G) if i == 0, the i-th element of the vector gens(G) if i is positive, and the inverse of the i-th element of gens(G) if i is negative.\n\nFor positive i, 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 abs(i) is larger than the length of gens(G).\n\nExamples\n\njulia> g = symmetric_group(5); gen(g, 1)\n(1,2,3,4,5)\n\njulia> g[-1]\n(1,5,4,3,2)\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(SubPcGroup, [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(G::GAPGroup)\nis_pgroup(G::GAPGroup)\nis_pgroup_with_prime(::Type{T}, G::GAPGroup) where T <: IntegerUnion\nis_nilpotent(G::GAPGroup)\nis_supersolvable(G::GAPGroup)\nis_solvable(G::GAPGroup)\nis_perfect(G::GAPGroup)\nis_simple(G::GAPGroup)\nis_almost_simple(G::GAPGroup)\nis_quasisimple(G::GAPGroup)\nis_sporadic_simple(G::GAPGroup)\nis_finitely_generated(G::GAPGroup)","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-Tuple{Oscar.GAPGroup}","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":"method"},{"location":"Groups/basics/#is_pgroup-Tuple{Oscar.GAPGroup}","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":"method"},{"location":"Groups/basics/#is_pgroup_with_prime-Union{Tuple{T}, Tuple{Type{T}, Oscar.GAPGroup}} where T<:Union{Integer, ZZRingElem}","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":"method"},{"location":"Groups/basics/#is_nilpotent-Tuple{Oscar.GAPGroup}","page":"Basics","title":"is_nilpotent","text":"is_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\nExamples\n\njulia> is_nilpotent(dihedral_group(8))\ntrue\n\njulia> is_nilpotent(dihedral_group(10))\nfalse\n\n\n\n\n\n","category":"method"},{"location":"Groups/basics/#is_supersolvable-Tuple{Oscar.GAPGroup}","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\nExamples\n\njulia> is_supersolvable(symmetric_group(3))\ntrue\n\njulia> is_supersolvable(symmetric_group(4))\nfalse\n\njulia> is_supersolvable(symmetric_group(5))\nfalse\n\n\n\n\n\n","category":"method"},{"location":"Groups/basics/#is_solvable-Tuple{Oscar.GAPGroup}","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\nExamples\n\njulia> is_solvable(symmetric_group(3))\ntrue\n\njulia> is_solvable(symmetric_group(4))\ntrue\n\njulia> is_solvable(symmetric_group(5))\nfalse\n\n\n\n\n\n","category":"method"},{"location":"Groups/basics/#is_perfect-Tuple{Oscar.GAPGroup}","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":"method"},{"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_almost_simple-Tuple{Oscar.GAPGroup}","page":"Basics","title":"is_almost_simple","text":"is_almost_simple(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_almost_simple(symmetric_group(5))\ntrue\n\njulia> is_almost_simple(special_linear_group(2, 5))\nfalse\n\n\n\n\n\n\n","category":"method"},{"location":"Groups/basics/#is_quasisimple-Tuple{Oscar.GAPGroup}","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 center 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":"method"},{"location":"Groups/basics/#is_sporadic_simple-Tuple{Oscar.GAPGroup}","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":"method"},{"location":"Groups/basics/#is_finitely_generated-Tuple{Oscar.GAPGroup}","page":"Basics","title":"is_finitely_generated","text":"is_finitely_generated(G::GAPGroup)\n\nReturn whether G is a finitely generated group.\n\nExamples\n\njulia> F = free_group(2)\nFree group of rank 2\n\njulia> is_finitely_generated(F)\ntrue\n\njulia> H = derived_subgroup(F)[1]\nFree group\n\njulia> is_finitely_generated(H)\nfalse\n\n\n\n\n\n","category":"method"},{"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\nabelian_invariants(G::GAPGroup)\nabelian_invariants_schur_multiplier(G::GAPGroup)\ncyclic_generator(G::GAPGroup)\nexponent(G::GAPGroup)\ndescribe(G::GAPGroup)\nnilpotency_class(G::GAPGroup)\nprime_of_pgroup\nderived_length\nschur_cover(G::GAPGroup)\nschur_multiplier(G::Union{GAPGroup, FinGenAbGroup})","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_finite_order 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_finite_order(gen(g, 1))\nfalse\n\n\n\n\n\n","category":"method"},{"location":"Groups/basics/#abelian_invariants-Tuple{Oscar.GAPGroup}","page":"Basics","title":"abelian_invariants","text":"abelian_invariants(::Type{T} = ZZRingElem, G::Union{GAPGroup, FinGenAbGroup}) where T <: IntegerUnion\n\nReturn the sorted vector of abelian invariants of the commutator factor group of G (see maximal_abelian_quotient). The entries are prime powers or zeroes and have the type T. They describe the structure of the commutator factor group of G as a direct product of cyclic groups of prime power (or infinite) order.\n\nExamples\n\njulia> abelian_invariants(symmetric_group(4))\n1-element Vector{ZZRingElem}:\n 2\n\njulia> abelian_invariants(Int, abelian_group([2, 12]))\n3-element Vector{Int64}:\n 2\n 3\n 4\n\njulia> abelian_invariants(alternating_group(5))\nZZRingElem[]\n\n\n\n\n\n","category":"method"},{"location":"Groups/basics/#abelian_invariants_schur_multiplier-Tuple{Oscar.GAPGroup}","page":"Basics","title":"abelian_invariants_schur_multiplier","text":"abelian_invariants_schur_multiplier(::Type{T} = ZZRingElem, G::Union{GAPGroup, FinGenAbGroup}) where T <: IntegerUnion\n\nReturn the sorted vector of abelian invariants (see abelian_invariants) of the Schur multiplier of G. The entries are prime powers or zeroes and have the type T. They describe the structure of the Schur multiplier of G as a direct product of cyclic groups of prime power (or infinite) order.\n\nExamples\n\njulia> abelian_invariants_schur_multiplier(symmetric_group(4))\n1-element Vector{ZZRingElem}:\n 2\n\njulia> abelian_invariants_schur_multiplier(Int, alternating_group(6))\n2-element Vector{Int64}:\n 2\n 3\n\njulia> abelian_invariants_schur_multiplier(abelian_group([2, 12]))\n1-element Vector{ZZRingElem}:\n 2\n\njulia> abelian_invariants_schur_multiplier(cyclic_group(5))\nZZRingElem[]\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)])\nPermutation group of degree 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 with n steps (meaning that it consists of n+1 groups). The trivial group is the unique group with nilpotency class 0 and all abelian groups have nilpotency class 1.\n\nAn exception is thrown if G is not nilpotent.\n\nSee also lower_central_series and upper_central_series.\n\nExamples\n\njulia> nilpotency_class(dihedral_group(8))\n2\n\njulia> nilpotency_class(dihedral_group(12))\nERROR: ArgumentError: The group 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"},{"location":"Groups/basics/#derived_length","page":"Basics","title":"derived_length","text":"derived_length(G::GAPGroup)\n\nReturn the number of steps in the derived series of G, that is the series length minus 1. See also derived_series.\n\nExamples\n\njulia> derived_length(symmetric_group(4))\n3\n\njulia> derived_length(symmetric_group(5))\n1\n\njulia> derived_length(dihedral_group(8))\n2\n\n\n\n\n\n","category":"function"},{"location":"Groups/basics/#schur_cover-Tuple{Oscar.GAPGroup}","page":"Basics","title":"schur_cover","text":"schur_cover(::Type{T} = FPGroup, G::GAPGroup) where T <: GAPGroup\n\nReturn S, f where S is a Schur cover of G and f is an epimorphism from S to G.\n\nExamples\n\njulia> S, f = schur_cover(symmetric_group(4)); order(S)\n48\n\njulia> S, f = schur_cover(PermGroup, dihedral_group(12)); order(S)\n24\n\n\n\n\n\n","category":"method"},{"location":"Groups/basics/#schur_multiplier-Tuple{Union{FinGenAbGroup, Oscar.GAPGroup}}","page":"Basics","title":"schur_multiplier","text":"schur_multiplier(::Type{T} = FinGenAbGroup, G::Union{GAPGroup, FinGenAbGroup}) where T <: Union{GAPGroup, FinGenAbGroup}\n\nReturn the Schur multiplier of G. This is an abelian group whose abelian invariants can be computed with abelian_invariants_schur_multiplier.\n\nExamples\n\njulia> schur_multiplier(symmetric_group(4))\nZ/2\n\njulia> schur_multiplier(PcGroup, alternating_group(6))\nPc group of order 6\n\njulia> schur_multiplier(abelian_group([2, 12]))\nZ/2\n\njulia> schur_multiplier(cyclic_group(5))\nZ/1\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/abelian/introduction/","page":"Introduction","title":"Introduction","text":"CurrentModule = Hecke\nDocTestSetup = quote\n using Hecke\nend","category":"page"},{"location":"Hecke/manual/abelian/introduction/#AbelianGroupLink2","page":"Introduction","title":"Introduction","text":"","category":"section"},{"location":"Hecke/manual/abelian/introduction/","page":"Introduction","title":"Introduction","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/manual/abelian/introduction/#Basic-Creation","page":"Introduction","title":"Basic Creation","text":"","category":"section"},{"location":"Hecke/manual/abelian/introduction/","page":"Introduction","title":"Introduction","text":"Finitely presented (as mathbb Z-modules) abelian groups are of type FinGenAbGroup with elements of type FinGenAbGroupElem. 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/manual/abelian/introduction/","page":"Introduction","title":"Introduction","text":" sum_i=1^n m_ij e_j = 0","category":"page"},{"location":"Hecke/manual/abelian/introduction/","page":"Introduction","title":"Introduction","text":"abelian_group(M::ZZMatrix)\nabelian_group(M::Matrix{ZZRingElem})\nabelian_group(M::Matrix{Integer})","category":"page"},{"location":"Hecke/manual/abelian/introduction/#abelian_group-Tuple{ZZMatrix}","page":"Introduction","title":"abelian_group","text":"abelian_group(::Type{T} = FinGenAbGroup, M::ZZMatrix) -> FinGenAbGroup\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/manual/abelian/introduction/#abelian_group-Tuple{Matrix{ZZRingElem}}","page":"Introduction","title":"abelian_group","text":"abelian_group(::Type{T} = FinGenAbGroup, 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/manual/abelian/introduction/#abelian_group-Tuple{Matrix{Integer}}","page":"Introduction","title":"abelian_group","text":"abelian_group(::Type{T} = FinGenAbGroup, 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/manual/abelian/introduction/","page":"Introduction","title":"Introduction","text":"Alternatively, there are shortcuts to create products of cyclic groups:","category":"page"},{"location":"Hecke/manual/abelian/introduction/","page":"Introduction","title":"Introduction","text":"abelian_group(M::Vector{Union{ZZRingElem, Integer}})","category":"page"},{"location":"Hecke/manual/abelian/introduction/#abelian_group-Tuple{Vector{Union{Integer, ZZRingElem}}}","page":"Introduction","title":"abelian_group","text":"abelian_group(::Type{T} = FinGenAbGroup, M::AbstractVector{<:IntegerUnion}) -> FinGenAbGroup\nabelian_group(::Type{T} = FinGenAbGroup, M::IntegerUnion...) -> FinGenAbGroup\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/manual/abelian/introduction/","page":"Introduction","title":"Introduction","text":"using Hecke # hide\nG = abelian_group(2, 2, 6)","category":"page"},{"location":"Hecke/manual/abelian/introduction/","page":"Introduction","title":"Introduction","text":"or even","category":"page"},{"location":"Hecke/manual/abelian/introduction/","page":"Introduction","title":"Introduction","text":"free_abelian_group(::Int)\nabelian_groups(n::Int)","category":"page"},{"location":"Hecke/manual/abelian/introduction/#free_abelian_group-Tuple{Int64}","page":"Introduction","title":"free_abelian_group","text":"free_abelian_group(::Type{T} = FinGenAbGroup, n::Int) -> FinGenAbGroup\n\nCreates the free abelian group of rank n.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/abelian/introduction/#abelian_groups-Tuple{Int64}","page":"Introduction","title":"abelian_groups","text":"abelian_groups(n::Int) -> Vector{FinGenAbGroup}\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/manual/abelian/introduction/","page":"Introduction","title":"Introduction","text":"using Hecke # hide\nabelian_groups(8)","category":"page"},{"location":"Hecke/manual/abelian/introduction/#Invariants","page":"Introduction","title":"Invariants","text":"","category":"section"},{"location":"Hecke/manual/abelian/introduction/","page":"Introduction","title":"Introduction","text":"is_snf(A::FinGenAbGroup)\nnumber_of_generators(A::FinGenAbGroup)\nnrels(G::FinGenAbGroup)\nrels(A::FinGenAbGroup)\nis_finite(A::FinGenAbGroup)\ntorsion_free_rank(A::FinGenAbGroup)\norder(A::FinGenAbGroup)\nexponent(A::FinGenAbGroup)\nis_trivial(A::FinGenAbGroup)\nis_torsion(G::FinGenAbGroup)\nis_cyclic(G::FinGenAbGroup)\nelementary_divisors(G::FinGenAbGroup)","category":"page"},{"location":"Hecke/manual/abelian/introduction/#is_snf-Tuple{FinGenAbGroup}","page":"Introduction","title":"is_snf","text":"is_snf(G::FinGenAbGroup) -> 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/manual/abelian/introduction/#number_of_generators-Tuple{FinGenAbGroup}","page":"Introduction","title":"number_of_generators","text":"number_of_generators(G::FinGenAbGroup) -> Int\n\nReturn the number of generators of G in the current representation.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/abelian/introduction/#nrels-Tuple{FinGenAbGroup}","page":"Introduction","title":"nrels","text":"number_of_relations(G::FinGenAbGroup) -> Int\n\nReturn the number of relations of G in the current representation.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/abelian/introduction/#rels-Tuple{FinGenAbGroup}","page":"Introduction","title":"rels","text":"rels(A::FinGenAbGroup) -> ZZMatrix\n\nReturn the currently used relations of G as a single matrix.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/abelian/introduction/#is_finite-Tuple{FinGenAbGroup}","page":"Introduction","title":"is_finite","text":"isfinite(A::FinGenAbGroup) -> Bool\n\nReturn whether A is finite.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/abelian/introduction/#torsion_free_rank-Tuple{FinGenAbGroup}","page":"Introduction","title":"torsion_free_rank","text":"torsion_free_rank(A::FinGenAbGroup) -> Int\n\nReturn the torsion free rank of A, that is, the dimension of the mathbfQ-vectorspace A otimes_mathbf Z mathbf Q.\n\nSee also rank.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/abelian/introduction/#order-Tuple{FinGenAbGroup}","page":"Introduction","title":"order","text":"order(A::FinGenAbGroup) -> ZZRingElem\n\nReturn the order of A. It is assumed that A is finite.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/abelian/introduction/#exponent-Tuple{FinGenAbGroup}","page":"Introduction","title":"exponent","text":"exponent(A::FinGenAbGroup) -> ZZRingElem\n\nReturn the exponent of A. It is assumed that A is finite.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/abelian/introduction/#is_trivial-Tuple{FinGenAbGroup}","page":"Introduction","title":"is_trivial","text":"is_trivial(A::FinGenAbGroup) -> Bool\n\nReturn whether A is the trivial group.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/abelian/introduction/#is_torsion-Tuple{FinGenAbGroup}","page":"Introduction","title":"is_torsion","text":"is_torsion(G::FinGenAbGroup) -> Bool\n\nReturn whether G is a torsion group.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/abelian/introduction/#is_cyclic-Tuple{FinGenAbGroup}","page":"Introduction","title":"is_cyclic","text":"is_cyclic(G::FinGenAbGroup) -> Bool\n\nReturn whether G is cyclic.\n\n\n\n\n\n","category":"method"},{"location":"Hecke/manual/abelian/introduction/#elementary_divisors-Tuple{FinGenAbGroup}","page":"Introduction","title":"elementary_divisors","text":"elementary_divisors(G::FinGenAbGroup) -> Vector{ZZRingElem}\n\nGiven G, return the elementary divisors of G, that is, the unique non-negative integers e_1dotsce_k with e_i mid e_i + 1 and e_ineq 1 such that G cong mathbfZe_1mathbfZ times dotsb times mathbfZe_kmathbfZ.\n\n\n\n\n\n","category":"method"}] -} diff --git a/previews/PR4245/siteinfo.js b/previews/PR4245/siteinfo.js deleted file mode 100644 index 376d64a5b603..000000000000 --- a/previews/PR4245/siteinfo.js +++ /dev/null @@ -1 +0,0 @@ -var DOCUMENTER_CURRENT_VERSION = "previews/PR4245";
    [ABGJ18]
    X. Allamigeon, P. Benchimol, S. Gaubert and M. Joswig. Log-barrier interior point methods are not strongly polynomial. SIAM Journal on Applied Algebra and Geometry 2, 140–178 (2018).
    [ABS97]
    D. Avis, D. Bremner and R. Seidel. How good are convex hull algorithms? Comput. Geom. 7, 265–301 (1997). 11th ACM Symposium on Computational Geometry (Vancouver, BC, 1995).
    [AG10]
    I. V. Arzhantsev and S. A. Gaĭfullin. Cox rings, semigroups, and automorphisms of affine varieties. Mat. Sb. 201, 3–24 (2010), arXiv:0810.1148.
    [AGK96]
    B. Amrhein, O. Gloor and W. Küchlin. Walking faster. In: Design and Implementation of Symbolic Computation Systems, DISCO 1996 (Springer Berlin, Heidelberg, Heidelberg, Germany, 1996); pp. 150–161.
    [AGK97]
    B. Amrhein, O. Gloor and W. Küchlin. On the walk. Theoretical Computer Science 187, 179–202 (1997).
    [AHK18]
    K. Adiprasito, J. Huh and E. Katz. Hodge theory for combinatorial geometries. Ann. of Math. (2) 188, 381–452 (2018).
    [AL94]
    W. W. Adams and P. Loustaunau. An Introduction to Gröbner Bases. Graduate studies in mathematics (American Mathematical Society, 1994).
    [ATLAS]
    R. A. Wilson, P. Walsh, J. Tripp, I. Suleiman, R. A. Parker, S. P. Norton, S. Nickerson, S. Linton, J. Bray and R. Abbott. ATLAS of Finite Group Representations. Published electronically.
    [AZ99]
    N. Amenta and G. M. Ziegler. Deformed products and maximal shadows of polytopes. Contemporary Mathematics 223, 57–90 (1999).
    [BBS02]
    M. Bayer, A. Bruening and J. Stewart. A Combinatorial Study of Multiplexes and Ordinary Polytopes. Discrete & Computational Geometry 27, 49–63 (2002).
    [BCL21]
    M. Bies, M. Cvetič and M. Liu. Statistics of limit root bundles relevant for exact matter spectra of F-theory MSSMs. Phys. Rev. D 104, L061903 (2021).
    [BDEPS04]
    N. Berry, A. Dubickas, N. D. Elkies, B. Poonen and C. Smyth. The conjugate dimension of algebraic numbers. Q. J. Math. 55, 237–252 (2004).
    [BDLP17]
    J. Böhm, W. Decker, S. Laplagne and G. Pfister. Local to global algorithms for the Gorenstein adjoint ideal of a curve. In: Algorithmic and experimental methods in algebra, geometry, and number theory (Springer, Cham, 2017); pp. 51–96.
    [BDLP19]
    J. Böhm, W. Decker, S. Laplagne and G. Pfister. Computing integral bases via localization and Hensel lifting. In: MEGA 2019 - International Conference on Effective Methods in Algebraic Geometry (Madrid, Spain, 2019). HAL:hal-02912148.
    [BDLPSS13]
    J. Böhm, W. Decker, S. Laplagne, G. Pfister, A. Steenpaß and S. Steidel. Parallel algorithms for normalization. Journal of Symbolic Computation 51, 99–114 (2013). Effective Methods in Algebraic Geometry.
    [BEO23]
    H. U. Besche, B. Eick and E. O'Brien. SmallGrp, The GAP Small Groups Library, Version 1.5.3 (May 2023). GAP package.
    [BES-E-D21]
    J. Berthomieu, C. Eder and M. 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 (Association for Computing Machinery, New York, NY, USA, 2021); pp. 51–58.
    [BES19]
    S. Backman, C. Eur and C. Simpson. Simplicial generation of Chow rings of matroids (2019), arXiv:1905.07114 [math.CO].
    [BGV03]
    J. L. Bueso, J. Gómez-Torrecillas and A. Verschoren. Algorithmic methods in non-commutative algebra. Applications to quantum groups. Vol. 17 of Math. Model.: Theory Appl. (Dordrecht: Kluwer Academic Publishers, 2003).
    [BH09]
    W. Bruns and J. Herzog. Cohen-Macaulay rings. Vol. 39 of Cambridge Studies in Advanced Mathematics (Cambridge University Press, Cambridge, 2009). 2nd edition.
    [BH23]
    S. Brandhorst and T. Hofmann. Finite subgroups of automorphisms of K3 surfaces. Forum of Mathematics, Sigma 11, e54 1–57 (2023).
    [BHMPW20]
    T. Braden, J. Huh, J. P. Matherne, N. Proudfoot and B. Wang. A semi-small decomposition of the Chow ring of a matroid (2020), arXiv:2002.03341 [math.AG].
    [BHPV-D-V04]
    W. P. Barth, K. Hulek, C. A. Peters and A. Van de Ven. Compact complex surfaces. 2nd enlarged ed. Edition, Vol. 4 of Ergeb. Math. Grenzgeb., 3. Folge (Berlin: Springer, 2004).
    [BJRR10]
    R. Blumenhagen, B. Jurke, T. Rahn and H. Roschy. Cohomology of line bundles: A computational algorithm. Journal of Mathematical Physics 51, 103525 (2010).
    [BJRR10*1]
    R. Blumenhagen, B. Jurke, T. Rahn and H. Roschy, cohomCalg package. Published electronically on GitHub (2010). High-performance line bundle cohomology computation based on BJRR10.
    [BJRR12]
    R. Blumenhagen, B. Jurke, T. Rahn and H. Roschy. Cohomology of line bundles: Applications. Journal of Mathematical Physics 53, 012302 (2012).
    [BJSST07]
    T. Bogart, A. N. Jensen, D. Speyer, B. Sturmfels and R. R. Thomas. Computing tropical varieties. J. Symb. Comput. 42, 54–73 (2007).
    [BKR20]
    J. Böhm, S. Keicher and Y. Ren. Computing GIT-fans with symmetry and the Mori chamber decomposition of $\overline M_{0,6}$. Math. Comp. 89, 3003–3021 (2020).
    [BL81]
    L. J. Billera and C. W. Lee. A proof of the sufficiency of McMullen's conditions for $f$-vectors of simplicial convex polytopes. J. Combin. Theory Ser. A 31, 237–255 (1981).
    [BN07]
    M. Baker and S. Norine. Riemann-Roch and Abel-Jacobi theory on a finite graph. Adv. Math. 215, 766–788 (2007).
    [BS09]
    T. Banica and R. Speicher. Liberation of orthogonal Lie groups. Advances in Mathematics 222, 1461–1501 (2009).
    [Ben93]
    D. J. Benson. Polynomial invariants of finite groups. Vol. 190 of London Mathematical Society Lecture Note Series (Cambridge University Press, Cambridge, 1993).
    [Bhm99]
    J. Böhm. Parametrisierung rationaler Kurven. Diploma Thesis, Universität Bayreuth (1999).
    [Bie18]
    M. Bies. Cohomologies of coherent sheaves and massless spectra in F-theory. Ph.D. Thesis, Heidelberg U. (Feb 2018).
    [Bie24]
    M. Bies. Root bundles: Applications to F-theory Standard Models. Proc. Symp. Pure Math. 107, 17–44 (2024), arXiv:2303.08144 [hep-th].
    [Bis96]
    T. Bisztriczky. On a class of generalized simplices. Mathematika 43, 274–285 (1996).
    [Bur55]
    W. Burnside. Theory of groups of finite order (Dover Publications, Inc., New York, 1955); p. xxiv+512. 2d ed.
    [C-MLS20]
    J. L. Cisneros Molina, D. T. Le and J. Seade. Handbook of Geometry and Topology of Singularities I (Springer-Verlag, Cham, 2020); p. xviii+601.
    [C-MLS21]
    J. L. Cisneros Molina, D. T. Le and J. Seade. Handbook of Geometry and Topology of Singularities II (Springer-Verlag, Cham, 2021); p. xii+578.
    [CCNPW85]
    J. H. Conway, R. T. Curtis, S. P. Norton, R. A. Parker and R. A. Wilson. Atlas of finite groups (Oxford University Press, Eynsham, 1985); p. xxxiv+252. Maximal subgroups and ordinary characters for simple groups, With computational assistance from J. G. Thackray.
    [CHLLT19]
    M. Cvetič, J. Halverson, L. Lin, M. Liu and J. Tian. Quadrillion $F$-Theory Compactifications with the Exact Chiral Spectrum of the Standard Model. Phys. Rev. Lett. 123, 101601 (2019), arXiv:1903.00009 [hep-th].
    [CHM98]
    J. H. Conway, A. Hulpke and J. McKay. On transitive permutation groups. LMS J. Comput. Math. 1, 1–8 (1998).
    [CKM97]
    S. Collart, M. Kalkbrener and D. Mall. Converting Bases with the Gröbner Walk. Journal of Symbolic Computation 24, 465–469 (1997).
    [CLO05]
    D. A. Cox, J. Little and D. O'Shea. Using Algebraic Geometry. Vol. 185 of Graduate Texts in Mathematics (Springer-Verlag, 2005).
    [CLS11]
    D. A. Cox, J. B. Little and H. K. Schenck. Toric varieties. Vol. 124 of Graduate Studies in Mathematics (Providence, RI: American Mathematical Society (AMS), 2011); p. xxiv+841.
    [CMS07]
    B. Collins, J. A. Mingo, P. Śniady and R. Speicher. Second order freeness and fluctuations of random matrices. III: Higher order freeness and free cumulants. Documenta Mathematica 12, 1–70 (2007).
    [CMT04]
    A. M. Cohen, S. H. Murray and D. E. Taylor. Computing in groups of Lie type. Math. Comp. 73, 1477–1498 (2004).
    [CS99]
    J. H. Conway and N. J. Sloane. Sphere packings, lattices and groups. Third Edition, Vol. 290 of Grundlehren der mathematischen Wissenschaften [Fundamental Principles of Mathematical Sciences] (Springer-Verlag, New York, 1999); p. lxxiv+703. 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.
    [CSZ15]
    C. Ceballos, F. Santos and G. M. Ziegler. Many non-equivalent realizations of the associahedron. Combinatorica 35, 513–551 (2015).
    [CW16]
    G. Cébron and M. Weber. Quantum groups based on spatial partitions (2016), arXiv:1609.02321 [math.QA].
    [Cam99]
    P. J. Cameron. Permutation groups. Vol. 45 of London Mathematical Society Student Texts (Cambridge University Press, Cambridge, 1999); p. x+220.
    [Chr91]
    J. A. 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), Vol. 1462 of Lecture Notes in Math. (Springer, Berlin, 1991); pp. 81–92.
    [Coh00]
    H. Cohen. Advanced topics in computational number theory. Vol. 193 of Graduate Texts in Mathematics (Springer-Verlag, New York, 2000); p. xvi+578.
    [Coh93]
    H. Cohen. A course in computational algebraic number theory. Vol. 138 of Graduate Texts in Mathematics (Springer-Verlag, Berlin, 1993); p. xii+534.
    [Cor21]
    D. Corey. Initial degenerations of Grassmannians. Sel. Math. New Ser. 27 (2021).
    [DE02]
    W. Decker and D. Eisenbud. Sheaf algorithms using the exterior algebra. In: Computations in algebraic geometry with Macaulay 2 (Berlin: Springer, 2002); pp. 215–249.
    [DES93]
    W. Decker, L. Ein and F.-O. Schreyer. Construction of surfaces in ${\mathbb P}^4$. J. Algebr. Geom. 2, 185–237 (1993).
    [DF20]
    G. De Franceschi. Centralizers and conjugacy classes in finite classical groups (2020), arXiv:2008.12651 [math.GR].
    [DFO13]
    A. S. Detinko, D. L. Flannery and E. A. O'Brien. Recognizing finite matrix groups over infinite fields. J. Symbolic Comput. 50, 100–109 (2013).
    [DGP99]
    W. Decker, G.-M. Greuel and G. Pfister. Primary decomposition: algorithms and comparisons. In: Algorithmic algebra and number theory. Selected papers from a conference, Heidelberg, Germany, October 1997 (Springer, Berlin, 1999); pp. 187–220.
    [DH00]
    M. Domokos and P. Hegedűs. Noether's bound for polynomial invariants of finite groups. Arch. Math. (Basel) 74, 161–167 (2000).
    [DHS98]
    W. Decker, A. E. Heydtmann and F.-O. Schreyer. Generating a Noetherian normalization of the invariant ring of a finite group. J. Symbolic Comput. 25, 727–731 (1998).
    [DJ98]
    W. Decker and T. 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, Vol. 251 of London Math. Soc. Lecture Note Ser. (Cambridge Univ. Press, Cambridge, 1998); pp. 61–89.
    [DK15]
    H. Derksen and G. Kemper. Computational invariant theory. With two appendices by Vladimir L. Popov, and an addendum by Norbert A'Campo and Popov, 2nd enlarged edition, Invariant Theory and Algebraic Transformation Groups, VIII, enlarged Edition, Vol. 130 of Encyclopaedia of Mathematical Sciences (Springer, Heidelberg, 2015); p. xxii+366.
    [DK17]
    M. Donten-Bury and S. Keicher. Computing resolutions of quotient singularities. J. Algebra 472, 546–572 (2017).
    [DL06]
    W. Decker and C. Lossen. Computing in algebraic geometry. A quick start using SINGULAR. Vol. 16 of Algorithms and Computation in Mathematics (Springer-Verlag, Berlin; Hindustan Book Agency, New Delhi, 2006); p. xvi+327.
    [DLRS10]
    J. A. De Loera, J. Rambau and F. Santos. Triangulations. Structures for algorithms and applications. Vol. 25 of Algorithms and Computation in Mathematics (Springer-Verlag, Berlin, 2010); p. xiv+535.
    [DP13]
    W. Decker and G. Pfister. A first course in computational algebraic geometry. African Institute of Mathematics (AIMS) Library Series (Cambridge University Press, Cambridge, 2013); p. viii+118.
    [DS00]
    W. Decker and F.-O. Schreyer. Non-general type surfaces in ${\mathbb P}^4$: Some remarks on bounds and constructions. J. Symb. Comput. 29, 545–582 (2000).
    [DSS09]
    M. Drton, B. Sturmfels and S. Sullivant. Lectures on algebraic statistics. Vol. 39 of Oberwolfach Semin. (Basel: Birkhäuser, 2009).
    [Der99]
    H. Derksen. Computation of invariants for reductive groups. Adv. Math. 141, 366–384 (1999).
    [EFS03]
    D. Eisenbud, G. Fløystad and F.-O. Schreyer. Sheaf cohomology and free resolutions over exterior algebras. Trans. Am. Math. Soc. 355, 4397–4426 (2003).
    [EH16]
    D. Eisenbud and J. Harris. 3264 and all that. A second course in algebraic geometry (Cambridge: Cambridge University Press, 2016).
    [EHU03]
    D. Eisenbud, C. Huneke and B. Ulrich. What is the Rees algebra of a module? Proc. Am. Math. Soc. 131, 701–708 (2003).
    [EHV92]
    D. Eisenbud, C. Huneke and W. Vasconcelos. Direct methods for primary decomposition. Invent. Math. 110, 207–235 (1992).
    [EM16]
    Z. S. Eser and L. F. Matusevich. Decompositions of cellular binomial ideals. J. Lond. Math. Soc. (2) 94, 409–426 (2016).
    [EM19]
    Z. S. Eser and L. F. Matusevich. Corrigendum: Decompositions of cellular binomial ideals: (J. Lond. Math. Soc. 94 (2016) 409–426). J. Lond. Math. Soc. (2) 100, 717–719 (2019).
    [EMSS16]
    B. Eröcal, O. Motsak, F.-O. Schreyer and A. Steenpaß. Refined algorithms to compute syzygies. J. Symb. Comput. 74, 308–327 (2016).
    [ES96]
    D. Eisenbud and B. Sturmfels. Binomial ideals. Duke Math. J. 84, 1–45 (1996).
    [Eis95]
    D. Eisenbud. Commutative algebra. With a view toward algebraic geometry. Vol. 150 (Berlin: Springer-Verlag, 1995); p. xvi + 785.
    [Eis98]
    D. Eisenbud. Computing cohomology. A chapter in W. Vasconcelos, Computational methods in commutative algebra and algebraic geometry (Berlin: Springer, 1998); pp. 209–216.
    [FGLM93]
    J. Faugère, P. Gianni, D. Lazard and T. Mora. Efficient Computation of Zero-dimensional Gröbner Bases by Change of Ordering. Journal of Symbolic Computation 16, 329–344 (1993).
    [FJLT07]
    K. Fukuda, A. N. Jensen, N. Lauritzen and R. Thomas. The generic Gröbner walk. Journal of Symbolic Computation 42, 298–312 (2007).
    [FJR17]
    H. Fan, T. Jarvis and Y. Ruan. A mathematical theory of the gauged linear sigma model. Geometry & Topology 22, 235–303 (2017).
    [FJT07]
    K. Fukuda, A. N. Jensen and R. R. Thomas. Computing Groebner Fans. Math. Comp. 76, 2189–2213 (2007).
    [FLINT]
    W. B. Hart. Fast Library for Number Theory: An Introduction. In: Proceedings of the Third International Congress on Mathematical Software, ICMS'10 (Springer-Verlag, Berlin, Heidelberg, 2010); pp. 88–91, https://flintlib.org.
    [FY04]
    E. M. Feichtner and S. Yuzvinsky. Chow rings of toric varieties defined by atomic lattices. Inventiones Mathematicae 155, 515–536 (2004).
    [Fau99]
    J.-C. Faugère. A new efficient algorithm for computing Gröbner bases (F4). Journal of Pure and Applied Algebra 139, 61–88 (1999). HAL:hal-01148855.
    [Ful69]
    W. Fulton. Algebraic curves. An introduction to algebraic geometry. Mathematics Lecture Note Series (W. A. Benjamin, Inc., New York-Amsterdam, 1969); p. xiii+226. Notes written with the collaboration of Richard Weiss.
    [Ful97]
    W. Fulton. Young tableaux. Vol. 35 of London Mathematical Society Student Texts (Cambridge University Press, Cambridge, 1997); p. x+260. With applications to representation theory and geometry.
    [Ful98]
    W. Fulton. Intersection theory. Second Edition, Vol. 2 of Ergebnisse der Mathematik und ihrer Grenzgebiete. 3. Folge. A Series of Modern Surveys in Mathematics [Results in Mathematics and Related Areas. 3rd Series. A Series of Modern Surveys in Mathematics] (Springer-Verlag, Berlin, 1998); p. xiv+470.
    [GH12]
    T. W. Grimm and H. Hayashi. F-theory fluxes, chirality and Chern-Simons theories. Journal of High Energy Physics 2012 (2012).
    [GHJ16]
    E. Gawrilow, S. Hampe and M. Joswig. The polymake XML File Format. In: Mathematical Software – ICMS 2016, edited by G.-M. Greuel, T. Koch, P. Paule and A. Sommese (Springer International Publishing, Cham, 2016); pp. 403–410.
    [GIR96]
    W. A. de Graaf, G. Ivanyos and L. Rónyai. Computing Cartan subalgebras of Lie algebras. Appl. Algebra Eng. Commun. Comput. 7, 339–349 (1996).
    [GJ00]
    E. Gawrilow and M. Joswig, polymake: a Framework for Analyzing Convex Polytopes. In: Polytopes — Combinatorics and Computation, edited by G. Kalai and G. M. Ziegler (Birkhäuser, 2000); pp. 43–74, https://polymake.org.
    [GJRW10]
    E. Gawrilow, M. Joswig, T. Rörig and N. Witte. Drawing polytopal graphs with polymake. Comput. Vis. Sci. 13, 99–110 (2010), arXiv:0711.2397.
    [GK14]
    Y. Giannakopoulos and E. Koutsoupias. Duality and optimality of auctions for uniform distributions. In: Proceedings of the fifteenth ACM conference on Economics and computation (Association for Computing Machinery, New York, 2014); pp. 259–276.
    [GLS07]
    G.-M. Greuel, C. Lossen and E. Shustin. Introduction to Singularities and Deformations. Springer Monographs in Mathematics (Springer-Verlag, Berlin, 2007); p. xii+471.
    [GLS10]
    G.-M. Greuel, S. Laplagne and F. Seelisch. Normalization of rings. J. Symbolic Comput. 45, 887–901 (2010).
    [GP08]
    G.-M. Greuel and G. Pfister. A Singular introduction to commutative algebra. With contributions by Olaf Bachmann, Christoph Lossen and Hans Schönemann. 2nd extended ed. (Springer, Berlin, 2008); p. xx+689. With 1 CD-ROM (Windows, Macintosh and UNIX).
    [GS79]
    D. Goldfarb and W. Y. Sit. Worst case behavior of the steepest edge simplex method. Discrete Applied Mathematics 1, 277–285 (1979).
    [GSS22]
    D. R. Grayson, A. Seceleanu and M. E. Stillman. Computations in intersection rings of flag bundles (2022), arXiv:1205.4190 [math.AG].
    [GTZ88]
    P. Gianni, B. Trager and G. Zacharias. Gröbner bases and primary decomposition of polynomial ideals. In: Computational aspects of commutative algebra, Vol. 6 (Elsevier Ltd, Oxford, 1988); pp. 149–167.
    [GW20]
    U. Görtz and T. Wedhorn. Algebraic Geometry I: Schemes with Examples and Exercises. 2 Edition (Springer Spektrum, 2020).
    [Gat18]
    A. Gathmann. Class notes „Plane Algebraic Curves” (SS 2018). Published electronically (2018).
    [Gat96]
    K. Gatermann. Semi-invariants, equivariants and algorithms. Appl. Algebra Engrg. Comm. Comput. 7, 105–124 (1996).
    [Gra00]
    W. A. de Graaf. Lie algebras: theory and algorithms. Vol. 56 of North-Holland Mathematical Library (North-Holland Publishing Co., Amsterdam, 2000); p. xii+393.
    [Gro20]
    D. Gromada. Compact matrix quantum groups and their representation categories, doctoralthesis, Universität des Saarlandes (2020).
    [Gru03]
    B. Grünbaum. Convex polytopes. Second Edition, Vol. 221 of Graduate Texts in Mathematics (Springer-Verlag, New York, 2003); p. xvi+468. Prepared and with a preface by Volker Kaibel, Victor Klee and Günter M. Ziegler.
    [HEO05]
    D. F. Holt, B. Eick and E. A. O'Brien. Handbook of computational group theory. Discrete Mathematics and its Applications (Boca Raton) (Chapman & Hall/CRC, Boca Raton, FL, 2005); p. xvi+514.
    [HHS11]
    J. Hausen, E. Herppich and H. Süss. Multigraded factorial rings and Fano varieties with torus action. Doc. Math. 16, 71–109 (2011).
    [HM73]
    G. Horrocks and D. Mumford. A rank 2 vector bundle on $\text{P}^4$ with 15,000 symmetries. Topology 12, 63–81 (1973).
    [HP89]
    D. F. Holt and W. Plesken. Perfect groups. Oxford Mathematical Monographs (The Clarendon Press, Oxford University Press, New York, 1989); p. xii+364. With an appendix by W. Hanrath, Oxford Science Publications.
    [HRR23]
    A. Hulpke, C. Roney-Dougal and C. Russell. PrimGrp, GAP Primitive Permutation Groups Library, Version 3.4.4 (Feb 2023). GAP package.
    [HT17]
    [Har77]
    R. Hartshorne. Algebraic Geometry. Graduate Texts in Mathematics (Springer-Verlag, New York, 1977); p. xvi+496.
    [Hul22]
    A. Hulpke. The perfect groups of order up to two million. Math. Comp. 91, 1007–1017 (2022).
    [Hul23]
    A. Hulpke. TransGrp, Transitive Groups Library, Version 3.6.5 (Dec 2023). GAP package.
    [Hum72]
    J. E. Humphreys. Introduction to Lie Algebras and Representation Theory. Vol. 9 of Graduate Texts in Mathematics (Springer-Verlag, New York, 1972); p. xii+169.
    [Hup67]
    B. Huppert. Endliche Gruppen. I. Vol. 134 of Die Grundlehren der mathematischen Wissenschaften (Springer-Verlag, Berlin-New York, 1967); p. xii+793.
    [Huy16]
    D. Huybrechts. Lectures on K3 surfaces. Vol. 158 of Cambridge Studies in Advanced Mathematics (Cambridge University Press, Cambridge, 2016); p. xi+485.
    [IR96]
    Y. Ito and M. Reid. The McKay correspondence for finite subgroups of $\mathrm{SL}(3,\mathbb C)$. In: Higher-dimensional complex varieties (Trento, 1994) (de Gruyter, 1996); pp. 221–240.
    [JKS22]
    M. Joswig, M. Klimm and S. Spitz. Generalized permutahedra and optimal auctions. SIAM Journal on Applied Algebra and Geometry 6, 711–739 (2022).
    [JLLT22]
    M. Joswig, D. Lofano, F. H. Lutz and M. Tsuruga. Frontiers of sphere recognition in practice. J. Appl. Comput. Topol. 6, 503–527 (2022).
    [JLPW95]
    C. Jansen, K. Lux, R. Parker and R. Wilson. An atlas of Brauer characters. Vol. 11 of London Mathematical Society Monographs. New Series (The Clarendon Press Oxford University Press, New York, 1995); p. xviii+327. Appendix 2 by T. Breuer and S. Norton, Oxford Science Publications.
    [JP00]
    T. de Jong and G. Pfister. Local Analytic Geometry. Advanced Lectures in Mathematics (Vieweg+Teubner Verlag, 2000); p. xi+384.
    [JT13]
    M. Joswig and T. Theobald. Polyhedral and algebraic methods in computational geometry. Universitext (Springer, London, 2013); p. x+250. Revised and updated translation of the 2008 German original.
    [JZ00]
    M. Joswig and G. M. Ziegler. Neighborly Cubical Polytopes. Discrete & Computational Geometry  24, 325–344 (2000).
    [Joh12]
    F. Johansson. Efficient implementation of the Hardy-Ramanujan-Rademacher formula. LMS J. Comput. Math. 15, 341–359 (2012).
    [Jos03]
    M. Joswig. Beneath-and-Beyond Revisited. In: Algebra, Geometry and Software Systems, edited by M. Joswig and N. Takayama (Springer Berlin Heidelberg, Berlin, Heidelberg, 2003); pp. 1–21.
    [Jos05]
    M. Joswig. Polytope propagation on graphs. In: Algebraic statistics for computational biology. (Cambridge: Cambridge University Press, 2005); pp. 181–192.
    [Jos21]
    M. Joswig. Essentials of tropical combinatorics. Vol. 219 of Graduate Studies in Mathematics (American Mathematical Society, Providence, RI, 2021).
    [Jow11]
    S.-Y. Jow. Cohomology of toric line bundles via simplicial Alexander duality. Journal of Mathematical Physics 52, 033506 (2011).
    [KL91]
    T. Krick and A. 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), Vol. 539 of Lecture Notes in Comput. Sci. (Springer, Berlin, 1991); pp. 195–205.
    [KLT20]
    M. Kaluba, B. Lorenz and S. Timme. Polymake.jl: A New Interface to polymake. In: Mathematical Software – ICMS 2020, edited by A. M. Bigatti, J. Carette, J. H. Davenport, M. Joswig and T. de Wolff (Springer International Publishing, Cham, 2020); pp. 377–385.
    [KM-POPR15]
    D. Klevers, D. K. Mayorga Pena, P.-K. Oehlmann, H. Piragua and J. Reuter. F-Theory on all Toric Hypersurface Fibrations and its Higgs Branches. JHEP 01, 142 (2015), arXiv:1408.4808 [hep-th].
    [KMSS11]
    S. Katz, D. R. Morrison, S. Schafer-Nameki and J. Sully. Tate's algorithm and F-theory. JHEP 08, 094 (2011), arXiv:1106.3854 [hep-th].
    [KO14]
    J. Kelleher and B. O'Sullivan. Generating All Partitions: A Comparison Of Two Encodings (2014), arXiv:0909.2331 [cs.DS].
    [KR05]
    M. Kreuzer and L. Robbiano. Computational commutative algebra. II (Berlin: Springer, 2005); p. x + 586.
    [KS99]
    G. Kemper and A. Steel. Some algorithms in invariant theory of finite groups. In: Computational methods for representations of groups and algebras (Essen, 1997), Vol. 173 of Progr. Math. (Birkhäuser, Basel, 1999); pp. 267–285.
    [Kah10]
    T. Kahle. Decompositions of binomial ideals. Ann. Inst. Statist. Math. 62, 727–745 (2010).
    [Kem02]
    G. Kemper. The calculation of radical ideals in positive characteristic. J. Symbolic Comput. 34, 229–238 (2002).
    [Kem99]
    G. Kemper. An algorithm to calculate optimal homogeneous systems of parameters. J. Symbolic Comput. 27, 171–184 (1999).
    [Kin07]
    S. King. Fast computation of secondary invariants (2007), arXiv:math/0701270 [math.AC].
    [Kin13]
    S. King. Minimal generating sets of non-modular invariant rings of finite groups. J. Symb. Comput. 48, 101–109 (2013).
    [Knu11]
    D. E. Knuth. The art of computer programming. Vol. 4A. Combinatorial algorithms. Part 1 (Addison-Wesley, Upper Saddle River, NJ, 2011); p. xv+883.
    [Kol13]
    J. Kollár. Singularities of the minimal model program. Vol. 200 of Cambridge Tracts in Mathematics (Cambridge University Press, 2013). With a collaboration of Sándor Kovács.
    [Koz08]
    D. Kozlov. Combinatorial algebraic topology. Vol. 21 of Algorithms and Computation in Mathematics (Springer, Berlin, 2008).
    [LN97]
    R. Lidl and H. Niederreiter. Finite fields. Second Edition, Vol. 20 of Encyclopedia of Mathematics and its Applications (Cambridge University Press, Cambridge, 1997); p. xiv+755. With a foreword by P. M. Cohn.
    [LS03]
    V. Levandovskyy and H. 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. (New York, NY: ACM Press, 2003); pp. 176–183.
    [LS13]
    [Lev05]
    V. Levandovskyy. Non-commutative Computer Algebra for polynomial algebras: Gröbner bases, applications and implementation, doctoralthesis, Technische Universität Kaiserslautern (2005).
    [Liu06]
    Q. Liu. Algebraic geometry and arithmetic curves. Transl. by Reinie Erné. Vol. 6 of Oxf. Grad. Texts Math. (Oxford: Oxford University Press, 2006).
    [Loo84]
    E. Looijenga. Isolated Singular Points on Complete Intersections. Vol. 77 of LMS Lecture Note Series (Cambridge University Press, Cambridge, 1984); p. xi+200.
    [MNP24]
    T. Merkwitz, L. Naughton and G. Pfeiffer. TomLib, The GAP Library of Tables of Marks, Version 1.2.11 (Jan 2024). GAP package.
    [MP82]
    R. V. Moody and J. Patera. Fast recursion formula for weight multiplicities. Bull. Amer. Math. Soc. (N.S.) 7, 237–242 (1982).
    [MR20]
    T. Markwig and Y. Ren. Computing tropical varieties over fields with valuation. Found. Comput. Math. 20, 783–800 (2020).
    [MS05]
    E. Miller and B. Sturmfels. Combinatorial commutative algebra. Vol. 227 (New York, NY: Springer, 2005); p. xiv + 417.
    [MS15]
    D. Maclagan and B. Sturmfels. Introduction to tropical geometry. Vol. 161 (Providence, RI: American Mathematical Society (AMS), 2015); p. xii + 363.
    [MS21]
    M. Michałek and B. Sturmfels. Invitation to nonlinear algebra. Vol. 211 (Providence, RI: American Mathematical Society (AMS), 2021); p. xiii + 226.
    [Mar18]
    D. A. Marcus. Number fields. Universitext (Springer, Cham, 2018); p. xviii+203. Second edition of [MR0457396], With a foreword by Barry Mazur.
    [Nik79]
    V. V. Nikulin. Integer symmetric bilinear forms and some of their geometric applications. Izv. Akad. Nauk SSSR Ser. Mat. 43, 111–177, 238 (1979).
    [OEIS]
    OEIS Foundation Inc. The On-Line Encyclopedia of Integer Sequences. Published electronically at https://oeis.org (2024).
    [OM78]
    T. Oda and K. Miyake. Lectures on Torus Embeddings and Applications. Lectures on mathematics and physics (Tata Institute of Fundamental Research, 1978).
    [OMdCS00]
    I. Ojeda Martínez de Castilla and R. P. Sánchez. Cellular binomial ideals. Primary decomposition of binomial ideals. J. Symbolic Comput. 30, 383–400 (2000).
    [Oxl11]
    J. Oxley. Matroid theory. Second Edition, Vol. 21 of Oxford Graduate Texts in Mathematics (Oxford University Press, Oxford, 2011); p. xiv+684.
    [PS09]
    A. Postnikov and R. P. Stanley. Chains in the Bruhat order. J. Algebraic Combin. 29, 133–174 (2009).
    [PS11]
    S. Pokutta and A. S. Schulz. Integer-empty polytopes in the 0/1-cube with maximal Gomory–Chvátal rank. Operations research letters 39, 457–460 (2011).
    [PSS11]
    G. Pfister, A. Sadiq and S. Steidel. An algorithm for primary decomposition in polynomial rings over the integers. Cent. Eur. J. Math. 9, 897–904 (2011).
    [PZ97]
    M. Pohst and H. Zassenhaus. Algorithmic algebraic number theory. Vol. 30 of Encyclopedia of Mathematics and its Applications (Cambridge University Press, Cambridge, 1997); p. xiv+499. Revised reprint of the 1989 original.
    [Pan23]
    [Peg14]
    C. Pegel. Chow Rings of Toric Varieties. Master's thesis, University of Bremen (Faculty of Mathematics, Sep 2014). Refereed by Prof. Dr. Eva Maria Feichtner and Dr. Emanuele Delucchi.
    [Pol56]
    G. Pólya. On picture-writing. Amer. Math. Monthly 63, 689–697 (1956).
    [Pop93]
    S. Popescu. On smooth surfaces of degree $\geq 11$ in the projective fourspace, doctoralthesis, Universität des Saarlandes, Saarbrücken (1993).
    [Pos09]
    A. Postnikov. Permutohedra, associahedra, and beyond. International Mathematics Research Notices 2009, 1026–1106 (2009).
    [Pos18]
    S. Posur. Linear systems over localizations of rings. Archiv der Mathematik 111, 23–32 (2018).
    [RJ76]
    W. Riha and K. R. James. Algorithm 29 efficient algorithms for doubly and multiply restricted partitions. Computing 16, 163–168 (1976).
    [RR10]
    H. Roschy and T. Rahn. Cohomology of line bundles: Proof of the algorithm. Journal of Mathematical Physics 51, 103520 (2010).
    [RSS03]
    G. Rote, F. Santos and I. Streinu. Expansive motions and the polytope of pointed pseudo-triangulations. Discrete and Computational Geometry: The Goodman-Pollack Festschrift, 699–736 (2003).
    [Rin13]
    F. Rincón. Computing tropical linear spaces. J. Symb. Comput. 51, 86–98 (2013).
    [SS03]
    C. Semple and M. Steel. Phylogenetics. Vol. 24 of Oxf. Lect. Ser. Math. Appl. (Oxford University Press, 2003).
    [SS12]
    C. D. Savage and M. J. Schuster. Ehrhart series of lecture hall polytopes and Eulerian polynomials for inversion sequences. Journal of Combinatorial Theory, Series A 119, 850–870 (2012).
    [SV-D-V87]
    A. J. Sommese and A. Van de Ven. On the adjunction mapping. Math. Ann. 278, 593–603 (1987).
    [SY96]
    T. Shimoyama and K. Yokoyama. Localization and primary decomposition of polynomial ideals. J. Symbolic Comput. 22, 247–277 (1996).
    [Sch23]
    J. Schmitt. On $\mathbb Q$-factorial terminalizations of symplectic linear quotient singularities. Ph.D. Thesis, RPTU Kaiserslautern-Landau (2023).
    [Sch95]
    P. Schuchert. Matroid-Polytope und Einbettungen kombinatorischer Mannigfaltigkeiten. Ph.D. Thesis, TU Darmstadt (1995).
    [Ser03]
    Á. Seress. Permutation group algorithms. Vol. 152 of Cambridge Tracts in Mathematics (Cambridge University Press, Cambridge, 2003); p. x+264.
    [Sez02]
    [Shi15]
    [Shi18]
    I. Shimada. Connected Components of the Moduli of Elliptic $K3$ Surfaces. Michigan Mathematical Journal 67, 511–559 (2018).
    [Sta79]
    R. P. Stanley. Invariants of finite groups and their applications to combinatorics. Bull. Amer. Math. Soc. (N.S.) 1, 475–511 (1979).
    [Stacks]
    The Stacks Project Authors. Stacks Project. Published electronically.
    [Ste01]
    J. R. Stembridge. Computational aspects of root systems, Coxeter groups, and Weyl characters. In: Interaction of combinatorics and representation theory, Vol. 11 of MSJ Memoirs (The Mathematical Society of Japan, 2001); pp. 1–38.
    [Ste91]
    J. Stevens. On the versal deformation of cyclic quotient singularities. In: Singularity theory and its applications, Part I (Coventry, 1988/1989), Vol. 1462 of Lecture Notes in Math. (Springer, Berlin, 1991); pp. 302–319.
    [Stu93]
    B. Sturmfels. Algorithms in invariant theory. Texts and Monographs in Symbolic Computation (Springer-Verlag, Vienna, 1993); p. vi+197.
    [Sul18]
    S. Sullivant. Algebraic statistics. Vol. 194 of Grad. Stud. Math. (Providence, RI: American Mathematical Society (AMS), 2018).
    [Sym11]
    P. Symonds. On the Castelnuovo-Mumford regularity of rings of polynomial invariants. Ann. of Math. (2) 174, 499–517 (2011).
    [TW18]
    P. Tarrago and M. Weber. The classification of tensor categories of two-colored noncrossing partitions. Journal of Combinatorial Theory, Series A 154, 464–506 (2018).
    [Tay87]
    D. E. Taylor. Pairs of Generators for Matrix Groups. I. The Cayley Bulletin 3, 76–85 (1987), arXiv:2201.09155 [math.GR].
    [Tra00]
    Q.-N. Tran. A Fast Algorithm for Gröbner Basis Conversion and its Applications. Journal of Symbolic Computation 30, 451–467 (2000).
    [Tra04]
    Q.-N. Tran. Efficient Groebner walk conversion for implicitization of geometric objects. Computer Aided Geometric Design 21, 837–857 (2004).
    [Tur18]
    I. Turkalj. Reflective Lorentzian lattices of signature (5, 1). Journal of Algebra 513, 516–544 (2018).
    [VE22]
    [Vin75]
    E. B. Vinberg. Some arithmetical discrete groups in Lobacevsky spaces. In: Discrete subgroups of Lie groups and applications to moduli (Internat. Colloq., Bombay, 1973), No. 7 of Tata Inst. Fundam. Res. Stud. Math. (Published for the Tata Institute of Fundamental Research, Bombay by Oxford University Press, Bombay, 1975); pp. 323–348.
    [Vol23]
    S. Volz. Design and implementation of efficient algorithms for operations on partitions of sets. Bachelor's Thesis, Universität des Saarlandes (2023).
    [Was08]
    L. C. Washington. Elliptic curves. Second Edition, Discrete Mathematics and its Applications (Boca Raton) (Chapman & Hall/CRC, Boca Raton, FL, 2008); p. xviii+513. Number theory and cryptography.
    [Wei10]
    T. Weigand. Lectures on F-theory compactifications and model building. Class. Quant. Grav. 27, 214004 (2010), arXiv:1009.3497 [hep-th].
    [Wei18]
    T. Weigand. TASI Lectures on F-theory. PoS TASI2017, 016 (2018), arXiv:1806.01854 [hep-th].
    [Wil13]
    J. B. Wilson. Optimal algorithms of Gram-Schmidt type. Linear Algebra Appl. 438, 4573–4583 (2013).
    [Wit88]
    E. Witten. Topological Sigma Models. Commun. Math. Phys. 118, 411 (1988).
    [Wit97]
    [Yam18]
    R. Yamagishi. On smoothness of minimal models of quotient singularities by finite subgroups of $\mathrm{SL}_n(\mathbb C)$. Glasg. Math. J. 60, 603–634 (2018).
    [ZS98]
    A. Zoghbi and I. Stojmenovic. Fast algorithms for generating integer partitions. Int. J. Comput. Math. 70, 319–332 (1998).
    [Zie95]
    G. M. Ziegler. Lectures on polytopes. Vol. 152 of Graduate Texts in Mathematics (Springer-Verlag, New York, 1995); p. x+370.